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’
如果浏览器不支持,只解析为一条简单的语句, 没有任何副作用
语法和行为改变
- 必须用 var 声明变量,不允许使用未声明的变量
- 禁止自定义的函数中的 this 指向 window
- 创建 eval 作用域
- 对象不能有重名的属性(Chrome 已经修复了这个 Bug,IE 还会出现)
- 函数不能有重复的形参
- 新增一些保留字, 如: implements interface private protected public
- 使用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只有全局作用域和函数作用域,没有块级作用域,这带来很多不合理的场景
- 内层变量可能会覆盖外层变量。
- 用来计数的循环变量泄露为全局变量。
块级作用域
- 在 ES6 中新增了块级作用域的概念,使用{}扩起来的区域叫做块级作用域
- let关键字声明变量,实际上为 JavaScript 新增了块级作用域。
- 块作用域由 { } 包括,if语句和for语句里面的{ }也属于块作用域。
- 在块内使用let声明的变量,只会在当前的块内有效。
let关键字
ES6新增了let命令,用来声明变量。它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效,也就是增加了块级作用域。
- 使用块级作用域(let定义的变量属于块级作用域) 防止全局变量污染
- 块级作用域可以任意嵌套
- for循环的计数器,就很合适使用let命令
- 变量i是let声明的,当前的i只在本轮循环有效,所以每一次循环的i其实都是一个新的变量
你可能会问,如果每一轮循环的变量i都是重新声明的,那它怎么知道上一轮循环的值,从而计算出本轮循环的值?这是因为 JavaScript 引擎内部会记住上一轮循环的值,初始化本轮的变量i时,就在上一轮循环的基础上进行计算
- 变量i是let声明的,当前的i只在本轮循环有效,所以每一次循环的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]])
本文标签: 入门
版权声明:本文标题:前端入门到转行 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://m.elefans.com/xitong/1727190812a1101412.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论