标题1 组件注册
- 全局组件注册
Vue.component
- 示例代码:
Vue.component('my-cart',{
data:function(){
return {返回的是组件中使用的数据}
},
template:`<h1>这是组件的模板结构</h1>`
})
- 参数分析:
- data:必须是一个带有return返回值的函数,return返回的是一个对象,对象中是template模板中要使用的数据
- template模板:使用模板字符串包裹比较好,里面是组件的模板类型
- 在组件中,除了没有el,其他的参数可以和vue实例对象一样使用
- 局部组件注册:
components:{'组件名':template}
属性和methods同级。
局部组件一定要在实例上注册,才能在html上使用
var ComponentA={
data:function() {
return {msg:0}
},
template:''
};
components:{
'component-a':ComponentA
}
注:组件的命名规则,一般以短横线命名,如果使用大驼峰的形式命名的化,可以在template中使用大驼峰,但是在HTML标签中必须使用短横线的形式。因此组件大多都是使用短横线命名的
标题2 组件数据之间的相互传递(父传子、子传父、兄弟)
-
父组件和子组件的区分
在组件中声明的template模板就是子组件,组件标签相对于模板来说就是父组件 -
父组件向子组件传递数据
- 父组件通过v-bind属性绑定的形式向子组件传值
- 子组件通过props属性接收父组件传递过来的值(props是一个数组的形式存储值)
//1.父组件传值,父组件先通过v-bind绑定要传输的数据
<my-cate :title='ptitle'></my-cate>
//2.子组件接收值。子组件通过接收父组件绑定的属性名获取值
Vue.component('my-cate',{
props:['title'],
data:function() {
msg:'123'
},
template:`<h1>{{title}}</h1>`//这里可以直接把props属性里面的值拿过来使用
})
//3.vue实例对象
var vm=new Vue({
el:'#app',
data:{
ptitle:'这是要向子组件传递的值'
}
})
//页面的最终结果就是“这是要向子组件传递的值”
props的命名规则:如果单词较长的话,只能使用小驼峰的形式,但是在html标签(父组件)中必须使用短横线的形式。所以一般情况下,在命名的时候用一个较短的单词即可。
- 子组件向父组件传值(通过父组件来触发子组件的事件)
- 子组件通过自定义事件向父组件传值(
$emit('事件名',参数)
) - 父组件通过事件绑定的形式监听子组件
- 子组件自定义事件中传递的参数在父组件中使用
$event
接收 $emit()
只能传递两个参数,一个是事件名,一个是需要传递的参数,如果传递的参数有多个就使用数组或者对象的形式
//1.父组件事件绑定,事件绑定的事件名必须和子组件中的自定义事件名相同
<div id='app'>
<span>{{num}}</span>
<menu-item v-on:event-event='handle($event)'></menu-item>
</div>
//2.子组件通过$emit进行自定义事件
Vue.component('menu-item',{
data:function(){
msg:''123
},
template:`<button @click='$emit('event-name',2)'>点击</button>`
//也可以写成下面这一种单独的形式,把触发事件的$emit写在方法中
methods:{
eventName:function(参数){
this.$emit('event-name',e)
}
}
//模板中就变成了一下的写法
template:`<button @click='eventName(参数e)'>点击</button>`
})
//3.父组件中事件绑定的事件在vue实例对象中声明
var vm=new Vue({
el:'#app',
data:{num:0}
methods:{
handle:function(val) {//使用val接收$event,也就是子组件中的2,如果是数组或者对象,这里也需要用相同的方式接收
this.num+=val//点击按钮,num每次自加2
}
}
})
- 兄弟组件之间的数据传递(通过事件中心来监听和触发事件)
- 事件中心实际上是一个空的vue实例对象
var hub=new Vue()
- 监听事件:
hub.$on()
- 触发事件:
hub.$emit()
- 销毁事件:
hub.$off()
案例:在兄弟组件A中,通过$emit
触发组件B中添加的事件;在兄弟组件B中,通过$emit
触发组件A中添加的事件
//html结构
<div id='#app'>
<test-tom></test-tom>
<test-jerry></test-jerry>
</div>
//1.注册一个事件中心
var hub=new Vue()
//2.注册兄弟组件A
Vue.component('test-tom',{
data:function() {return{num:0}}
template:`<button @click='handle'></button>`,
methods:{
handle:function() {
//4.触发兄弟组件B的事件
hub.$emit('jerry-event',2)
}
},
//3.向事件中心注册自己的事件
mounted:function() {
//监听事件
hub.$on('tom-event',(val) => {//注意这里不能使用function,因为function是被hub调用的,hub对象中没有num这个值,箭头函数this指向它的上一级父级
this.num+=val
})
}
//注册一个兄弟组件B
Vue.component('test-jerry',{
data:function() {
return {num:1}
},
template:`<button @click='handle'></button>`,
methods:{
handl:function() {
hub.$emit('tom-event',1)
}
},
mounted:function() {
hub.$on('jerry-event',val => {this.num+=val})
}
})
})
标题 3 组件插槽的使用(slot标签)
- 概念:父组件向子组件传递内容,子组件在template中定义slot插槽标签,用于接收父组件内部传递的内容部分(开始标签和结束标签中间的文本内容)
- 插槽位置
Vue.component('tab-com',{
template:`
<div class='demo'>
<strong>location:</strong>
<slot></slot>
</div>
`
})
- 插槽内容
<tab-com>这是填充到子组件插槽的内容</tab-com>
- 具名插槽(就是有name属性的插槽)
- 定义具名插槽时,使用name属性,定义name=‘插槽名’
- 使用插槽时,在标签内部使用slot='插槽名’来使用对应的插槽
//1.定义具名插槽
Vue.component('alert-com',{
template:`
<div class='demo'>
<strong>location:</strong>
<slot name='header'></slot>
</div>
`
})
//2.使用具名插槽
<alert-com>
<p slot='header'>Content</p>
</alert-com>
- 如果传递的内容是多个标签,那么需要使用template来包裹,给template添加slot属性即可
<alert-com>
<template slot='header'>
<p>标题信息1</p>
<p>标题信息2</p>
</template>
</alert-com>
- 作用域插槽(在父组件中修改已经定义好的子组件)
作用:就是将父组件的template标签内容,插入到slot插槽中
- 子组件给slot插槽定义绑定自定义属性
- 父组件中的template标签通过
slot-scope
属性接收slot中自定义属性的值 - slotProps可以获取自定义属性item(v-bind绑定的属性)
slot-scope:"slotProps"
步骤: - 定义组件时,绑定自定义属性
Vue.component('fruit-list', {
props: ['list'],
template: `
<div>
<li :key='item.id' v-for='item in list'>
<slot :info='item'></slot>
</li>
</div>
`
});
//将自定义属性info与item绑定,item可以是组件中data的数据,也可以是有父组件传递
- 使用组件时,在组件中添加一个template标签作为内容(内部)
<fruit-list :list='list'>
<template slot-scope='slotProps'>
<strong v-if='slotProps.info.id==3' class="current">{{slotProps.info.name}}</strong>
<span v-else>{{slotProps.info.name}}</span>
</template>
</fruit-list>
//template接收slot绑定属性的数据,然后根据这个数据控制将要插入到slot中的内容
标题4 接口调用方式之-Promise
接口调用方式:
- 原生Ajax
- 基于jQuery的Ajax
- fetch:Ajax升级版,标准化组织制定的一套新规范
- axios:第三方库,比fetch更加强大
Url地址格式: - 传统形式的URL:如果要通过URL传参,以?的形式传递
- Restful形式的URL:如果要通过url传递参数,直接以/的方式在后面拼接参数即可
- Promise能够解决回调地狱的问题
- 回调地狱:异步调用结果如果存在依赖就需要嵌套,也就是在一个异步请求的回调函数中调用另外一个异步请求,这样的多层异步调用方式就称为回调地狱
- Promise:就是处理异步逻辑的一个工具。
- Promise基本用法
- 实例化Promise对象,构造函数中传递函数,该函数中用于处理异步任务
var p=new Promise(function(resolve,reject) {
//成功时调用resolve()
//失败时调用reject()
})
p.then(function(ret) {//从resolve得到结果},
function(ret){//第二个函数是从reject中得到结果})
- then:请求结束之后,不管成功失败都会调用then方法,方法中是成功和失败情况的回调函数。
- 发送多个Ajax侵权并且保证顺序
<body>
<script type="text/javascript">
/*
基于Promise发送Ajax请求
*/
function queryData(url) {
var p = new Promise(function(resolve, reject){
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if(xhr.readyState != 4) return;//请求状态不等于4,说明异常
if(xhr.readyState == 4 && xhr.status == 200) {
// 处理正常的情况
resolve(xhr.responseText);
}else{
// 处理异常情况
reject('服务器错误');
}
};
xhr.open('get', url);//初始化请求
xhr.send(null);//发送请求
});
return p;
}
// queryData('http://localhost:3000/data')
// .then(function(data){
// console.log(data);
// },function(info){
// console.log(info)
// });
// ============================
// 发送多个ajax请求并且保证顺序
queryData('http://localhost:3000/data')
.then(function(data){//data请求结束之后调用
console.log(data)
return queryData('http://localhost:3000/data1');//然后查询data1
})
.then(function(data){//data1请求结束之后调用
console.log(data);
return queryData('http://localhost:3000/data2');//最后查询data2
})
.then(function(data){//data2请求结束之后调用
console.log(data)
});
</script>
</body>
Promise的then方法参数中的函数是有返回值的,返回值有以下两种情况:
- 返回Promise实例对象。就是上述函数中的多次Ajax请求,在第一次请求成功之后返回一个新的Promise实例对象,这个实例对象接着调用接口。
- 返回的是普通值。如果返回的是普通值就直接传递给下一个then,通过then参数中的函数的参数接收该值。
queryData('http://localhost:3000/data').then(function(data) {
return queryData('http://localhost:3000/data1')//这里返回的是一个新的Promise实例对象
}).then(function(data) {
return new Promise(function(resolve, reject){
setTimeout(function(){
resolve(123);//返回成功数据123
},1000)
});
}).then(function(data) {//这里的data就接收上一个then返回的普通值123,如果是默认值,then就会默认添加一个Promise对象,并将值通过resolve返回
return 'hello'
})
- Promise常用的API实例方法
p.then()
:得到异步任务正确的结果p.catch()
:获取异常信息p.finally()
:成功与否都会执行Promise.all()
:并发处理多个异步任务,所有 任务都执行完成才能得到结果,参数是用数组形式Promise.race()
:并发处理多个异步任务,只要有一个任务就能得到结果
标题 5 接口调用-fetch用法
基于Promise实现
调用两个then方法。
- 基本使用
fetch('接口地址').then(data=>{
return data.text()//这里得到的是包含文本结果的Promise对象
}).then(ret=> {//ret作为形参接收的就是上一个then返回的包含文本结果的Promise对象通过resolve处理的数据
//注意这里得到的才是最终的数据
consloe.log(ret)
})
参数分析:
- 参数1:url地址
- fetch方法返回一个包含了响应结果的Promise对象,所以可以调用then方法。响应结果是Response对象,并且传递给了then方法的data参数,Response对象里面有一个方法
text()
可以返回包含了文本结果的Promise对象
- GET和DELETE请求传参
- fetch方法还可以传递第二个参数,配置参数,以对象的形式传递
- 常用的配置选项
method
:HTTP请求方式
body
:HTTP请求参数
headers
:HTTP的请求头,默认为对象形式{}
GET请求方式的参数传递(DELETE请求方式和其类似)
//1.普通方式传参?参数
fetch('/abc?id=123').then(data=>{//?id=123就是传入的参数
return data.text()
}).then(ret=>{console.log(ret)})
//2.Restful通过/参数的形式传参
fetch('/abc/123',{
method:'get'
}).then(data=>{
return data.text()
}).then(ret=>{console.log(ret)})
现在普通方式传参没有Restful方式流行,所以要记住Restful形式的传参是用“/参数”
的形式传递的。
- POST和PUT请求传参(两者相似)
- post传参主要是通过配置参数中的
body
属性传递的,格式主要是查询字符串的形式。并且必须设置配置参数headers:{'Content-Type': 'application/x-www-form-urlencoded'}
- put请求一般用于修改数据,所以需要传递两份数据。修改的id通过URL传递。修改的数据通过body传递
//1.post请求
fetch('/books',{
method:'post',
body:'uname=lishi&pwd=123',
headers:{
'Content-Type': 'application/x-www-form-urlencoded'//浏览器默认的编码格式
}
}).then(...).then(...)
//2.put请求
fetch('/books/123',{//传递参数,修改id是123的
method:'put',
body:JSON.stringify({uname:'lishi',age:12}),//将对象格式的转化为字符串格式的
headers:{'Content-Type':'application/json'}
}).then(...).then(...)
标题 6 接口调用之-axios方式
- axios的特点:
- 支持浏览器和node.js
- 支持promise
- 能拦截请求和响应
- 自动转化JSON数据
- 基本用法
axios.get('/adata').then(ret=>{
console.log(ret.data)//ret是axios封装的一个响应对象,data属性名称是固定的,用于获取后台响应的数据
})
- axios的GET和DELETE传参相似
- GET请求传参,两种方式
通过URL传递;通过params选项传递参数
//通过url传参
axios.get('/adata?id=123')//普通方式
axios.get('.adata/123')//Restful方式传参
//通过params传参
axios.get('adata',{
params:{id:123}
}).then(ret=>{
console.log(ret.data)
})
拿到的ret是一个对象,所有的数据都存在ret的data属性里面
- axios的POST和PUT请求传参相似
- 以对象,
key:value
传参(常用)
axios.post('/adata',{//默认传递的是JSON格式的数据
uname:'tom',
pwd:123
}).then()
-以URLSearchParams传参
var params = new URLSearchParams();
params.append('uname', 'zhangsan');
params.append('pwd', '111');
axios.post('http://localhost:3000/axios', params).then(function(ret){
console.log(ret.data)
})
- axios响应结果和全局配置(ret响应对象里面的属性)
data
:实际响应回来的数据
headers
:响应头信息
status
:响应状态码
statusText
:响应状态信息
全局配置:
- 1.配置公共的请求头:
axios.defaults.baseURL='https://api.example.com'
- 2.配置超时时间:
axios.defaults.timeout=2500
- 3.配置公共的请求头:
axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
- 4.配置公共的post的Content-Type:
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
- axios拦截器
interceptors
- 请求拦截器(在向服务器发起请求之前,做的一些事情)
axios.interceptors.request.use(function(config) {
console.log(config.url)
# 1.1 任何请求都会经过这一步 在发送请求之前做些什么
config.headers.mytoken = 'nihao';
# 1.2 这里一定要return 否则配置不成功
return config;
}, function(err){
#1.3 对请求错误做点什么
console.log(err)
})
- 响应拦截器:在获取数据之前对数据进行一些加工处理
axios.interceptors.response.use(function(res) {
#2.1 在接收响应做些什么
var data = res.data;
return data;//这里返回的数据跟最后请求成功的数据一样
}, function(err){
#2.2 对响应错误做点什么
console.log(err)
})
标题 7 接口调用-async/await用法🍒
- 用法介绍
async
关键字用于函数上,函数的返回值是Promise实例对象
await
关键字只能用于async关键字定义的函数当中,一般在axios请求前面,await可以得到异步的结果
//1.定义一个请求函数
async function queryData(id) {
const ret=await axios.get('/data');
console.log(ret.data)
}
//2.调用函数,直接就可以返回接口调用成功的结果
queryData()
原本axios.get的结果需要then才能拿到,现在使用await就可以拿到结果
- async+await处理多个异步结果
//2. async 函数处理多个异步函数
axios.defaults.baseURL = 'http://localhost:3000';//配置公共请求体
async function queryData() {
//2.1 添加await之后 当前的await 返回结果之后才会执行后面的代码
var info = await axios.get('async1');
//2.2 让异步代码看起来、表现起来更像同步代码
var ret = await axios.get('async2?info=' + info.data);
console.log(ret.data) ;
}
queryData()
总结:async/await让异步的代码看起来,表现的更像同步代码