Vue之组件化开发和vue接口调用

标题1 组件注册

  1. 全局组件注册Vue.component
  • 示例代码:
Vue.component('my-cart',{
data:function(){
   return {返回的是组件中使用的数据}
   },
template:`<h1>这是组件的模板结构</h1>`
})
  • 参数分析:
  • data:必须是一个带有return返回值的函数,return返回的是一个对象,对象中是template模板中要使用的数据
  • template模板:使用模板字符串包裹比较好,里面是组件的模板类型
  • 在组件中,除了没有el,其他的参数可以和vue实例对象一样使用
  1. 局部组件注册:components:{'组件名':template}属性和methods同级。
    局部组件一定要在实例上注册,才能在html上使用
var ComponentA={
data:function() {
     return {msg:0}
      },
     template:''
};
components:{
 'component-a':ComponentA
}

注:组件的命名规则,一般以短横线命名,如果使用大驼峰的形式命名的化,可以在template中使用大驼峰,但是在HTML标签中必须使用短横线的形式。因此组件大多都是使用短横线命名的

标题2 组件数据之间的相互传递(父传子、子传父、兄弟)

  1. 父组件和子组件的区分
    在组件中声明的template模板就是子组件,组件标签相对于模板来说就是父组件

  2. 父组件向子组件传递数据

  • 父组件通过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标签(父组件)中必须使用短横线的形式。所以一般情况下,在命名的时候用一个较短的单词即可。

  1. 子组件向父组件传值(通过父组件来触发子组件的事件)
  • 子组件通过自定义事件向父组件传值($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
    }
  }
})
  1. 兄弟组件之间的数据传递(通过事件中心来监听和触发事件)
  • 事件中心实际上是一个空的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标签)

  1. 概念:父组件向子组件传递内容,子组件在template中定义slot插槽标签,用于接收父组件内部传递的内容部分(开始标签和结束标签中间的文本内容)
  • 插槽位置
Vue.component('tab-com',{
template:`
<div class='demo'>
<strong>location:</strong>
<slot></slot>
</div>
`
})
  • 插槽内容
<tab-com>这是填充到子组件插槽的内容</tab-com>
  1. 具名插槽(就是有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>
  1. 作用域插槽(在父组件中修改已经定义好的子组件)
    作用:就是将父组件的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传递参数,直接以/的方式在后面拼接参数即可
  1. Promise能够解决回调地狱的问题
  2. 回调地狱:异步调用结果如果存在依赖就需要嵌套,也就是在一个异步请求的回调函数中调用另外一个异步请求,这样的多层异步调用方式就称为回调地狱
  3. Promise:就是处理异步逻辑的一个工具。
  4. Promise基本用法
  • 实例化Promise对象,构造函数中传递函数,该函数中用于处理异步任务
var p=new Promise(function(resolve,reject) {
//成功时调用resolve()
//失败时调用reject()
})
p.then(function(ret) {//从resolve得到结果},
function(ret){//第二个函数是从reject中得到结果})
  • then:请求结束之后,不管成功失败都会调用then方法,方法中是成功和失败情况的回调函数。
  1. 发送多个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'
})
  1. Promise常用的API实例方法
  • p.then():得到异步任务正确的结果
  • p.catch():获取异常信息
  • p.finally():成功与否都会执行
  • Promise.all():并发处理多个异步任务,所有 任务都执行完成才能得到结果,参数是用数组形式
  • Promise.race():并发处理多个异步任务,只要有一个任务就能得到结果

标题 5 接口调用-fetch用法

基于Promise实现
调用两个then方法。

  1. 基本使用
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对象
  1. 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形式的传参是用“/参数”的形式传递的。

  1. 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方式

  1. axios的特点:
  • 支持浏览器和node.js
  • 支持promise
  • 能拦截请求和响应
  • 自动转化JSON数据
  1. 基本用法
axios.get('/adata').then(ret=>{
console.log(ret.data)//ret是axios封装的一个响应对象,data属性名称是固定的,用于获取后台响应的数据
})
  1. 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属性里面

  1. 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)
    })
  1. 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';
  1. 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用法🍒

  1. 用法介绍
    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就可以拿到结果

  1. 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让异步的代码看起来,表现的更像同步代码

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值