admin管理员组

文章数量:1547529

前端入门到转行

  • node.js
    • node.js的组成
    • node.js的基本语法
        • node.js的全局对象global
      • Node.js的模块化开发
        • javaScript开发的弊端
        • Node.js模块开发规范
      • 系统模块
        • 系统模块fs文件读取操作
        • 系统模块fs文件写入操作
        • 系统文件path路径操作
            • 路径拼接的语法
            • 绝对路径和相对路径
  • ajax
    • 什么是ajax
    • ajax的原生写法
      • XMLHttpRequest对象
      • 实现流程
      • 原生写法中的注意点
    • get和post请求
    • success和complete的区别
    • XML -> JSON
    • JSON和JSONP
    • Ajax跨域访问
    • 再议HTTP状态码
    • 不可忽视的HTTP头文件
      • 请求头信息:
      • 响应头信息:
      • 两者都可能出现的消息
      • 跟缓存相关的字段
    • Ajax的优缺点
      • 优点:
      • 缺点:
  • Axios
    • Axios是什么
    • Axios特性
    • 浏览器支持情况
    • axios常用的请求方法
      • get请求
      • post方法
        • form-data(常用于表单提交(图片上传、文件上传))
        • application/json(常用)
      • put方法
      • patch方法
      • delete方法
      • 并发请求
      • axios实例创建
      • axios实例的相关配置
        • 配置列表
      • 拦截器
        • 案例:登录权限
        • 案例:移动端开发数据加载loading动画
      • 错误处理
          • 错误处理举例
        • 取消请求(不常用)
          • 代码示例
      • 代理
      • request.js
      • 在Vue中调用接口
  • ES6
    • ES6是什么
    • 严格模式
      • 介绍
      • 作用
      • 使用
      • 语法和行为改变
      • Object扩展方法
        • Object.keys(obj)
        • Object.values(obj)
        • Object.create()
        • 读写器
        • Object.defineProperty(obj,“key”,{descriptors}) 只能写一个属性
        • Object.defineProperties()
        • call、apply 和 bind
    • 关键字扩展
      • let和块级作用域
        • ES5没有块级作用域
        • 块级作用域
        • let关键字
        • let关键字特点
      • const关键字
      • 块级作用域的函数声明
    • 变量的解构赋值(重点)
      • 什么是变量的解构赋值
      • 引入
      • 解构赋值语法
      • 对象解构赋值
      • 数组解构赋值
      • 解构传递参数
      • 解构返回结果
      • 字符串解构(了解)
      • 数值和布尔值解构(了解)
    • spread运算符与rest参数
      • spread运算符
      • rest参数
  • VUE.js
    • vue导入
      • 概述
      • 语法
      • 案例
    • vue的基本语法
      • 1. 钩子函数
      • 2. 插值表达式
      • 3.显示数据(v-text和v-html)
      • 4.数据双向绑定数据(v-model)
        • 4.2.绑定单个复选框
        • 4.2.绑定单个复选框
        • 4.3.绑定多个复选框
        • 4.4.form表单数据提交
      • 5.事件处理(v-on)
        • 5.1.事件绑定(v-on)
        • 5.2.事件修饰符
      • 6.循环遍历(v-for)
        • 6.1.遍历数组
        • 6.2.遍历对象
        • 6.3.key
      • 判断语法(v-if和v-show)
      • 8.显示数据(v-bind)
      • 9.Vue页面挑战(两种方法)
        • 9.1.方法一(标签实现)
        • 9.1.方法二(this.$router.push()实现)
    • 三、Vue其他语法
      • 1.计算属性
        • 2.watch监控
    • 四、Vue组件
      • 4.1.基本使用
      • 4.2.父组件向子组件通信
      • 4.3.子组件向父组件通信
    • 五、axios异步请求
      • 5.1 axios概述
      • 5.2.Get请求
      • 5.3.Post请求
      • 5.4.跨域请求
    • 六、VueJs Ajax
      • 6.1.vue-resource
      • 6.2.axios
        • 6.2.1.引入axios
        • 6.2.2.get请求
        • 6.2.3.post请求

node.js

node.js的组成

node.js是由ECMAScript、node环境提供的一些放假API组成的,包括网络、文件、路径等等一些强大的API。

node.js的基本语法

node.js的全局对象global

注:在浏览器中全局对象是window,在Node中的全局对象是global

在Node中全局对象有以下方法:
console.log() 在控制台输出
setTimeout() 设置超时定时器
clearTimeout() 清除超时定时器
setInterval() 设置间歇定时器
clearInterval() 清除间歇定时器

Node.js的模块化开发

javaScript开发的弊端

1)文件依赖关系不明确:在javaScript中文件的依赖关系是由文件引入的先后顺序决定
2) 命名冲突导致文件覆盖
模块化开发可解决上述两问题。

Node.js模块开发规范

在Node.js中规定一个javaScript文件就是一个模块,模块内部定义的变量和函数在默认情况下外部是无法访问的,在模块的内部可以通过exports对象进行成员的导出,使用require方法可以导入其他模块。

系统模块

系统模块fs文件读取操作

f:file 文件,s:system 系统文件操作系统

const fs = require(‘fs’);

读取文件内容

fs.reaFile(‘文件路径/文件名称’[,‘文件编码’],callback);

系统模块fs文件写入操作

fs.writeFile(‘文件路径/文件名称’,‘数据’,callback);

系统文件path路径操作

1 为什么要进行路径拼接?
1,不同操作系统的路径分割符不统一
2,window是/或\均可,而Linux必须是/

路径拼接的语法
path.join('路径''路径'.......);
绝对路径和相对路径

在读取文件和设置文件是需要使用绝对路径,此时我们可以使用__dirname读取当前文件所在的绝对路径。

ajax

什么是ajax

Ajax(Asynchronous JavaScript and XML),可以理解为JavaScript执行异步网络请求。通俗的理解的话就是,如果没有Ajax技术,改变网页的一小部分(哪怕是一行文字、一张图片)都需要重新加载一次整个页面,而有了Ajax之后,就可以实现在网页不跳转不刷新的情况下,在网页后台提交数据,部分更新页面内容。

ajax的原生写法

XMLHttpRequest对象

XMLHttpRequest 对象用于在后台与服务器交换数据,能够在不重新加载页面的情况下更新网页,在页面已加载后从服务器请求数据,在页面已加载后从服务器接收数据,在后台向服务器发送数据。所以XMLHttpRequest对象是Ajax技术的核心所在。

实现流程

创建 XMLHttpRequest对象——>打开请求地址,初始化数据——>发送请求数据——>监听回调函数状态——>收到服务器返回的应答结果。

var xmlhttp;

function loadXMLDoc(url)

{

xmlhttp=null;

if (window.XMLHttpRequest)

{// code for all new browsers

xmlhttp=new XMLHttpRequest();//在这里创建 XMLHttpRequest对象

}

else if (window.ActiveXObject)

{// code for IE5 and IE6

xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");

}

if (xmlhttp!=null)

{

xmlhttp.open("GET",url,true); //请求的方式和请求地址

xmlhttp.send(null);//发送请求

xmlhttp.onreadystatechange=state_Change;//监听回调函数

}

else

{

alert("Your browser does not support XMLHTTP.");

}

}





function state_Change() //这里是回调函数

{

if (xmlhttp.readyState==4&&xmlhttp.status==200)

  //当满足这两个条件时表示请求成功,完成响应 4 = "loaded", 200 = OK  

{

 var data=xmlhttp.responseText; //拿到服务器返回的数据

     // ...our code here...在这里进行数据返回后的操作

}else

 {

 alert("Problem retrieving XML data");

 }

}

原生写法中的注意点

(1).open() 的第三个参数中使用了 “true”,该参数规定请求是否异步处理,默认是异步。True 表示脚本会在 send() 方法之后继续执行,而不等待来自服务器的响应。

(2).关于readyState

(3).关于status 由服务器返回的 HTTP 状态代码,200 表示成功,而 404 表示 “Not Found” 错误。当 readyState 小于 3 的时候读取这一属性会导致一个异常。(后面会有http状态码的详细解读)

get和post请求

作为Ajax最常用的两种数据提交方式,GET和POST有着自己的特点和适用场景,正确区分GET和POST的不同并根据实际需要进行选用在开发中十分重要,简单但是关键!

先上一张GET 和 POST的比较图,从这张图中可以看出两者之间的差别:

从表格中拎出关键点: 1.传递数据的方式不同:get是直接把请求数据放在url的后面,是可见的,post的请求数据不会显示在url中,是不可见的。 2.数据长度和数据类型的差异:get有数据长度的的限制,且数据类型只允许ASCII字符,post在这两方面都没有限制。 3.安全性的差异:get不安全,post更安全。

由此得出的两者的使用场景:get使用较方便,适用于页面之间非敏感数据的简单传值,post使用较为安全,适用于向服务器发送密码、token等敏感数据。

success和complete的区别

JQuery封装的Ajax回调函数中,success、error、complete是最常用的三个,其中,success和error很好区别,一个是请求成功调用的,另一个是请求失败调用的,从字面上就可以理解。但是success和complete容易混淆,在这里特别做一个说明:

success:请求成功后回调函数。

complete:请求完成后回调函数 (请求成功或失败时均调用)。

注意到括号里面了吗,没错,区别就在于complete只要请求完成,不论是成功还是失败均会调用。也就是说如果调用了success,一定会调用complete;反过来调用了complete,不一定会调用success。(状态码404、403、301、302…都会进入complete,只要不出错就会调用)

XML -> JSON

Ajax中的是 “x” 指的就是XML。

xml:可扩展标记语言,标准通用标记语言的子集,是一种用于标记电子文件使其具有结构性的标记语言。

xml作为一种数据交互格式,广泛用在计算机领域,然而,随着json的发展,json以其明显的优势已经渐渐取代了xml成为现在数据交互格式的标准,所以在这里,想强调的是,json现在是主流的数据交互格式,前后端的交互标准,无论是前端提交给后台的数据,还是后台返回给前端的数据,都最好统一为json格式,各自接收到数据后再解析数据即可供后续使用。所以 “Ajax” 实际上已经发展为 “Ajaj”

JSON和JSONP

json 和 jsonp 看起来只相差了一个 “p” ,然而实际上根本不是一个东西,千万别以为是差不多的两个概念。

json:(JavaScript Object Notation, JS 对象标记) 是一种轻量级的数据交换格式。

jsonp:一种借助

Ajax跨域访问

ajax很好,但不是万能的,ajax的请求与访问同样会受到浏览器同源策略的限制,不能访问不同主域中的地址。所以,为了解决这一问题,实现跨域访问,有很多种方式,上述提到的jsonp就是一种流行的方式,还有其他一些方式,我在这里就不展开说了,只是想说明ajax的使用也是有条件的,任何技术的实现都不会是没有限制的。跨域访问时一个很重要的知识点,之前专门写过一篇关于跨域访问的总结,还挺详细的,可以移步查看: javascript中实现跨域的方式总结

再议HTTP状态码

前面提到的"200"、"404"只是http状态码中常见的两个,当浏览者访问一个网页时,浏览者的浏览器会向网页所在服务器发出请求。当浏览器接收并显示网页前,此网页所在的服务器会返回一个包含HTTP状态码的信息头(server header)用以响应浏览器的请求。

需要掌握的常见http状态码大致有以下一些:

101:切换协议,服务器根据客户端的请求切换协议

200:请求成功。一般用于GET与POST请求

301:永久重定向

302:临时重定向

303:与301类似。使用GET和POST请求查看

304:请求资源未修改,使用缓存

307:与302类似。使用GET请求重定向

404:客户端请求失败

408:请求超时

500:内部服务器错误,无法完成请求

505:服务器不支持请求的HTTP协议的版本,无法完成处理

不可忽视的HTTP头文件

请求头信息:

Accept:客户端支持的数据类型

Accept-Charset:客户端采用的编码

Accept-Encoding:客户端支持的数据压缩格式

Accept-Language:客户端的语言环境

Cookie:客服端的cookie

Host:请求的服务器地址

Connection:客户端与服务连接类型

If-Modified-Since:上一次请求资源的缓存时间,与Last-Modified对应

If-None-Match:客户段缓存数据的唯一标识,与Etag对应

Referer:发起请求的源地址。

响应头信息:

content-encoding:响应数据的压缩格式。

content-length:响应数据的长度。

content-language:语言环境。

content-type:响应数据的类型。

Date:消息发送的时间

Age:经过的时间

Etag:被请求变量的实体值,用于判断请求的资源是否发生变化

Expires:缓存的过期时间

Last-Modified:在服务器端最后被修改的时间

server:服务器的型号

两者都可能出现的消息

Pragma:是否缓存(http1.0提出) Cache-Control:是否缓存(http1.1提出)

跟缓存相关的字段

(1) 强制缓存 expire 和 cache-control

(2) 对比缓存 Last-Modified 和 If-Modified-Since Etag 和 If-None-Match

Ajax的优缺点

优点:

页面无刷新,在页面内与服务器通信,减少用户等待时间,增强了用户体验。

使用异步方式与服务器通信,响应速度更快。

可以把一些原本服务器的工作转接到客户端,利用客户端闲置的能力来处理,减轻了服务器和带宽的负担,节约空间和宽带租用成本。

基于标准化的并被广泛支持的技术,不需要下载插件或者小程序。

缺点:

无法进行操作的后退,即不支持浏览器的页面后退。

对搜索引擎的支持比较弱。

可能会影响程序中的异常处理机制。

安全问题,对一些网站攻击,如csrf、xxs、sql注入等不能很好地防御。

Axios

Axios是什么

Axios是一个基于promise的HTTP库,类似于jQuery的ajax,用于http请求。可以应用于浏览器端和node.js,既可以用于客户端,也可以用于node.js编写的服务端。

Axios特性

(1)支持Promise API
(2)拦截请求与响应,比如:在请求前添加授权和响应前做一些事情。
(3)转换请求数据和响应数据,比如:进行请求加密或者响应数据加密。
(4)取消请求
(5)自动转换JSON数据
(6)客户端支持防御XSRF

浏览器支持情况

Firefox、Chrome、Safari、Opera、Edge、IE8+

axios常用的请求方法

方法列举:get, post, put, patch, delete

  • get:一般用户获取数据
  • post:一般用于表单提交与文件上传
  • patch:更新数据(只将修改的数据推送到后端)
  • put:更新数据(所有数据推送到服务端)
  • delete:删除数据
    备注:post一般用于新建数据,put一般用于更新数据,patch一般用于数据量较大的时候的数据更新。

get请求

  • 方法一
    如果不带有参数的请求
    axios
    // 请求方式
      .get("/data.json")
      .then(res => {
        console.log(res);
      })
      .catch(err => {
        console.log(err);
      });

如果带有参数

	axios
      .get("/data.json", {
        params: {
          id: 12
        }
      })
      .then(res => {
        console.log(res);
      })
      .catch(err => {
        console.log(err);
      });
  • 方法二
    如果不带参数
      axios({
          method:'get',
          url:'/data.json'
      }).then(res=>{
          console.log(res)
      })

如果带有参数

 axios({
      method: "get",
      url: "/data.json",
      params:{
          id:12
      }
    }).then(res => {
      console.log(res);
    });

浏览器控制台相关信息介绍:

Request URL:请求URL

Request Method:请求方式

post方法

post请求常用的数据请求格式有两种

form-data(常用于表单提交(图片上传、文件上传))
 let data = {
      id: 12
    };
    let formData = new FormData();
    for(let key in data){
      formData.append(key,data[key])
    }
    console.log(formData)
    axios.post('/data.json',formData).then(res=>{
      console.log(res,'formData')
    })
application/json(常用)
  • 方式一
 let data = {
      id: 12
    };
    axios({
      method:'post',
      url:'/data.json',
      data:data
    }).then(res=>{
      console.log(res)
    })
  • 方式二
  let data = {
      id: 12
    };
    axios.post("/data.json", data).then(res=>{
      console.log(res, 'post')
    });

put方法

let data = {
  id: 12
};
axios.put("/data.json", data).then(res=>{
  console.log(res, 'put')
});

patch方法

let data = {
  id: 12
};
axios.patch("/data.json", data).then(res=>{
  console.log(res, 'patch')
});

备注:put与patch与post方法只有method不同,其他相同。

delete方法

  • 方式一 :params
axios
  .delete("/data.json", {
    params: {
      id: 12
    }
  })
  .then(res => {
    console.log(res, "delete");
  });
  
let params = {
  id: 12
};
axios({
  method:'delete',
  url:'/data.json',
  params:params
}).then(res=>{
  console.log(res)
})
  • 方式二:data
axios
  .delete("/data.json", {
    data: {
      id: 12
    }
  })
  .then(res => {
    console.log(res, "delete");
  });
  
let data = {
  id: 12
};
axios({
  method:'delete',
  url:'/data.json',
  data:data
}).then(res=>{
  console.log(res)
})

并发请求

并发请求,就是同时进行多个请求,并统一处理返回值。

在例子中,我们使用axios.all,对data.json/city.json同时进行请求,使用axios.spread,对返回的结果分别进行处理。代码如下:

// 并发请求
axios.all([axios.get("/data.json"), axios.get("/city.json")]).then(
  axios.spread((dataRes, cityRes) => {
    console.log(dataRes, cityRes);
  })
);

注意:axios.all的参数是请求函数的数组,在对应的回调then中,调用axios.spead对返回值进行处理,即可。

并发请求的应用场景:需要同时进行多个请求,并且需要同时处理接口调用的返回值的时候,我们可以使用并发请求。

axios实例创建

比如:后端接口地址有多个(www.test、www.example),并且超时时长不同(1000ms、2000ms),这个时候,我们可以创建实例。

思路如下:创建多个实例,配置不同的超时时长,用不同的实例去请求不同的接口。使用axios.acreate来创建实例,配置相关信息,进行网络请求。代码如下:

// 实例1
let instance = axios.create({
  baseURL:'http://loacalhost:8080',
  timeout:1000
})
instance.get('/data.json').then(res=>{
  console.log(res)
})
//实例2
let instance2 = axios.create({
  baseURL: "http://loacalhost:8081",
  timeout: 2000
});
instance2.get("/city.json").then(res => {
  console.log(res);
});

axios实例的相关配置

配置列表
  • baseURL:请求的域名(基本地址)。
  • timeout:请求的超时时长,超出后后端返回401。
  • 备注:一般由后端定义,后端的接口需要的处理时长较长的时候,如果请求的时间过长,后端处理不过来,就会阻塞,给服务器造成较大的压力。设置后,可以及时释放掉。
  • url:请求路径。
  • method:请求方法。如:get、post、put、patch、delete等。
  • headers:请求头。
  • params:将请求参数拼接到url上
  • data:将请求参数放置到请求体里
    axios.create({
        baseURL:'', //请求的域名(基本地址)
        timeout:2000, //请求的超时时长,单位毫秒,默认。
        url:'/data.json', //请求路径
        method:'get', //请求方法
        headers:{
            token:''
        }, //设置请求头
        params:{

        },//将请求参数拼接到url上
        data:{

        }, //将请求参数放置到请求体里
    });

三种配置方式:

  • axios 全局配置
    axios.defaults.baseURL = 'http://localhost:8080'
    axios.defaults.timeout = 2000
  • axios实例配置
    let instance = axios.create();
    instance.defaults.timeout = 3000
  • axios请求配置
    instance.get('/data.json',{
        timeout:5000
    })

优先级:axios全局配置< axios实例配置 < axios请求配置

拦截器

什么是拦截器
在请求前或响应被处理前拦截他们,分为两种:请求拦截器与响应拦截器

  • 请求拦截器
    //   请求拦截器
    axios.interceptors.request.use(config => {
      // 在发送请求前做些什么
      return config;
    }, err=>{
        // 在请求错误的时候的逻辑处理
        return Promise.reject(err)
    });
  • 响应拦截器
    // 响应拦截器
    axios.interceptors.response.use(res => {
      // 在请求成功后的数据处理
      return res;
    }, err=>{
        // 在响应错误的时候的逻辑处理
        return Promise.reject(err)
    });
  • 取消拦截器
	let inter = axios.interceptors.request.use(config=>{
        config.header={
            auth:true
        }
        return config
    })
    axios.interceptors.request.eject(inter)
案例:登录权限
  • 需要token的接口
    // 需要token的接口
    let instance = axios.create({});
    instance.interceptors.request.use(config=>{
        config.headers.token = '';
        return config
    })
  • 不需要token的接口
    // 不需要token接口
    let newInstance = axios.create({});
案例:移动端开发数据加载loading动画
    // 请求的加载动画loading
    let instance_phone = axios.create({});
    instance_phone.interceptors.request.use(config=>{
        $('#loading').show();
        return config
    })
    instance_phone.interceptors.response.use(res=>{
        $('#loading').hide();
        return res
    })

备注:实现的效果是请求数据的时候显示loading动画,数据响应后隐藏loading动画。

错误处理

结合请求拦截器与响应拦截器来说,不管是请求错误还是响应错误,都会执行catch方法。

		//  请求拦截器
    axios.interceptors.request.use(
      config => {
        // 在发送请求前做些什么
        return config;
      },
      err => {
        // 在请求错误的时候的逻辑处理
        return Promise.reject(err);
      }
    );
    // 响应拦截器
    axios.interceptors.response.use(
      res => {
        // 在请求成功后的数据处理
        return res;
      },
      err => {
        // 在响应错误的时候的逻辑处理
        return Promise.reject(err);
      }
    ); 
	axios
      .get("data.json")
      .then(res => {
        console.log(res);
      })
      .catch(err => {
        console.log(res);
      });
错误处理举例

在实际开发中,不会再每次网络请求的时候,都使用catch方法,可以添加统一的错误处理方法。代码如下:

    //   请求错误处理
    let instance = axios.create({});
    instance.interceptors.request.use(
      config => {
        return config;
      },
      err => {
        // 请求错误的常见状态码:4XX  401-请求超时  404-mot found
        $("#error").show();
        setTimeout(()=>{
           $("#error").hide(); 
        }, 2000)
        return Promise.reject(err);
      }
    );
    // 响应错误处理
    instance.interceptors.response.use(
      res => {
        return res;
      },
      err => {
        // 响应错误的常见状态码 5XX 500-服务器错误 502-服务器重启
        $("#error").show();
        setTimeout(()=>{
           $("#error").hide(); 
        }, 2000)
        return Promise.reject(err);
      }
    );
    instance.get("/data.json").then(res=>{
        console.log(res,'请求成功')
    }).catch(err=>{
        console.log(err,'除了拦截器设置的处理之外的其他处理')
    })

思路分析:首先创建实例,给实例设置请求拦截器与响应拦截器。
(1)请求错误的常见状态码以4开头,如401-请求超时、404-接口未找到;
(2)响应错误的常见状态码以5开头,如500-服务器错误、502-服务器重启等。
(3)处理设置请求拦截器与响应拦截器的操作外,如果还要其他操作,我们可以在请求的时候,在使用catch方法。

取消请求(不常用)
代码示例
let source = axios.CancelToken.source();
    axios
      .get("/data.json", {
        cancelToken: source.token
      })
      .then(res => {
       	console.log(res);
      }).catch(err=>{
        console.log(err)
      })
    //   取消请求(参数msg)
      source.cancel('自定的的字符串可选')

应用场景
在查询数据的时候,很长时间(3-5s)仍未获取数据,这个时候需要取消请求。

代理

vue cil2 代理分为旧版本 也就是 vue cil2 这个版本需要在config/index.js下配置

dev: {
    // Paths
    assetsSubDirectory: 'static',
    assetsPublicPath: '/',
    // 后端请求地址代理,配置后testIp再之后的页面调用时就直接指代 http://197.82.15.15:8088
    proxyTable: {
      '/testIp': {
        target: 'http://197.82.15.15:8088',
        changeOrigin: true,
        pathRewrite: { 
          '^/testIp': ''
        }
      },
      '/elseIp': {
        target: 'http://182.83.19.15:8080',
        changeOrigin: true,
        pathRewrite: { 
          '^/esleIp': ''
        }
      },
    },

vue cil 3在 vue.config.js文件下

devServer: {
            overlay: { // 让浏览器 overlay 同时显示警告和错误
              warnings: true,
              errors: true
            },
            host: "localhost",
            port: 8080, // 端口号
            https: false, // https:{type:Boolean}
            open: false, //配置后自动启动浏览器
            hotOnly: true, // 热更新
            // proxy: 'http://localhost:8080'   // 配置跨域处理,只有一个代理
            proxy: { //配置多个代理
                "/testIp": {
                    target: "http://197.0.0.1:8088",
                    changeOrigin: true,
                    ws: true,//websocket支持
                    secure: false,
                    pathRewrite: {
                        "^/testIp": "/"
                    }
                },
                "/elseIp": {
                    target: "http://197.0.0.2:8088",
                    changeOrigin: true,
                    //ws: true,//websocket支持
                    secure: false,
                    pathRewrite: {
                        "^/elseIp": "/"
                    }
                },
            }
        }

当项目有多个后台的时候,可以在api文件夹下 新建一个elseApi.js ,书写当前ip下的接口请求。方法同上,只是 let resquest = "/elseIp/request/" 调用的时候把端口更改一下。

request.js

在项目src目录下新建utils文件夹,然后在其中新建 request.js文件,这个文件是主要书写axios的封装过程。

/****   request.js   ****/
// 导入axios
import axios from 'axios'
// 使用element-ui Message做消息提醒
import { Message} from 'element-ui';
//1. 创建新的axios实例,
const service = axios.create({
  // 公共接口--webpack中的全局变量process.env.BASE_API
  //为了适应多个后台或者开发的时候的api地址和发布的时候的api地址不一样这种情况
  baseURL: process.env.BASE_API,
  // 超时时间 单位是ms,这里设置了3s的超时时间
  timeout: 3 * 1000
})
// 2.请求拦截器
service.interceptors.request.use(config => {
  //发请求前做的一些处理,数据转化,配置请求头,设置token,设置loading等,根据需求去添加
  
  
  ***** 下面详解
   config.data = JSON.stringify(config.data); //数据转化,也可以使用qs转换
   config.headers = {
     'Content-Type':'application/x-www-form-urlencoded' //配置请求头
   }
   //注意使用token的时候需要引入cookie方法或者用本地localStorage等方法,推荐js-cookie
   const token = getCookie('名称');//这里取token之前,你肯定需要先拿到token,存一下
   if(token){
      config.params = {'token':token} //如果要求携带在参数中
      config.headers.token= token; //如果要求携带在请求头中
    }
    *****
    
    
  return config
}, error => {
  Promise.reject(error)
})

// 3.响应拦截器
service.interceptors.response.use(response => {
  //接收到响应数据并成功后的一些共有的处理,关闭loading等
  
  return response
}, error => {
   /***** 接收到异常响应的处理开始 *****/
  if (error && error.response) {
    // 1.公共错误处理
    // 2.根据响应码具体处理
    switch (error.response.status) {
      case 400:
        error.message = '错误请求'
        break;
      case 401:
        error.message = '未授权,请重新登录'
        break;
      case 403:
        error.message = '拒绝访问'
        break;
      case 404:
        error.message = '请求错误,未找到该资源'
        window.location.href = "/NotFound"
        break;
      case 405:
        error.message = '请求方法未允许'
        break;
      case 408:
        error.message = '请求超时'
        break;
      case 500:
        error.message = '服务器端出错'
        break;
      case 501:
        error.message = '网络未实现'
        break;
      case 502:
        error.message = '网络错误'
        break;
      case 503:
        error.message = '服务不可用'
        break;
      case 504:
        error.message = '网络超时'
        break;
      case 505:
        error.message = 'http版本不支持该请求'
        break;
      default:
        error.message = `连接错误${error.response.status}`
    }
  } else {
    // 超时处理
    if (JSON.stringify(error).includes('timeout')) {
      Message.error('服务器响应超时,请刷新当前页')
    }
    error.message('连接服务器失败')
  }

  Message.error(error.message)
  /***** 处理结束 *****/
  //如果不需要错误处理,以上的处理过程都可省略
  return Promise.resolve(error.response)
})
//4.导入文件
export default service0

在Vue中调用接口

用到哪个api 就调用哪个接口——适用于上文接口分类导出;
import {getListAPI,postFormAPI, putSomeAPI, deleteListAPI} from '@/api/api'

  methods: {
      //promise调用,链式调用, getList()括号内只接受参数;
      //   get不传参
      getList() {
        getListAPI().then(res => console.log(res)).catch(err => console.log(err))
      },
		//post传参
      postForm(formData) {
        let data = formData
        postFormAPI(data).then(res => console.log(res)).catch(err => console.log(err))
      },

      //async await同步调用
      async postForm(formData) {
        const postRes = await postFormAPI(formData)
        const putRes = await putSomeAPI({data: 'putTest'})
        const deleteRes = await deleteListAPI(formData.name)
        // 数据处理
        console.log(postRes);
        console.log(putRes);
        console.log(deleteRes);
      },
   }
-----------------------------------------------

把api全部导入,然后用哪个调用哪个api——适用于全部导出

 import api from '@/api/api'
   methods: {
     getList() {
        api.getListAPI(data).then(res => {
          //数据处理
        }).catch(err => console.log(err))
      }
    } 

ES6

ES6是什么

1995年的美国,有一家名为netscape(网景)的公司打造了一款主要用于check验证的脚本语言,而恰在此时,Sun公司的java语言火的一塌糊涂,netscape公司为蹭其热度,便将该脚本语言命名为 JavaScript。不料 JavaScript居然被越来越多的人使用,后效仿大秦的货币统一政策将其提交给国际标准组织ECMA。
该组织发布的标准被称做ECMAScript。 2015年6月发布的版本称为ECMAScript2015,简称ES6。从ES6开始,该组织每年会发布一个版本,版本号比年份最后一位大1,至今最新版本为ES12。
ES6 既是一个历史名词,也是一个泛指,含义是 5.1 版以后的 JavaScript 的下一代标准,涵盖了 ES2015、ES2016、ES2017 等等,而 ES2015 则是正式名称,特指该年发布的正式版本的语言标准

严格模式

介绍

ES5 除了正常运行模式(又称为混杂模式),还添加了第二种运行模式:“严格模式”(strict mode)。严格模式顾名思义,就是使 JavaScript 在更严格的语法条件下运行。

作用

消除 JavaScript 语法的一些不合理、不严谨之处,减少一些怪异行为。
消除代码运行的一些不安全之处,保证代码运行的安全
为未来新版本的 JavaScript 做好铺垫。

使用

在全局或函数的第一条语句定义为: ‘use strict’
如果浏览器不支持,只解析为一条简单的语句, 没有任何副作用

语法和行为改变

  1. 必须用 var 声明变量,不允许使用未声明的变量
  2. 禁止自定义的函数中的 this 指向 window
  3. 创建 eval 作用域
  4. 对象不能有重名的属性(Chrome 已经修复了这个 Bug,IE 还会出现)
  5. 函数不能有重复的形参
  6. 新增一些保留字, 如: implements interface private protected public
  7. 使用call、apply传第一个参数为null或undefined时,this值不会跳转到全局对象

Object扩展方法

var obj = {
     name: "张阳",
    age:18,
    like:[
        "早上跑步",
        "晚上复习",
        "人帅有腹肌"
    ]
}
Object.keys(obj)

遍历obj 对象中的键 (key)

Object.values(obj)

遍历obj 对象的值 (value)

Object.create()

Object.create 方法可以以指定对象为原型创建新的对象,同时可以为新的对象设置属性, 并对属性进行描述
Object.create(proto, propertiesObject)
proto 指定的对象为原型
propertiesObject 设置新的属性

o2 = Object.create({}, {
 p: {
   value: 42,
   writable: true,
   enumerable: true,
   configurable: true
 }
});
  • value : 指定值
  • writable : 标识当前属性值是否是可修改的, 默认为 false
  • configurable:标识当前属性是否可以被删除 默认为 false
  • enumerable:标识当前属性是否能用for in 枚举 默认为 false
读写器

get: 当获取当前属性时的回调函数
set: 当设置当前属性时

Object.defineProperty(obj,“key”,{descriptors}) 只能写一个属性

get,set与value,writable不能同时存在

 Object.defineProperty(obj,"age",{
             value:18,
             writable:true, //可编辑,默认为false
             configurable:true,//可删除,默认为false
             enumerable:true, //可遍历,默认为false
         });
 Object.defineProperty(obj,'name',{
            get:function(){
                return this._name || "今麦郎";
            },
            set:function(v){
                this._name = v;
            }
        })
Object.defineProperties()

defineProperty复数形式

直接在一个对象上定义新的属性或修改现有属性,并返回该对象。

Object.defineProperties(object, descriptors)

  • object 要操作的对象
  • descriptors 属性描述
    • get 作为该属性的 getter 函数,如果没有 getter 则为undefined。函数返回值将被用作属性的值。
    • set 作为属性的 setter 函数,如果没有 setter 则为undefined。函数将仅接受参数赋值给该属性的新值。
var obj2 = Object.defineProperties(obj,{
                name:{
                    value:'老王'
                },
                age:{
                    value:18
                },
                like:{
                    get:function(){
                        // return  _like || [];

                        // 如果不写return 
                        // 默认return undefined;
                    },
                    set:function(v){
                        _like = v;
                    }
                }
            });
call、apply 和 bind
  • call 方法使用一个指定的 this 值和单独给出的一个或多个参数来调用一个函数
  • apply 方法调用一个具有给定 this 值的函数,以及- 作为一个数组(或类似数组对象)提供的参数
  • bind 同 call 相似,不过该方法会返回一个新的函数,而不会立即执行

关键字扩展

let和块级作用域

ES5没有块级作用域

在ES5中,JS 的作用域分为全局作用域和局部作用域。通常是用函数区分的,函数内部属于局部作用域。
ES5只有全局作用域和函数作用域,没有块级作用域,这带来很多不合理的场景

  1. 内层变量可能会覆盖外层变量。
  2. 用来计数的循环变量泄露为全局变量。
块级作用域
  1. 在 ES6 中新增了块级作用域的概念,使用{}扩起来的区域叫做块级作用域
  2. let关键字声明变量,实际上为 JavaScript 新增了块级作用域。
  3. 块作用域由 { } 包括,if语句和for语句里面的{ }也属于块作用域。
  4. 在块内使用let声明的变量,只会在当前的块内有效。
let关键字

ES6新增了let命令,用来声明变量。它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效,也就是增加了块级作用域。

  • 使用块级作用域(let定义的变量属于块级作用域) 防止全局变量污染
    • 块级作用域可以任意嵌套
    • for循环的计数器,就很合适使用let命令
      • 变量i是let声明的,当前的i只在本轮循环有效,所以每一次循环的i其实都是一个新的变量
        你可能会问,如果每一轮循环的变量i都是重新声明的,那它怎么知道上一轮循环的值,从而计算出本轮循环的值?这是因为 JavaScript 引擎内部会记住上一轮循环的值,初始化本轮的变量i时,就在上一轮循环的基础上进行计算
  • for循环还有一个特别之处,就是设置循环变量的那部分是一个父作用域,而循环体内部是一个单独的子作用域
  • 练习1
 var a = [];
 for (var i = 0; i < 10; i++) {
     a[i] = function () {
      	 console.log(i);
     };
}
a[6]();
  • 练习2
    var a = [];
    for (let i = 0; i < 10; i++) {
        a[i] = function () {
        	console.log(i);
        };
 }
 a[6]();
let关键字特点
  • let命令不存在变量提升
    和var不同的还有,let命令不存在变量提升,所以声明前调用变量,都会报错,这就涉及到一个概念——暂时性死区。
    暂时性死区即:区块中存在let或const命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。
  • 不允许重复声明let 只能声明一次而var 可以声明多次。
  • 块级作用域的出现,实际上使得获得广泛应用的匿名立即执行函数表达式不再必要了
  • let 是在代码块内有效,var 是在全局范围内有效
  • 不影响作用域链,let与var都拥有作用域链。
    作用域链: 如果在当前作用域中没有查到值,就会向上级作用域去查,直到查到全局作用域,这么一个查找过程形成的链条就叫做作用域链。
  • 不再是顶层全局对象的属性
    使用var定义的全局变量相当于直接挂载在window对象上, 而let不会。

const关键字

注意:
变量:数据可以变化。在执行过程当中,有一些数据会使用多次,根据条件会变化,一般定义为变量。
常量:不会变化的数据,有些时候有的数据是不允许修改的,所以需要定义常量。
声明一定要赋初始值:一旦声明变量,就必须立即初始化,不能留到以后赋值

  • const 声明一个只读变量,声明之后不允许改变。意味着,一旦声明必须初始化,否则会报错。
  • 值不允许修改
    const 其实保证的不是变量的值不变,而是保证变量指向的内存地址不允许改动。所以 使用 const 定义的对象或者数组,其实是可变的。
    • const只在声明所在的块级作用域内有效。(与let相同)
    • const命令声明的常量也是不会提升(与let相同)
    • const不可重复声明(与let相同)
    • 不再是顶层全局对象的属性(与let相同)
      let命令、const命令、class命令声明的全局变量,不属于顶层对象的属性。也就是说,从 ES6 开始,全局变量将逐步与顶层对象的属性脱钩。
  • const使用的两点建议:
    1、被多次使用且不允许更改的数据建议通过const定义;
    2、项目全局常量建议大写,单词之间用-分隔;
    3、如果不清楚要使用let还是const,那么就用const。如果后面发生值的改变,那么再将const改成let.
    4、以后不允许使用var

块级作用域的函数声明

  • 函数声明一般常用的是两种,一种是function声明,一种是函数表达式。
    • 建议函数在顶层作用域和函数作用域之中声明,尽量避免在块级作用域声明。( "use strict"下报错)
    • 如果确实需要,也应该写成函数表达式,而不是函数声明语句。

变量的解构赋值(重点)

什么是变量的解构赋值

解构 → 解析,重构。
解构的目标:数组以及对象。
ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构。
解构赋值本质就是赋值:把结构解散重构然后赋值。
解构赋值是对赋值运算符=的一种扩展。
在代码书写上简洁且易读,语义更加清晰明了;也方便了复杂对象中数据字段获取。

引入

在ES5中,开发者们为了从对象和数组中获取特定数据并赋值给变量,编写了许多看起来同质化的代码 ;

解构赋值语法

解构的目标 = 解构源;(目标指的是定义的常量或变量,解析源一般指的是数组或对象)
解构目标:定义的常量或变量
解构源:待解构的数组或对象

对象解构赋值

  • 对象解构赋值基本语法
    对象的语法形式是在一个赋值操作符= 右边放置一个对象字面量
  • 顺序不用一一对应
    • = 右侧可以是一个常或变量
    • 嵌套对象解构
      解构嵌套对象仍然与对象字面量的语法相似,可以将对象拆解以获取想要的信息
  • 可忽略部分解构源的属性
  • 剩余运算符
  • 不完全解构:变量名称在对象中不存在
    使用解构赋值表达式时,如果指定的变量名称在对象中不存在,那么这个变量会被赋值为undefined
  • 解构默认值(常用)
    当指定的属性不存在时,可以定义一个默认值:在属性名称后添加一个等号(=)和相应的默认值即可
    • 为非同名局部变量赋值 ,可避免命名冲突
      如果希望使用不同命名的局部变量来存储对象属性的值,ES6中的一个扩展语法可以满足需求,这个语法与完整的对象字面量属性初始化程序的很像。
      函数传参数
      解构赋值表达式的值与表达式右侧(也就是=右侧)的值相等,如此一来,在任何可以使用值的地方都可以使用解构赋值表达式

数组解构赋值

  • 基本使用
    与对象解构的语法相比,数组解构就简单多了,它使用的是数组字面量,且解构操作全部在数组内完成,而不是像对象字面量语法一样使用对象的命名属性 。
  • 忽略元素
    在解构模式中,可以直接省略元素,只为感兴趣的元素提供变量名 。
  • 变量交换
    数组解构语法还有一个独特的用例:交换两个变量的值。在排序算法中,值交换是一个非常常见的操作,如果要在ES5中交换两个变量的值,则须引入第三个临时变量
  • 添加默认值
    也可以在数组解构赋值表达式中为数组中的任意位置添加默认值,当指定位置的属性不存在或其值为undefined时使用默认值
  • 嵌套数组解构
    嵌套数组解构与嵌套对象解构的语法类似,在原有的数组模式中插入另一个数组模式,即可将解构过程深入到下一个层级
  • 不定元素
    函数具有不定参数,而在数组解构语法中有一个相似的概念——不定元素。在数组中,可以通过…语法将数组中的其余元素赋值给一个特定的变量
  • 数组复制
    在ES5中,开发者们经常使用concat()方法来克隆数组

解构传递参数

  • 解构赋值可以应用在函数参数的传递过程中。
    • 如果调用函数时不传入参数或设置默认值,被解构的参数会导致程序抛出错误
    • 可以为解构参数指定默认值

解构返回结果

函数的多个返回值获取

字符串解构(了解)

字符串也可以解构赋值。这是因为,字符串被转换成了一个类似数组的对象

数值和布尔值解构(了解)

解构赋值时,如果等号右边是数值和布尔值,则会先转为对象

spread运算符与rest参数

在ES6中, 三个点(…) 有2个含义。分别表示扩展运算符(spread运算符) 和 剩余运算符(spread运算符)

spread运算符

  • 复制、合并数组
  • 复制、合并对象
  • 解构数组与对象
  • 字符串转换为数组
  • 伪数组转为真数组

rest参数

  • rest 参数(形式为…变量名),rest运算符用于获取函数调用时传入的参数。
  • 和普通参数混合使用的时候,需要放在参数的最后
  • 函数的length属性,不包括 rest 参数

VUE.js

vue导入

概述

Vue是一个类似于Jquery的一个JS框架,所以,如果想使用Vue,则在当前页面导入Vue.js文件即可。

语法

<!-- 在线导入 -->
<!-- 开发环境版本,包含了用帮助的命令行警告 -->
<script src="https://cdn.jsdelivr/npm/vue/dist/vue.js"></script>
<!-- 生产环境版本,优化了尺寸和速度 -->
<script src="https://cdn.jsdelivr/npm/vue"></script>

<!-- 本地导入 -->
<script src="node_modules/vue/dist/vue.js"></script>

案例

<div id="app">
    <h1>用户名:<input type="text" v-model="name"/></h1> <br/>
    <h1>您输入的用户名是: {{name}}</h1>
</div>

<script type="text/javascript">
    //创建一个Vue对象
    var app = new Vue({
        //指定,该对象代表<div id="app">,也就是说,这个div中的所有内容,都被当前的app对象管理
        el: "#app",
        //定义vue中的数据
        data: {
            name: ""
        }
    });
</script>

vue的基本语法

1. 钩子函数

概述:钩子函数, 其实就是Vue提前定义好的事件, 其作用类似于Servlet的init方法和distory方法
语法:

<script type="text/javascript">
    var app = new Vue({
        el:"#app",
        //钩子函数created,该方法在页面显示之后,自动执行
        created() {
            console.log("created...");
        }
    });
</script>

补充:vue声明周期和钩子函数

(1)什么是vue生命周期?
Vue 实例从创建到销毁的过程,就是生命周期。也就是从开始创建、初始化数据、编译模板、挂载Dom→渲染、更新→渲染、卸载等一系列过程,我们称这是 Vue 的生命周期。
(2)vue生命周期的作用是什么?
Vue生命周期中有多个事件钩子,让我们在控制整个Vue实例过程时更容易形成好的逻辑。
(3)vue生命周期总共有几个阶段?
可以总共分为8个阶段:创建前/后, 载入前/后,更新前/后,销毁前/后。
(4)第一次页面加载会触发哪几个钩子?
第一次页面加载时会触发 beforeCreate, created, beforeMount, mounted 这几个钩子
(5)DOM 渲染在 哪个周期中就已经完成?
DOM 渲染在 mounted 中就已经完成了。
(6)简单描述每个周期具体适合哪些场景?
生命周期钩子的一些使用方法:
beforecreate : 可以在此阶段加loading事件,在加载实例时触发;
created : 初始化完成时的事件写在这里,如在这结束loading事件,异步请求也适宜在这里调用;
mounted : 挂载元素,获取到DOM节点;
updated : 如果对数据统一处理,在这里写上相应函数;
beforeDestroy : 可以做一个确认停止事件的确认框;
nextTick : 更新数据后立即操作dom;

2. 插值表达式

概述插值表达式用户把vue中所定义的数据,显示在页面上. 插值表达式允许用户输入"JS代码片段"
语法:{{ 变量名/对象.属性名 }}
案例:

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vue插值表达式</title>
    <script src="node_modules/vue/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <h1>欢迎来到-->{{ name }}</h1>
    </div>
    <script type="text/javascript">
        //创建vue对象
        var app = new Vue({
            //让vue接管div标签
            el:"#app",
            //定义数据,里边包含一个属性name,值为"白大锅"
            data:{
                name:"白大锅"
            }
        });
    </script>
</body>
</html>

3.显示数据(v-text和v-html)

概述:
​ v-text和v-html专门用来展示数据, 其作用和插值表达式类似。v-text和v-html可以避免插值闪烁问题.
​ 当网速比较慢时, 使用{{}}来展示数据, 有可能会产生插值闪烁问题。
​ 插值闪烁: 在数据未加载完成时,页面会显示出原始的{{}}, 过一会才会展示正常数据.
语法:

v-text:<span v-text="msg"></span>	<!-- 相当于<span>{{msg}}</span> -->
v-html:<span v-html="msg"></span>	<!-- 相当于<span>{{msg}}</span> -->

区别
v-text:把数据当作纯文本显示.
v-html:遇到html标签,会正常解析

4.数据双向绑定数据(v-model)

概述:
​ Vue的双向绑定可以实现: 数据变化的时候, 页面会自动刷新, 页面变化的时候,数据也会自动变化.
注意:
双向绑定, 只能绑定文本框,单选按钮,复选框,文本域,下拉列表
文本框/单选按钮/textarea, 绑定的数据是字符串类型
单个复选框, 绑定的是boolean类型
多个复选框, 绑定的是数组
select单选对应字符串,多选对应也是数组

4.2.绑定单个复选框

代码

<div id="app">
    <input type="checkbox" v-model="agree">同意<br>
</div>
<script type="text/javascript">
    var app = new Vue({
        el:"#app",
        data:{
            agree:true
        }
    });
</script>

效果

4.2.绑定单个复选框

代码

<div id="app">
    <input type="checkbox" v-model="agree">同意<br>
</div>
<script type="text/javascript">
    var app = new Vue({
        el:"#app",
        data:{
            agree:true
        }
    });
</script>

效果:

4.3.绑定多个复选框

** 代码**

<div id="app">
    <input type="checkbox" value="Java" v-model="language">Java<br>
    <input type="checkbox" value="Python" v-model="language">Python<br>
    <input type="checkbox" value="Swift" v-model="language">Swift<br>
</div>
<script type="text/javascript">
    var app = new Vue({
        el:"#app",
        data:{
            //数组中的值,就是被选中的元素的value属性值
            language:["Java","Python"]
        }
    });
</script>

效果

4.4.form表单数据提交

例子:传json格式跟formData格式的两种情况

<template>
  <div class="from_box">
    <form action="">
      <input type="text"  placeholder="请输入昵称" v-model="formMess.account">
      <input type="password" placeholder="请输入密码" v-model="formMess.act_pwd">
      <input type="text" placeholder="请输入手机号" v-model="formMess.phone">
    </form>
    <span class="but" @click="onSubmit()">提交</span>
  </div>
</template>
 
<script>
import axios from 'axios';
 
export default {
  name: "from",
  data() {
    return {
    	formMess:{
	    "account":"",
	    "act_pwd":"",
	    "phone":""
	}
    };
  },
  methods: {
    onSubmit() {
      /* json格式提交: */
      // let formData = JSON.stringify(this.formMess);
 
      /* formData格式提交: */
      let formData = new FormData();
      for(var key in this.formMess){
        formData.append(key,this.formMess[key]);
      }
 
        axios({
	    method:"post",
	    url:"xxxxxxx",
	    headers: {
		  "Content-Type": "multipart/form-data"
	    },
	    withCredentials:true,
	    data:formData
	}).then((res)=>{
            console.log(res);
        });
    }
  }
};
</script>
 
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="less">
.from_box{
  form{
    width:90%;
    margin: auto;
    border:.01rem solid gray;
    display: flex;
    flex-wrap: wrap;
    input{
      width:80%;
      height:.5rem;
      margin-bottom: .2rem;
      border:.01rem solid black;
      height:.5rem;
    }
  }
  .but{
    font-size: .14rem;
    margin-left:5%;
  }
}
</style>

5.事件处理(v-on)

5.1.事件绑定(v-on)

概述:

​ Vue中也可以给页面元素绑定事件.

语法:

<!--完整写法-->
<button v-on:事件名="函数名/vue表达式">点我</button>
<!--简化写法-->
<button @事件名="函数名/vue表达式">点我</button>

注意
​ Vue支持html中所有已知事件. 如: @click, @submit等, 只不过事件的名字不带on
案例

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vue事件处理</title>
    <script src="node_modules/vue/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <button @click="show">点我</button>
    </div>
    <script type="text/javascript">
        //创建vue对象
        var app = new Vue({
            //获取id为app的元素,该元素被vue对象所管理.只有被vue对象管理的标签,其内部才允许书写vue语法
            el:"#app",
            //定义vue的方法
            methods:{
                //定义show方法,弹出提示框
                show() {
                    alert("Hello Vue!!!");
                }
            }
        });
    </script>
</body>
</html>
5.2.事件修饰符

概述:
事件修饰符主要对事件的发生范围进行限定
语法:

<button @事件名.事件修饰符="函数名/vue表达式">点我</button>

分类:

.stop :阻止事件冒泡, 也就是当前元素发生事件,但当前元素的父元素不发生该事件
.prevent :阻止默认事件发生
.capture :使用事件捕获模式, 主动获取子元素发生事件, 把获取到的事件当自己的事件执行
.self :只有元素自身触发事件才执行。(冒泡或捕获的都不执行)
.once :只执行一次

案例

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vue事件处理</title>
    <script src="node_modules/vue/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <button @click="show">点我</button>
    </div>
    <script type="text/javascript">
        //创建vue对象
        var app = new Vue({
            //获取id为app的元素,该元素被vue对象所管理.只有被vue对象管理的标签,其内部才允许书写vue语法
            el:"#app",
            //定义vue的方法
            methods:{
                //定义show方法,弹出提示框
                show() {
                    alert("Hello Vue!!!");
                }
            }
        });
    </script>
</body>
</html>

6.循环遍历(v-for)

6.1.遍历数组

语法:

<h v-for="item in items">
<h v-for="(item,index) in items">

items:要迭代的数组
item:存储数组元素的变量名
index:迭代到的当前元素索引,从0开始。
代码

<div id="app">
	<ul>
        <li v-for="(user, index) in users">
        	{{index}}--{{user.name}}--{{user.age}}--{{user.gender}}
        </li>
	</ul>
</div>
<script>
    var app = new Vue({
        el:"#app",//el即element,要渲染的页面元素
        data: {
            users:[
                {"name":"白卓冉","age":8,"gender":"男"},
                {"name":"白大锅","age":12,"gender":"女"},
                {"name":"白仙女","age":4,"gender":"男"}
            ]
        }
    });
</script>
6.2.遍历对象

语法

v-for="value in object"
v-for="(value,key) in object"
v-for="(value,key,index) in object"

value,对象的值
key, 对象的键
index, 索引,从0开始
代码:

<div id="app">
	<ul>
        <li v-for="(value,key,index) in person">
        	{{index}}--{{key}}--{{value}}
        </li>
	</ul>
</div>
<script>
    var app = new Vue({
        el:"#app",//el即element,要渲染的页面元素
        data: {
            person:{"name":"白大锅", "age":3, "address":"中国"}
        }
    });
</script>
6.3.key

概述:
​ :key 一般配合v-for一起使用. 用来在特定情况下, 保证被遍历的数组中的元素的顺序.
案例:

<div id="app">
    <button @click="add">添加</button>
    <ul>
        <li v-for="name in list">
            <input type="checkbox"> {{name}}
        </li>
    </ul>
</div>
<script>
    var app = new Vue({
        el: '#app',
        data: {
            list: ["孙悟空", "猪八戒", "沙和尚"]
        },
        methods: {
            add() {
                //注意这里是unshift,向数组的头部添加一个元素
                this.list.unshift("唐僧");
            }
        }
    });
</script>

解决方案

<div id="app">
    <button @click="add">添加</button>
    <ul>
        <!-- 添加:key即可. 注意,key中的值必须是唯一且不会改变的值-->
        <li v-for="name in list" :key="name">
            <input type="checkbox"> {{name}}
        </li>
    </ul>
</div>

判断语法(v-if和v-show)

概述:

v-if与v-show可以根据条件的结果,来决定是否显示指定内容.
​ v-if: 条件不满足时, 元素不会存在.
​ v-show: 条件不满足时, 元素不会显示(但仍然存在).

案例:

<div id="app">
	<button @click="show = !show">点我</button>
	<h1 v-if="show">Hello v-if.</h1>
    <h1 v-show="show">Hello v-show.</h1>
</div>
<script>
    var app = new Vue({
        el:"#app",
        data: {
        	show:true
        }
    });
</script>

8.显示数据(v-bind)

概述:

v-bind的作用和插值表达式差不多, 只不过, v-bind主要用于动态设置标签的属性值
语法:

<!--完整写法-->
<标签名 v-bind:标签属性名="vue实例中的数据属性名"/>
<!--简化写法-->
<标签名 :标签属性名="vue实例中的数据属性名"/>

案例:

<div id="app">
    <input type="button" :value="msg"/>
</div>
<script type="text/javascript">
    var app = new Vue({
        el:"#app",
        data:{
           msg:"我是按钮"
        }
    });

</script>

9.Vue页面挑战(两种方法)

9.1.方法一(标签实现)
<router-link :to="{name: 'bookshelf', params: { entityId: this.entityId } }"
             :class="{'flex-item-1':'flex-item-1',cur:tabs[0].isShow}" href="javascript:">
              <span class="tabNav-ico tabNav-book"></span>
              <span class="tabNav-txt">书 架</span>
</router-link>
9.1.方法二(this.$router.push()实现)

当this.$router.push()只有一个参数时 默认为跳转地址 最多可传两个参数 第二个参数为地址参数

 var app = new Vue({
     el:"#app",
     //计算属性必须放在Vue的computed中
     computed:{
         //定义计算属性
         属性名(){
             return "返回值";
         }
     }
});

三、Vue其他语法

1.计算属性

概述:
计算属性就是一个提前定义好的方法, 该方法可以看作是一个特殊的值, 可以在插值表达式中使用.
语法:

 var app = new Vue({
     el:"#app",
     //计算属性必须放在Vue的computed中
     computed:{
         //定义计算属性
         属性名(){
             return "返回值";
         }
     }
});

案例

<div id="app">
    <h1>{{birth}}</h1>
    <h1 v-text="birth"></h1>
    <h1 v-html="birth"></h1>
</div>
<script type="text/javascript">
    var app = new Vue({
        el:"#app",
        computed:{
            //定义一个birth方法,该方法就是一个计算属性,可以在插值表达式中使用
            birth(){
                let date = new Date();
                let year = date.getFullYear();
                let month = date.getMonth()+1;
                let day = date.getDay();
                return year + "-" + month + "-" + day;
            }
        }
    });
</script>
2.watch监控

概述:
​ watch可以监听简单属性值及其对象中属性值的变化.
​ watch类似于onchange事件,可以在属性值修改的时候,执行某些操作.
语法:

var app = new Vue({
    el:"#app",
    data:{
        message:"白大锅",
        person:{"name":"heima", "age":13}
    },
    //watch监听
    watch:{
        //监听message属性值,newValue代表新值,oldValue代表旧值
        message(newValue, oldValue){
        	console.log("新值:" + newValue + ";旧值:" + oldValue);
        },
        //监控person对象的值,对象的监控只能获取新值
        person: {
            //开启深度监控;监控对象中的属性值变化
            deep: true,
            //获取到对象的最新属性数据(obj代表新对象)
            handler(obj){
                console.log("name = " + obj.name + "; age=" + obj.age);
            }
        }
    }
});

四、Vue组件

4.1.基本使用

概述:
组件, 类似于模版, 模块. 在项目需要重用某个模块(头部、尾部、新闻。。。)的时候,可以将模块抽取成组件,其它页面中注册组件并引用。
案例:

<div id="app">
    <!--使用组件(组件名称),如果组件名称中有大写字母,如"myList",则这里需要书写<my-list>-->
    <counter></counter>
    <counter></counter>
</div>
<script type="text/javascript">
    //定义组件
    const counterTemp = {
        //定义组件的模版
        template:`<button @click='num++'>你点击了{{num}}次</button>`,
        //定义组件中使用到的数据属性
        data(){
           return {
              num:0
           }
        } 
    };    

    //全局注册组件:在所有的vue实例中都可以使用组件
    //参数1:组件名称,参数2:具体的组件
    //Vueponent("counter", counterTemp);
    var app = new Vue({
        el:"#app",
        //局部注册组件: 只能在当前Vue实例中使用
        components:{
            //组件名称:具体组件
            counter: counterTemp
        }
    });
</script>

注意:

组件的模版中, 只能书写一个跟标签
组件的定义必须放在Vue创建对象之前, 否则报错

4.2.父组件向子组件通信

概述:

子组件无法直接使用父组件中的数据, 如果需要使用, 则必须由父组件把数据传递给子组件才可以.
本质: 让子组件中的属性与父组件中的属性进行关联绑定, 然后子组件使用该属性, 这样才能做到数据传递

意义:

可以把父组件中的数据, 更新传递到子组件

示例:

<div id="app">
     <!-- 把父组件中的count传递给子组件的number属性,把父arr传递给子ids,把父p传递给子person -->
    <aaa :number="count" :ids="arr" :person="p"></aaa>
</div>

<script>
    var aaa = {
        //定义组件的模版
        template: `<h2>{{num}}---{{number}}--{{ids}}--{{person}}</h2>`,
        //定义组件中使用到的数据属性
        data() {
            return {
                num: 0
            }
        },
        //给组件添加属性
        props: {
            //普通属性number
            number: "",
            //数组属性ids
            ids: [],
            //对象属性person
            person: {}
            /*
            *	//以上属性还可以书写为以下格式
            *	items:{
            *        //数据类型,如果是数组则是Array,如果是对象则是Object
            *       type:Array,
            *       //默认值
            *       default:[]
            *	}
            */
        }
    };

    //注册:全局注册
    Vue.component("aaa", aaa);

    var app = new Vue({
        el: "#app",
        data: {
            count: 5,
            arr: [1, 2, 3],
            p: {username: "zhangsan", age: 23}
        }
    });
</script>

4.3.子组件向父组件通信

概述

子组件无法直接给父组件传递数据. 也无法操作父组件中的数据, 更无法调用父组件中的方法.
所以, 所谓的子组件向父组件通讯, 其实就是想办法让子组件调用父组件的方法. 进而响应到父组件中的数据.

意义

子组件可以调用父组件中的方法

示例:

<div id="app">
    <h1>父组件中:app_num={{app_num}}</h1>
    <!-- 把父组件的add方法,绑定给子组件的aaa属性,绑定方法使用@属性名="方法名" -->
    <!-- 把父组件的rem方法,绑定给子组件的bbb属性,绑定方法使用@属性名="方法名 -->
    <!-- 把父组件的app_num变量,绑定给子组件的counter_num属性,绑定变量使用:属性名="方法名 -->
    <counter @aaa="add" @bbb="rem" :counter_num="app_num"></counter>
</div>

<script>
    //定义一个组件(模版)
    let counter = {
        template: `
             <div>
                   <h1>子组件中:counter_num={{counter_num}}</h1>
                   <input type="button" @click="fun1" value="+"/>
                   <input type="button" @click="fun2" value="-"/>
            </div>
                `,
        props:{
            //定义属性counter_num,用来接收父组件传递的数据
            counter_num:null,
            //定义aaa属性,用来绑定父组件的方法,当然,该定义也可以省略
            aaa:function(){},
            //定义bbb属性,用来绑定父组件的方法,当然,该定义也可以省略
            bbb:function(){},
        },       
        methods:{
            fun1(){
                //找到aaa属性所绑定的那个方法,执行那个方法
                return this.$emit("aaa");
            },
            fun2(){
                //找到bbb属性所绑定的那个方法,执行那个方法
                return this.$emit("bbb");
            }
        }
    }

    var app = new Vue({
        el: '#app',
        data: {
            app_num: 0
        },
        components: {
            counter
        },
        methods:{
            add(){
                this.app_num++;
            },
            rem(){
                this.app_num--;
            }
        }
    });
</script>

五、axios异步请求

5.1 axios概述

概述:

axios是一个基于 promise 的 HTTP 库, 主要用于:发送异步请求获取数据。
常见的方法:
​ axios(config)
​ axios.get(url, [config])
​ axios.post(url, [data])

发送数据config常用参数:

{
    url: '请求的服务器',
	method: '请求方式', // 默认是 get
    // GET请求参数
    params: {
    	参数名: 参数值
    },
	// POST请求参数, 如果使用axios.post,则参数在url之后直接书写,不需要该位置传递参数
    data: {
    	参数名: 参数值
    },
	// 响应数据格式,默认json
	responseType: 'json'
}

响应数据常用参数:

{
    data: {},		//真正的响应数据(响应体)
    status: 200,	//响应状态码
    statusText: 'OK',	 //响应状态描述
    headers: {},	//响应头
    config: {}		//其他配置信息
}

5.2.Get请求

var app = new Vue({
    el: "#app",
    data: {
        user: {}
    },
    //当页面加载完毕后
    created() { 
        //发送GET请求axios.get("请求路径",{ config });
       axios.get("请求路径",{
            //get请求参数
            params: {
                name:"zhangsan",
                age:23
            },
            //响应数据格式为"json"
            responseType: 'json'
        }).then(res => {
            //打印响应数据
            console.log(res);
            //把响应数据赋值给Vue中的user属性
            app.user = res.data;
        }).catch(err => {
            //打印响应数据(错误信息)
            console.log(err);
        });
    }
});

5.3.Post请求

var app = new Vue({
    el: "#app",
    data: {
        user: {}
    },
    //当页面加载完毕后
    created() { 
        //发送POST请求axios.post("请求路径",{ 参数 });
        axios.post("请求路径",{
                name:"zhangsan",
                age:23
            }).then(res => {
                console.log(res);
                app.user = res.data;
            }).catch(err => {
                console.log(err);
            });
    }
});

5.4.跨域请求

跨域请求:在前端js中如果发送异步请求的话,请求的地址与当前服务器的ip或者端口号不同都是跨域请求.
跨域请求需要在服务提供方, 开启允许跨域请求

六、VueJs Ajax

6.1.vue-resource

vue-resource是Vue.js的插件提供了使用XMLHttpRequest或JSONP进行Web请求和处理响应的服务。 当vue更新
到2.0之后,作者就宣告不再对vue-resource更新,而是推荐的axios,在这里大家了解一下vue-resource就可以。
vue-resource的github: https://github/pagekit/vue-resource

6.2.axios

Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中
axios的github:https://github/axios/axios

6.2.1.引入axios

首先就是引入axios,如果你使用es6,只需要安装axios模块之后
import axios from ‘axios’;
//安装方法
npm install axios
//或
bower install axios
当然也可以用script引入

<script src="https://unpkg/axios/dist/axios.min.js"></script>
6.2.2.get请求
//通过给定的ID来发送请求
axios.get('/user?ID=12345')
.then(function(response){
console.log(response);
}).catch(function(err){
console.log(err);
});
//以上请求也可以通过这种方式来发送
axios.get('/user',{
params:{
ID:12345
}
}).then(function(response){
console.log(response);
}).catch(function(err){
console.log(err);
});
6.2.3.post请求
axios.post('/user',{
firstName:'Fred',
lastName:'Flintstone'
})
.then(function(res){
console.log(res);
})
.catch(function(err){
console.log(err);
});

为方便起见,为所有支持的请求方法提供了别名

axios.request(config)
axios.get(url[, config])
axios.delete(url[, config])
axios.head(url[, config])
axios.post(url[, data[, config]])
axios.put(url[, data[, config]])
axios.patch(url[, data[, config]])

本文标签: 入门