zoukankan      html  css  js  c++  java
  • Vue

    一. Vue概述

    1. 什么是Vue?

    • Vue是一套用于构建用户界面的渐进式框架
    • vue的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合

    2. Vue:渐进式JavaScript框架

    其中框架指的是提供一些基础性的服务
    指的是以提供API为主
    渐进式: 声明式渲染-> 组件系统->客户端路由->集中式状态管理->项目构建
    官网

    Vue的优点

    • 易用: 熟悉HTML、CSS、JavaScript知识后,可快速上手Vue
    • 灵活:在一个库和一套完整框架之间自如伸缩
    • 高效:20kB运行大小,超快虚拟DOM

    二. Vue的基本使用

    1. 使用Vue将helloworld 渲染到页面上

     <!-- Vue代码运行原理分析:
        概述编译过程的概念(vue语法->原生语法) -->
    
    
        <div id="app">
            <!-- {{}}为插值表达式-->
            <div>{{msg}}</div>
            <div>{{1 + 2}}</div>
            <div>{{msg + '----' + 133}}</div>
    
        </div>
    
        <script src="js/vue.js"></script>
        <script>
            // Vue的基本使用步骤
            // 1. 需要提供标签用于填充数据
            // 2. 引入vue.js库文件
            // 3. 可以使用vue的语法做功能了
            // 4. 把vue提供的数据填充到标签里面
            var num = new Vue({
                el: '#app',
                data: {
                    msg: 'hello Vue'
                }
            })
        </script>
    

    1. 实例参数分析

    • el: 元素的挂载位置(值可以是CSS选择器或者DOM元素)
    • data: 模型数据(值是一个对象)

    2. 插值表达式用法

    • 将数据填充到HTML标签中
    • 插值表达式支持基本的计算操作

    3. Vue代码运行原理分析

    • 概述编译·过程的概念(Vue语法->原生语法)

    三. Vue模板语法

    3.1 模板语法概述

    1. 如何理解前端渲染?

    把数据填充到HTML标签中

    2. 前端渲染方式

    • 原生js拼接字符串
    • 使用前端模板引擎
    • 使用vue特有的模板语法

    3. 原生js凭借字符串

    基本上就是将数据以字符串的方式拼接到HTML标签中。

    缺点:不同开发人员的代码风格差别很大,随着业务的复杂,后期的维护变得逐渐困难起来。

    4. 使用前端模板引擎

    优点:大家都遵循同样的规则写代码,代码可读性明显提高了,方便后期维护。

    缺点:没有专门提供事件机制。

    5. 模板语法概览

    • 差值表达式
    • 指令
    • 事件绑定(即事件的处理)
    • 属性绑定
    • 样式绑定
    • 分支循环结构

    3.2 指令

    1. 什么是指令?

    • 什么是自定义属性
    • 指令的本质就是自定义属性
    • 指令的格式: 以 v-开始 (比如: v-cloak)

    2. v-cloak指令用法

    • 差值表达式存在的问题: “闪动”
    • 如何解决该问题: 使用 v-cloak 指令
    • 解决该问题的原理: 先隐藏,替换好值之后再显示最终的值

    官网

    3. 数据绑定指令

    • v-text 填充纯文本
      ① 相比插值表达式更加简洁
    • v-html 填充HTML片段
      ① 存在安全问题
      ② 本网站内部数据可以使用,来自第三方的数据不可以使用
    • v-pre 填充原始信息
      ① 显示原始信息,跳过编译过程(分析编译过程)

    4. 数据响应式

    • 如何理解响应式
      ① html5的响应式(屏幕尺寸的变化导致样式的变化)
      ② 数据的响应式(数据的变化导致页面内容的变化)
    • 什么式数据绑定
      ① 数据绑定: 将数据填充到标签中
    • v-once 只编译一次
      ① 显示内容之后不再具有响应式功能

    3.3 双向数据绑定指令

    1. 什么是双向数据绑定事件?(① 用户去改页面中插值表达式的值,数据也会跟着改变;② 数据发生变化,插值表达式的值也会发生变化)

    2. 双向数据绑定分析

    • v-mode 指令用法
      <input type='text' v-model='uname'/>

    3. MVVM设计思想

    ① M(model) 即data中的数据
    ② V(view) 即模板 (本质上来说是DOM元素)
    ③ VM(View-Model)实现控制逻辑

    3.4 事件绑定

    1. Vue如何处理事件?

    • v-on指令用法
      <input type="button" v-on:click="num++"/>

    • v-on简写形式
      `<input type="button" @click="num++"/>

    2. 事件函数的调用方式

    • 直接绑定函数名称
      <button v-on:click="say">Hello</button>

    • 调用函数
      <button v-on:click="say()">Say hi</button>

    3.事件函数参数传递

    • 普通参数和事件对象
      <button v-on:click="say('hi',$event)">Say hi</button>

    4. 事件修饰符

    • .stop 阻止冒泡
      <a v-on:click.stop="handle">跳转</a>

    • .prevent 阻止默认行为
      <a v-on:click.prevemt="handle">跳转</a>

    5. 按键修饰符

    • .enter 回车键
      <input v-on:keyup.enter="submit">
    • .esc 退出键
      <input v-on:keyup.delete="handle">

    6. 自定义按键修饰符

    • 全局config.keyCodes对象
      Vue.config.keyCodes.f1=112
      规则:自定义按键修饰符名字是自定义的,但是对应的值必须是按键对应event.keyCode值

    3.5 属性绑定

    1. Vue如何动态处理属性?

    • v-bind指令用法
      <a v-bind:herf='url'>跳转</a>
    • 缩写形式
      `跳转

    2. v-mode的底层实现原理分析

    <input v-bind:value="msg" v-on:input="msg=$event.target.value">

    3.6 样式绑定

    1. class样式处理

    • 对象语法
      <div v-bind:class="{active: isActice}"></div>

    • 数组语法
      <div v-bind:class="{activeClass: errorClass}"></div>

    样式绑定的相关语法细节:
    1) 对象绑定和数组绑定可以结合使用
    2)class绑定的值可以简化操作
    3)默认的class如何处理? 默认的class会被保留

    <body>
        <div id="app">
            <div :class="[activeClass,errorClass, {test: isTest}]">测试样式</div>
            <div :class="arrClasses">测试样式</div>
            <div :class="objClasses">测试样式</div>
            <div class="base" :class="objClasses">测试样式</div>
            <button v-on:click='handle'>切换</button>
        </div>
        <script src="js/vue.js"></script>
        <script>
            // 样式绑定相关语法细节:
            // - 对象那个绑定和数组绑定可以结合使用
            // - class绑定的值可以简化操作
            // - 默认的class如何处理? ,默认的class会被保留
            var vm = new Vue({
                el: '#app',
                data: {
                    activeClass: 'active',
                    errorClass: 'error',
                    isTest: true,
                    arrClasses: ['active', 'error'],
                    objClasses: {
                        active: true,
                        error: true,
    
                    }
                },
                methods: {
                    handle: function() {
                        this.isTest = false;
    
                    }
                }
            });
        </script>
    </body>
    

    2. style样式处理

    • 对象语法
      <div v-bind:style="[color: activerColor, fontSize: fontSize]"></div>

    • 数组语法
      <div v-bind:style="[baseStyles, overridingStyles]"></div>

    3.7 分支循环结构

    1. 分支结构

    • v-if
    • v-else
    • v-else-if
    • v-show
    <body>
        <div id="app">
            <div v-if='score>=90'>优秀</div>
            <div v-else-if='score<90 && score>=80'>良好</div>
            <div v-else-if='score<80 && score >=60'>一般</div>
            <div v-else>较差</div>
            <div v-show='flag'>测试v-show</div>
            <button v-on:click='handle'>点击</button>
        </div>
        <script src="js/vue.js"></script>
        <script>
            // 分支结构 
            // - v-if:控制元素是否渲染到页面 (出现之后用的就比较少了,就用)
            // - v-else
            // - v-else-if
            // - v-show的原理: 控制元素的样式是否显示 display:none/block (平凡的让一个元素显示或隐藏时用)
            var vm = new Vue({
                el: '#app ',
                data: {
                    score: 10,
                    flag: false,
                },
                methods: {
                    handle: function() {
                        this.flag = !this.flag;
                    }
                }
            })
        </script>
    </body>
    

    2. v-if与v-show的区别

    • v-if 控制元素是否渲染到页面 如果平凡的让一个元素显示和隐藏则有v-if
    • v-show 控制元素是否显示(已经渲染到了页面,但有可能没有显示,是隐藏的) 控制样式的变化用v-show

    3. 循环结构

    • v-for遍历数组
      <li v-for='item in list'> {{item}}</li>
      <li v-for='(item,index) in list'>{{item}} +'-----'+{{index}} </li>
    • key的作用:帮助Vue区分不同的元素,从而提高性能
      <li :key='item.id' v-for='(item,index) in list'> {{item}} + '----' + {{index}}</li>
    <body>
        <div id="app">
            <div>水果列表</div>
            <ul>
                <li v-for='item in fruites'>{{item}}</li>
                <li v-for='(item,index) in fruites'>{{item +'----'+index}}</li>
                <li :key='item.id' v-for='(item,index) in myFruites'>
                    <span>{{item.ename}}</span>
                    <span>---------</span>
                    <span>{{item.cname}}</span>
                </li>
    
            </ul>
        </div>
        <script src="js/vue.js"></script>
        <script>
            // 循环结构:
            // - v-for遍历数组
            // - key的作用: 帮助Vue区分不同的元素,从而提高性能 (在遍历的时候必须加上key)
            var vm = new Vue({
                el: '#app',
                data: {
                    fruites: ['apple', 'orange', 'banana'],
                    myFruites: [{
                        id: 1,
                        ename: 'apple',
                        cname: '苹果'
                    }, {
                        id: 2,
                        ename: 'orange',
                        cname: '橘子'
                    }, {
                        id: 3,
                        ename: 'banana',
                        cname: '香蕉'
                    }]
                },
                methods: {
    
                }
            })
        </script>
    </body>
    

    运行结果为:

    4. 循环结构

    • v-for遍历对象
      <div v-for='{value,key, index) in object'></div>

    • v-if和v-for结合使用
      <div v-if='value==12' v-for='(value, key, index) in object'></div>

    <body>
        <div id="app">
            <div v-if='v==18' v-for='(v,k,i) in obj'>{{v +'----'+ k +'----'+ i}}</div>
        </div>
        <script src="js/vue.js"></script>
        <script>
            // 原生js遍历对象
            var obj = {
                uname: 'lisi',
                age: 18,
                sex: 'male'
            }
            for (var key in obj) {
                console.log(key, obj[key]);
            }
            var vm = new Vue({
                el: '#app',
                data: {
                    obj: {
                        uname: 'lisi',
                        age: 18,
                        sex: 'male'
                    }
                },
                methods: {
    
                }
            })
        </script>
    </body>
    

    运行结果:

    四. 基础案例

    五. Vue常用特性

    5.1 常用特性概览

    • 表单操作
    • 自定义指令
    • 计算属性
    • 侦听器
    • 过滤器
    • 生命周期

    5.2 表单操作

    1. 基于Vue的表单操作

    • input 单行文本
    • textarea 多行文本
    • select 下拉对选
    • radio 单选框
    • checkbox 多选框

    2. 表单域修饰符

    • number: 转换为数值
    • trim: 去掉开始和结尾的空格
    • lazy: 将input事件切换为change事件

    <input v-model.number='age' type="number">

    5.3 自定义指令

    1. 为何需要自定义指令?

    内置指令不满足需求

    2. 自定义指令的语法规则(获取元素焦点)

    Vue.directive('focus' {
      inserted: function(el) {
        // 获取元素的焦点
        el.focus();
      }
    })
    

    3. 自定义指令用法

    <input type="text", v-focus>

    4. 带参数的自定义指令(改变元素背景色)

    Vue.directive(‘color', {
      inserted: function(el, binding) {
        el.style.backgroundColor = binding.value.color;
      }
    })
    

    5. 指令用法

    <input type="text" v-color='{color:"orange"}'>

    6. 局部指令

    directives: {
      focus: {
        // 指令的定义
        inserted: function (el) {
          el.focus()
        }
      }
    } 
    

    5.4 计算属性

    1. 何为需要计算属性

    表达式的计算逻辑可能会比较复杂,使用计算属性可以使模板内容更加简洁

    2. 计算属性的用法

    computed: {
      reversedMessage: function () {
        return this.msg.split('').reverse().join('')
      }
    }
    

    3. 计算属性与方法的区别

    • 计算属性是基于它们的依赖进行缓存的
    • 方法不存在缓存
    <body>
        <div id="app">
            <div>{{msg}}</div>
            <div>{{reverseMessage()}}</div>
            <div>{{reverseMessage()}}</div>
            <div>{{reverseString}}</div>
            <div>{{reverseString}}</div>
        </div>
        <script src="js/vue.js"></script>
        <script>
            var vm = new Vue({
                el: '#app',
                data: {
                    msg: 'hello'
                },
                methods: {
                    reverseMessage: function() {
                        console.log('methods');
                        return this.msg.split('').reverse().join('');
                    }
                },
                computed: {
                    reverseString: function() {
                        console.log('computed');
                        return this.msg.split('').reverse().join('');
                    }
                }
            });
        </script>
    </body>
    

    运行结果如下:

    5.5 侦听器

    侦听器的应用场景

    数据变化时执行异步或开销较大的操作

    2. 侦听器的用法

    watch: {
      firstName: function(val){
        // val表示变化之后的值
        this.fullName = val + this.lastName;
      },
      lastName: function(val) {
      this.fullName = this.firstName + val;
      }
    }
    

    5.6 过滤器

    1. 过滤器的作用是什么?

    格式化数据,比如将字符串格式化为首字母大写,佳能日期格式化为指定的格式等

    2. 自定义过滤器

    Vue.filter('过滤器名称', function(value) {
      // 过滤器业务逻辑
    })
    

    3. 过滤器的使用

    <div>{{msg | upper}}</div>
    <div>{{msg | upper  lower}}</div>
    <div v-bind:id='id | formatId'></div>
    

    案例:

    <body>
        <div id="app">
            <input type="text" v-model='msg'>
            <div>{{msg | upper}}</div>
            <div>{{msg | upper | lower}}</div>
            <div :abc='msg | upper'>测试数据</div>
            <div :abc='msg | lower'>测试数据形式</div>
        </div>
        <script src="js/vue.js"></script>
        <script>
            // 过滤器
    
            // 定义过滤器
            Vue.filter('upper', function(val) {
                return val.charAt(0).toUpperCase() + val.slice(1);
            });
            Vue.filter('lower', function(val) {
                return val.charAt(0).toLowerCase() + val.slice(1);
            })
            var vm = new Vue({
                el: '#app',
                data: {
                    msg: ''
                },
    
            })
        </script>
    </body>
    

    运行结果:

    4. 局部过滤器

    filters: {
      capitalize: function() {}
    }
    

    5. 带参数的过滤器

    Vue.filter(‘format’, function(value, arg1){
      // value就是过滤器传递过来的参数
    })
    

    6. 过滤器的使用

    <div>{{date | format(‘yyyy-MM-dd')}}</div>
    日期格式化规则
    y: 年,
    M:年中的月份(1-12),
    d: 月中的天(1-31),
    h: 小时(0-23),
    m: 分(0-59),
    s: 秒(0-59),
    S: 毫秒(0-999),
    q: 季度(1-4)
    案例:日期格式化

    <body>
        <div id="app">
            <div>{{date | format('yyyy-MM-dd')}}</div>
        </div>
        <script src="js/vue.js"></script>
        <script>
            // 过滤器案例: 格式化日期
    
            // Vue.filter('format', function(val, age) {
            //     if (age == 'yyyy-MM-dd') {
            //         var ret = '';
            //         ret += val.getFullYear() + '-' + (val.getMonth() + 1) + '-' + val.getDate();
            //         return ret;
            //     }
            //     return val;
            // })
    
            // 日期格式化规则
            // y: 年,
            // M:年中的月份(1-12),
            // d: 月中的天(1-31),
            // h: 小时(0-23),
            // m: 分(0-59),
            // s: 秒(0-59),
            // S: 毫秒(0-999),
            // q: 季度(1-4)
    
            Vue.filter('format', function(value, arg) {
                function dateFormat(date, format) {
                    if (typeof date === "string") {
                        var mts = date.match(/(/Date((d+))/)/);
                        if (mts && mts.length >= 3) {
                            date = parseInt(mts[2]);
                        }
                    }
                    date = new Date(date);
                    if (!date || date.toUTCString() == "Invalid Date") {
                        return "";
                    }
                    var map = {
                        "M": date.getMonth() + 1, //月份 
                        "d": date.getDate(), //日 
                        "h": date.getHours(), //小时 
                        "m": date.getMinutes(), //分 
                        "s": date.getSeconds(), //秒 
                        "q": Math.floor((date.getMonth() + 3) / 3), //季度 
                        "S": date.getMilliseconds() //毫秒 
                    };
    
                    format = format.replace(/([yMdhmsqS])+/g, function(all, t) {
                        var v = map[t];
                        if (v !== undefined) {
                            if (all.length > 1) {
                                v = '0' + v;
                                v = v.substr(v.length - 2);
                            }
                            return v;
                        } else if (t === 'y') {
                            return (date.getFullYear() + '').substr(4 - all.length);
                        }
                        return all;
                    });
                    return format;
                }
                return dateFormat(value, arg);
            })
    
            var vm = new Vue({
                el: '#app',
                data: {
                    date: new Date()
                }
            })
        </script>
    </body>
    

    6.1 生命周期

    1. 主要阶段

    • 挂载(初始化相关属性)
      ① beforeCreate
      ② created
      ③ beforeMount
      ④ mounted

    • 更新(元素或组件的变化操作)
      ① beforeUpdate
      ② uodated

    • 销毁(销毁相关的属性)
      ① beforeDestroy
      ② destroyed

    2. Vue 实例的产生过程

    ① beforeCreate 在实例初始化之后,数据观测和事件配置之前被调用。
    ② created 在实例创建完成后被立即调用。
    ③ beforeMount 在挂载开始之前被调用。
    ④ mounted el被新创建的vm.$el替换,并挂载到实例上去之后调用该钩子。
    ⑤ beforeUpdate 数据更新时调用,发生在虚拟DOM打补丁之前。
    ⑥ updated 由于数据更改导致的虚拟DOM重新渲染和打补丁,在这之后会调用该钩子。
    ⑦ beforeDestroy 实例销毁之前调用。
    ⑧ destroyed 实例销毁后调用。

    6.2 数组相关API(重点)

    1. 变异方法(修改原有数据)

    Vue 包含一组观察数组的变异方法,所以它们也将会触发视图更新。

    • push()
    • pop()
    • shift()
    • unshift()
    • splice() 实现删除数组中指定的元素
    • sort() 实现排序
    • reverse() 实现数组元素的翻转

    2. 替换数组(生成新的数组)

    • filter()
    • concat()
    • slice()

    3. 修改相应式数据

    • Vue.set(vm.item, indexOfItem, newValue)
    • vm.$set(vm.items, indexOfItem, newValue)
      ① 参数一表示要处理的数组名称
      ② 参数二表示要处理短的数组的索引
      ③ 参数三表示要处理的数组的值

    原始方法:

    <body>
        <div id="app">
            <ul>
                <li v-for='item in list'>{{item}}</li>
            </ul>
        </div>
        <script src="js/vue.js"></script>
        <script>
            // 动态处理响应式数据
            var vm = new Vue({
                el: '#app',
                data: {
                    list: ['apple', 'orange', 'banbana']
                }
            });
            vm.list[1] = 'lemon';
        </script>
    </body>
    

    运行结果:

    7. 组件化开发思想

    7.1 现实中的组件化思想体现

    • 标准
    • 分治
    • 重用
    • 组合

    7.2 编程中的组件化思想体现

    7.3 组件化规范:Web Components

    • 我们希望尽可能多的重用代码
    • 自定义组件的方式不太容易
    • 多次使用组件可能导致冲突

    Web Components 通过创建封装好的功能的定制元素解决上述问题

    官网: https://developer.mozilla.org/zh-CN/docs/Web/Web_Components

    8. 组件注册

    8.1 全局组件注册为语法

    Vue.component(组件名称, {
      data: 组件数据,
      template: 组件模板内容
    })
    
    // 注册一个名为button-counter 的新组件
    Vue.component('button-counter', {
      data: function() {
        return {
          count: 0
        }
      }
    trmplate: '<button v-on:click="count++">点击了{{count}}此</button>'
    })
    

    8.2 组件用法

    <div id="app">
      <button-counter></button-counter>
    </div>
    
    <div id="app">
      <button-counter></button-counter>
      <button-counter></button-counter>
      <button-counter></button-counter>
    </div>
    

    8.3 组件注册注意事项

    1. data必须是一个函数

    • 分析函数与普通对象的对比

    2. 组件模板内容必须是一个根元素

    • 分析演示实际的效果

    3. 组件模板内容可以是模板字符串

    • 模板字符串需要浏览器提供支持(ES6语法)

    4. 组件命名方式

    • 短横线方式
      Vue.component('my-compontent', { /* ... */ })
    • 驼峰方式
      Vue.compontent('MyComponent', { /* ... */ })

    注意事项:
    如果使用驼峰式命名组件,那么在使用组建的时候,只能在字符串中用驼峰的方式使用组件,但是在普通的标签模板中,必须使用短横线的方式使用组件

    8.4 局部组件注册

    var ComponentA = { /* ... */ }
    var ComponentB = { /* ... */ }
    var ComponemtC = { /* ... */ }
    new Vue({
      el: '#app',
      components: {
        'component-a': ComponentA,
        'component-b': ComponentB,
        'componemt-c': ComponentC,
      }
    })
    

    局部组件只能在注册它的组件中才能使用,全局组件可以在所有的组件中使用

    9. Vue 调试工具

    9.1 调试工具安装

    ① 克隆仓库
    ② 安装依赖包
    ③ 构建
    ④ 打开Chrome扩展页面
    ⑤ 选中开发者模式
    ⑥ 加载已解压的扩展,选择shells/chrom

    9.2 调试工具用法

    10. 组件间的数据交互

    10.1 父组件向子组件传值

    1. 组件内部通过props 接收传递过来的值

    Vue.component(‘menu-item', {
      props: ['title'],
      template: '<div>{{ title }}</div>'
    })
    
    

    2. 父组件通过属性将值传递给子组件

    <menu-item title="来自父组件的数据"></menu-item>
    <menu-item :title="title"></menu-item>
    

    3. props属性名规则

    • 在props中使用驼峰形式,模板中需要使用短横线的形式
    • 字符串形式的模板中没有这个限制
    Vue.component(‘menu-item', {
      // 在 JavaScript 中是驼峰式的
      props: [‘menuTitle'],
      template: '<div>{{ menuTitle }}</div>'
    })
    <!– 在html中是短横线方式的 -->
    <menu-item menu-title=“nihao"></menu-item>
    

    4. props属性值类型

    • 字符串String
    • 数值Number
    • 布尔型Boolean
    • 数组Array
    • 对象Object

    10.2 子组件向父组件传值

    1. 子组件通过自定义事件向父组件传递信息

    <button v-on:click='$emit("enlarge-text") '>扩大字体</button>

    2. 父组件监听子组件的事件

    <menu-item v-on:enlarge-text='fontSize += 0.1'></menu-item>

    3. 子组件通过自定义事件向父组件传递信息

    <button v-on:click='$emit("enlarge-text", 0.1) '>扩大字体</button>

    4. 父组件监听子组件的事件

    <menu-item v-on:enlarge-text='fontSize += $event'></menu-item>

    10.3 非父子组件间传值

    1. 单独的事件中心管理组件间的通信

    var eventHub = new Vue()

    2. 监听事件与销毁事件

    eventHub.$on('add-todo', addTodo)
    eventHub.$off('add-todo')
    

    3. 触发事件

    eventHub.$emit(‘add-todo', id)

    例子

    <body>
        <div id="app">
            <div>父组件</div>
            <div>
                <button @click='handle'>销毁事件</button>
            </div>
            <test-tom></test-tom>
            <test-jerry></test-jerry>
        </div>
        <script src="js/vue.js"></script>
        <script>
            // 兄弟组件之间数据传递
    
            // 1. 提供事件中心
            var hub = new Vue();
    
            Vue.component('test-tom', {
                data: function() {
                    return {
                        num: 0
                    }
                },
                template: `
                    <div>
                        <div>TOM:{{num}}</div>
                        <div>
                            <button @click='handle'>点击</button>
                        </div>
                    </div>
                `,
                methods: {
                    handle: function() {
                        // 3. 触发兄弟组件的事件
                        hub.$emit('jerry-event', 2);
                    }
                },
                mounted: function() {
                    // 2. 监听事件
                    hub.$on('tom-event', (val) => {
                        this.num += val;
                    })
                }
            });
            Vue.component('test-jerry', {
                data: function() {
                    return {
                        num: 0
                    }
                },
                template: `
                    <div>
                        <div>JERRY:{{num}}</div>
                        <div>
                            <button @click='handle'>点击</button>
                        </div>
                    </div>
                `,
                methods: {
                    handle: function() {
                        hub.$emit('tom-event', 1);
                    }
                },
                mounted: function() {
                    hub.$on('jerry-event', (val) => {
                        this.num += val;
                    })
                }
            });
            var vm = new Vue({
                el: '#app',
                data: {
    
                },
                methods: {
                    handle: function() {
                        // 4. 销毁事件
                        hub.$off('tom-event');
                        hub.$off('jerry-event')
                    }
                }
            })
        </script>
    </body>
    

    运行结果:

    11. 组件插槽

    11.1 组件插槽的作用

    • 父组件向子组件传递内容(其中内容指的时模板的内容)

    11.2 组件插槽基本用法

    1. 插槽位置

    Vue.component('alert-box', {
      template: `
        <div class="demo-alert-box">
        <strong>Error!</strong>
        <slot></slot>
        </div>
      `
    })
    

    标签为固定不变的

    2. 插槽内容

    <alert-box>Something bad happened.</alert-box>
    

    举例为

    <body>
        <div id="app">
            <alert-box>有bug发生</alert-box>
            <alert-box>有一个警告</alert-box>
            <alert-box></alert-box>
        </div>
        <script src="js/vue.js"></script>
        <script>
            Vue.component('alert-box', {
                template: `
                    <div>
                        <strong>ERROR:</strong>
                        <slot>默认内容</slot>
                    </div>
                `
    
            })
    
            var vm = new Vue({
                el: '#app',
                data: {
    
                }
            });
        </script>
    </body>
    

    运行结果:

    11.3 具名插槽用法

    1. 插槽定义

    <div class="container">
      <header>
        <slot name="header"><slot>
      </header>
      <main>
        <slot></slot>
      <main>
      <footer>
        <slot name="footer"></slot>
      </footer>
    </div>
    

    2. 插槽内容

    <base-layout>
      <h1 slot="header">标题内容</h1>
    
      <p>主要内容1</p>
      <p>主要内容2</p>
    
      <p slot="footer">底部内容</p>
    </base-layout>
    

    案例:

    <body>
        <div id="app">
            <base-layout>
                <h1 slot="header">标题内容</h1>
                <p>主要内容1</p>
                <p>主要内容2</p>
                <p slot="footer">底部内容</p>
            </base-layout>
    
            <base-layout>
                <template slot="header">
                    <h1>标题内容1</h1>
                    <h1>标题内容2</h1>
                </template>
                <p>主要内容1</p>
                <p>主要内容2</p>
                <template slot="footer">
                    <h1>底部内容1</h1>
                    <h1>底部内容2</h1>
                </template>
            </base-layout>
        </div>
        <script src="js/vue.js"></script>
        <script>
            // 具名插槽
    
            Vue.component('base-layout', {
                template: `
                    <div>
                        <header>
                            <slot name="header"></slot>    
                        </header>
                        <main>
                            <slot></slot>
                        </main>
                        <footer>
                            <slot name="footer"></slot>
                        </footer>
                    </div>
                `
            });
            var vm = new Vue({
                el: '#app',
                data: {
    
                }
            })
        </script>
    </body>
    

    运行结果:

    11.4 作用域插槽

    • 应用场景: 父组件对子组件的内容进行加工处理

    1. 插槽定义

    <ul> 
      <li v-for="item in list" v-bind:key="item.id">
        <slot v-bind:item="item">
          {{item.name}}
        </slot>
      </li>
    </ul>
    

    2. 插槽内容

    <fruit-list v-bind:list="list">
      <template slot-scope="slotProps">
        <strong v-if="slotProps.item.current">
          {{slotProps.item.text}}
        </strong>
      </template>
    </fruit-list>
    

    12. 前后端交互模式

    12.1 接口调用方式

    • 原生 ajax
    • 基于jQuery的 ajax (侧重点为DOM操作)
    • fetch (ajax的升级版)
    • axios
      客户端和服务器的通讯模式

    12.2 URL 地址格式

    1. 传统形式的URL

    • 格式: schema://host:port/path?query#fragment

    ① schema:协议。例如http、https、ftp等
    ② host:域名或者IP地址
    ③ port:端口,http默认端口为80,可以省略
    ④ path:路劲,例如/abc/a/b/c (这个路劲是虚拟的,其作用为区分不同的资源)
    ⑤ query:查询参数,例如 uname=lisi$age=12
    ⑥ fragment:锚点(哈希Hash),用于定位页面的某个位置

    2. Restful形式的 URL

    • HTTP请求方式

    ① GET 查询
    ② POST 添加
    ③ PUT 修改
    ④ DELETE 删除

    • 符合规定的URL地址

    http://www.hello.com/books GET
    http://www.hello.com/books POST
    http://www.hello.com/books/123 PUT 修改id=123的这本书的信息
    http://www.hello.com/books/123 DELETE 删除id=123的这本书的信息

    13. Promise用法(es6)

    13.1 异步调用

    • JavaScript的执行环境是单线程
    • 所谓单线程,是指JS 引擎中负责解释和执行JavaScript代码的线程只有一个,也就是一次只能完成一项任务,这个任务执行完之后才能执行下一个,它会阻塞其他任务。这个任务可称为主线程。
    • 异步模式可以一起执行多个任务
    • 异步效果分析
      ① 定时任务
      ② Ajax
      ③ 事件函数
    • 多次异步调用的依赖分析
      ① 多次异步调用的结果顺序不确定
              $.ajax({
                  url: 'http://localhost:3000/data',
                  success: function(data) {
                      console.log(data);
                  },
              });
              $.ajax({
                  url: 'http://localhost:3000/data1',
                  success: function(data) {
                      setTimeout(function() {
                          console.log(data);
                      }, 1000)
                  },
              });
              $.ajax({
                  url: 'http://localhost:3000/data2',
                  success: function(data) {
                      console.log(data);
                  },
              });
    

    ② 异步调用结果如果存在依赖需要嵌套

    // 异步调用结果如果存在依赖需要嵌套
            $.ajax({
                url: 'http://localhost:3000/data',
                success: function(data) {
                    console.log(data);
                    $.ajax({
                        url: 'http://localhost:3000/data1',
                        success: function(data) {
                            console.log(data);
                            $.ajax({
                                url: 'http://localhost:3000/data2',
                                success: function(data) {
                                    console.log(data);
                                },
                            });
                        },
                    });
                },
            });
    

    13.2 Promise 概述

    Promise 是异步编程的一种解决方案,从语法上讲,promise是一个对象,从它可以获取异步操作的消息。

    使用promise主要有一下好处:

    • 可以避免多层异步调用嵌套问题(回调地狱)
    • promise 对象提供了简洁的API,使得控制异步操作更加容易

    Promise官网

    13.3 Promise的基本使用

    • 实例化Promise对象,构造函数中传递函数,该函数中用于处理异步任务。
    • resolvereject两个参数用于处理成功和失败两种情况,并通过p.then获取处理结果
    var p = new Promise(function(resolve, reject) {
      // 成功时调用 resolve()
      // 失败时调用 reject()
    });
    p.then(function(ret) {
      // 从resolve得到正常结果
    },
    function(ret) {
      // 从reject得到错误信息
    });
    

    举例为:

     var p = new Promise(function(resolve, reject) {
                // 这里用于实现异步任务
                setTimeout(function() {
                    var flag = false;
                    if (flag) {
                        // 正常情况
                        resolve('hello');
                    } else {
                        // 异常情况
                        reject('出错了');
                    };
                }, 100);
            });
            p.then(function(data) {
                console.log(data);
            }, function(info) {
                console.log(info);
            })
    

    13.4 基于Promise处理Ajax请求

    1. 处理原生Ajax

    <script>
            // 基于Promise发送Ajax请求
    
            function queryData(url) {
                var p = new Promise(function(resolve, reject) {
                    var xhr = new XMLHttpRequest();
                    xhr.onreadystatechange = function() {
                        if (xhr.readyState != 4) return;
                        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);
                })
        </script>
    

    2. 发送多次ajax请求

              queryData('http://localhost:3000/data')
                .then(function(data) {
                    console.log(data);
                    return queryData('http://localhost:3000/data1')
                })
                .then(function(data) {
                    console.log(data);
                    return queryData('http://localhost:3000/data2')
                })
                .then(function(data) {
                    console.log(data);
                });
    

    13.5 then参数中的函数返回值

    1. 返回Promise 实例对象

    • 返回的该实例对象会调用下一个then
    <body>
        <script>
            // 基于Promise发送Ajax请求
    
            function queryData(url) {
                return new Promise(function(resolve, reject) {
                    var xhr = new XMLHttpRequest();
                    xhr.onreadystatechange = function() {
                        if (xhr.readyState != 4) return;
                        if (xhr.readyState == 4 && xhr.status == 200) {
                            // 处理正常的情况
                            resolve(xhr.responseText);
                        } else {
                            // 处理异常情况
                            reject('服务器错误');
                        };
                    };
                    xhr.open('get', url);
                    xhr.send(null);
                });
            };
            queryData('http://localhost:3000/data')
                .then(function(data) {
                    return queryData('http://localhost:3000/data1');
                })
                .then(function(data) {
                    return new Promise(function(resolve, reject) {
                        setTimeout(function() {
                            resolve(123);
                        }, 1000);
                    });
                })
                .then(function(data) {
                    console.log(data); // 123
                })
        </script>
    </body>
    

    2. 返回普通值

    • 返回的普通值会直接传递给下一个then,通过then参数中函数的参数接收该值。
    <body>
        <script>
            // 基于Promise发送Ajax请求
    
            function queryData(url) {
                return new Promise(function(resolve, reject) {
                    var xhr = new XMLHttpRequest();
                    xhr.onreadystatechange = function() {
                        if (xhr.readyState != 4) return;
                        if (xhr.readyState == 4 && xhr.status == 200) {
                            // 处理正常的情况
                            resolve(xhr.responseText);
                        } else {
                            // 处理异常情况
                            reject('服务器错误');
                        };
                    };
                    xhr.open('get', url);
                    xhr.send(null);
                });
            };
            queryData('http://localhost:3000/data')
                .then(function(data) {
                    return queryData('http://localhost:3000/data1');
                })
                .then(function(data) {
                    return new Promise(function(resolve, reject) {
                        setTimeout(function() {
                            resolve(123);
                        }, 1000);
                    });
                })
                // .then(function(data) {
                //     console.log(data); // 123
                // })
                .then(function(data) {
                    return 'hello'
                })
                .then(function(data) {
                    console.log(data); // hello
                })
        </script>
    </body>
    

    13.6 Promise常用的API

    1. 实例方法

    • p.then()得到异步任务的正确结果
    • p.catch()获取异常信息
    • p.finally() 成功与否都会执行(尚且不是正式标准)
    <body>
        <script>
            // Promise常用API--实例方法
    
            function foo() {
                return new Promise(function(resolve, reject) {
                    setTimeout(function() {
                        // resolve(123);
                        reject('error')
                    }, 100);
                });
            };
            foo()
                // 得到异步任务的正确结果
                .then(function(data) {
                    console.log(data);
                })
                // 获取异步信息
                .catch(function(data) {
                    console.log(data);
                })
                // 成功与否都会执行
                .finally(function() {
                    console.log('finished');
                })
        </script>
    </body>
    

    2. 对象方法

    • Promise.all() 并发处理多个异步任务,所有任务都执行完成才能得到结果
    • Promise.race() 并发处理多个异步任务,只要有一个任务完成就能得到结果
    <body>
        <script>
            // Promise常用API-对象方法
    
            function queryData(url) {
                return new Promise(function(resolve, reject) {
                    var xhr = new XMLHttpRequest();
                    xhr.onreadystatechange = function() {
                        if (xhr.readyState != 4) return;
                        if (xhr.readyState == 4 && xhr.status == 200) {
                            // 处理正常的情况
                            resolve(xhr.responseText);
                        } else {
                            // 处理异常情况
                            reject('服务器错误');
                        };
                    };
                    xhr.open('get', url);
                    xhr.send(null);
                });
            };
            var p1 = queryData('http://localhost:3000/a1');
            var p2 = queryData('http://localhost:3000/a2');
            var p3 = queryData('http://localhost:3000/a3');
            Promise.all([p1, p2, p3]).then(function(result) {
                console.log(result); // 返回三个值  ["Hello TOM", "Hello JERRY", "Hello SPIKE"]
            });
            Promise.race([p1, p2, p3]).then(function(result) {
                console.log(result); // Hello TOM
            });
        </script>
    </body>
    

    14. 接口调用-fetch用法

    14.1 fetch 概述

    1. 基本特性

    • 更加简单的数据获取方式、功能更强大、更灵活、可以看做是xhr的升级版
    • 基于Promise实现

    2. 语法结构

    fetch(url).then(fn2)
              .then(fn3)
              ...
              .catch(fn)
    

    fetch官网

    14.2 fetch 的基本使用

    <body>
        <script>
            // Fetch API基本用法
            fetch('http://localhost:3000/fdata').then(function(data) {
                 // text() 方法属于fetchAPI的一部分,他返回一个Promise实例对象,用于获取后台返回的数据
                return data.text();
            }).then(function(data) {
                // 注意这里得到的才是最终的数据
                console.log(data);
            })
        </script>
    </body>
    

    14.3 fetch请求参数

    1. 常见配置选项

    • method(String): Http请求方式,默认为GET(GET、POST、PUT、DELETE)
    • body(String): HTTP的请求参数
    • headers(Object): HTTP的请求头,默认为{}

    2. GET请求方式的参数传递

    • 传统的URL传递参数
            // 1. 传统的URL传递参数
            fetch('http://localhost:3000/books?id=123', {
                    method: 'get'
                })
                .then(function(data) {
                    // text() 方法属于fetchAPI的一部分,他返回一个Promise实例对象,用于获取后台返回的数据
                    return data.text();
                }).then(function(data) {
                    // 注意这里得到的才是最终的数据
                    console.log(data);
                });
    
    app.get('/books', (req, res) => {
        res.send('传统的URL传递参数!' + req.query.id);
    });
    
    • Restful形式的URL传递参数
            // Restful形式的URL传递参数
            fetch('http://localhost:3000/books/456', {
                    method: 'get'
                })
                .then(function(data) {
                    // text() 方法属于fetchAPI的一部分,他返回一个Promise实例对象,用于获取后台返回的数据
                    return data.text();
                }).then(function(data) {
                    // 注意这里得到的才是最终的数据
                    console.log(data);
                })
    
    app.get('/books/:id', (req, res) => {
        res.send('Restful形式的URL传递参数!' + req.params.id);
    });
    

    运行结果

    3. DELETE请求方式的参数传递

            // 2. DELETE请求方式的参数传递
            fetch('http://localhost:3000/books/789', {
                    method: 'delete'
                })
                .then(function(data) {
                    // text() 方法属于fetchAPI的一部分,他返回一个Promise实例对象,用于获取后台返回的数据
                    return data.text();
                }).then(function(data) {
                    // 注意这里得到的才是最终的数据
                    console.log(data);
                });
    
    app.delete('/books/:id', (req, res) => {
        res.send('DELETE请求方式传递参数!' + req.params.id);
    });
    

    运行结果

    4. POST请求方式的参数传递

    • 传递方式的post传递参数
    fetch('http://localhost:3000/books', {
                    method: 'post',
                    body: 'uname=lisi&pwd=123',
                    headers: {
                        'Content-Type': 'application/x-www-form-urlencoded'
                    }
                })
                .then(function(data) {
                    // text() 方法属于fetchAPI的一部分,他返回一个Promise实例对象,用于获取后台返回的数据
                    return data.text();
                }).then(function(data) {
                    // 注意这里得到的才是最终的数据
                    console.log(data);
                });
    
    • json格式的post传递参数
            // 2> json格式的post传递参数
            fetch('http://localhost:3000/books', {
                    method: 'post',
                    body: JSON.stringify({
                        uname: '张三',
                        pwd: 456
                    }),
                    headers: {
                        'Content-Type': 'application/json'
                    }
                })
                .then(function(data) {
                    // text() 方法属于fetchAPI的一部分,他返回一个Promise实例对象,用于获取后台返回的数据
                    return data.text();
                }).then(function(data) {
                    // 注意这里得到的才是最终的数据
                    console.log(data);
                });
    
    app.post('/books', (req, res) => {
        res.send('POST请求方式传递参数!' + req.body.uname + '---' + req.body.pwd);
    });
    

    传统的post传递参数和json格式的post传递参数格式相同是由于app.use(bodyParser.json())这个中间件

    运行结果

    5. PUT请求方式传递参数

    fetch('http://localhost:3000/books/123', {
                    method: 'put',
                    body: JSON.stringify({
                        uname: '张三',
                        pwd: 789
                    }),
                    headers: {
                        'Content-Type': 'application/json'
                    }
                })
                .then(function(data) {
                    // text() 方法属于fetchAPI的一部分,他返回一个Promise实例对象,用于获取后台返回的数据
                    return data.text();
                }).then(function(data) {
                    // 注意这里得到的才是最终的数据
                    console.log(data);
                });
    
    app.put('/books/:id', (req, res) => {
        res.send('PUT请求方式传递参数!' + req.params.id + '---' + req.body.uname + '---' + req.body.pwd);
    });
    

    运行结果

    14.4 fetch响应结果

    响应数据格式

    • text(): 将返回体处理成字符串类型
    • json(): 返回结果和JSON.parse(responseText)一样
    <body>
        <script>
            // fetch响应结果的数据格式
            fetch('http://localhost:3000/json').then(function(data) {
                // return data.json();
                return data.text();
            }).then(function(data) {
                // console.log(data.uname);
                // console.log(data); // {"uname":"lisi","age":13,"gender":"male"} 类型为字符串
                var obj = JSON.parse(data);
                console.log(obj.uname, obj.age, obj.gender); // lisi 13 male
            })
        </script>
    </body>
    
    app.get('/json', (req, res) => {
        res.json({
            uname: 'lisi',
            age: 13,
            gender: 'male'
        })
    });
    

    15. 接口调用-axios用法

    15.1 axios的基本特征

    axios是一个基于Promise用于浏览器和node.js的HTTP客户端。
    axios官网

    它具有一下特征:

    • 支持浏览器和node.js
    • 支持Promise
    • 能拦截请求和响应
    • 自动转换JSON数据

    15.2 axios的基本用法

    <body>
        <script src="../../js/axios.map" type="text/babel"></script>
        <script src="../../js/axios.js"></script>
        <script>
            axios.get('http://localhost:3000/adata').then(function(ret) {
                // 注意data属性是固定的用法,用于获取后台的实际数据
                // console.log(ret.data);
                console.log(ret);
            })
        </script>
    </body>
    

    运行结果:

    15.3 axios的常用API

    • get: 查询数据
    • post: 添加数据
    • put: 修改数据
    • delete: 删除数据

    15.4 axios的参数传递

    1. GET传递参数

    • 通过URL传递参数
            axios.get('http://localhost:3000/axios?id=123').then(function(ret) {
                console.log(ret.data);
            })
    
    app.get('/axios', (req, res) => {
        res.send('axios get 传递参数' + req.query.id);
    })
    

    运行结果:

    • 通过Restful传递参数

    axios参数传递.html

            // 2> 通过parmas选项传递参数
            axios.get('http://localhost:3000/axios/456').then(function(ret) {
                console.log(ret.data);
            });
    

    index.js(后台接口)

    app.get('/axios/:id', (req, res) => {
        res.send('axios get (Restful) 传递参数' + req.params.id);
    });
    
    • 通过params选项传递参数

    html文件

    axios.get('http://localhost:3000/axios', {
                params: {
                    id: 789
                }
            }).then(function(ret) {
                console.log(ret.data);
            });
    

    后台接口

    app.get('/axios', (req, res) => {
        res.send('axios get 传递参数' + req.query.id);
    });
    

    2. POST传递参数

    • 通过选项传递参数(默认传递的是json格式的数据)
    axios.post('/adata', {
      uname: 'tom',
      pwd: 123
    }).then(ret => {
      console.log(ret.data)
    })
    
    app.post('/axios', (req, res) => {
        res.send('axios post 传递参数' + req.body.uname + '---' + req.body.pwd);
    });
    
    • 通过URLSearchParams传递参数(application/x-www-form-urlencoded)
    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);
            });
    
    app.post('/axios', (req, res) => {
        res.send('axios post 传递参数' + req.body.uname + '---' + req.body.pwd);
    });
    

    3. PUT传递参数

    • 通过选项传递参数(默认传递的是json格式的数据)
    axios.put('http://localhost:3000/axios/123', {
                uname: 'lisi',
                pwd: 123
            }).then(function(ret) {
                console.log(ret.data);
            });
    
    app.put('/axios/:id', (req, res) => {
        res.send('axios put 传递参数' + req.params.id + '---' + req.body.uname + '---' + req.body.pwd);
    });
    
    • 通过URLSearchParams传递参数(application/x-www-form-urlencoded)
    var params = new URLSearchParams();
    params.append('uname', 'zhangsan');
    params.append('pwd', 111);
    axios.put('http://localhost:3000/axios/123', params).then(function(ret) {
     console.log(ret.data);
    });
    
    app.put('/axios', (req, res) => {
        res.send('axios put 传递参数' + req.body.uname + '---' + req.body.pwd);
    });
    

    4. DELETE传递参数

    • 通过URL传递参数
    • 通过Restful传递参数
    • 通过params选项传递参数
                  axios.delete('http://localhost:3000/axios', {
                    params: {
                        id: 111
                    }
                })
                .then(ret => {
                    console.log(ret.data);
                });
    
    app.delete('/axios', (req, res) => {
        res.send('axios delete 传递参数' + req.query.id);
    });
    

    15.5 axios 的响应结果

    响应结果的主要属性

    • data: 实际响应回来的数据
    • headers:响应头信息
    • status:响应状态码
    • statusText:响应状态信息

    15.6 axios 的全局配置

    • axios.defaults.timeout = 3000; //超时时间
    • axios.defaults.baseURL = 'http:localhost:3000/app'; //默认地址
    • axios.defaults.headers['mytoken'] = 'aqwerwqwerqwer2ewrwe23eresf23'; // 设置请求头 值为自定义的
     <script>
            // axios的全局配置
    
            // 配置请求的基准URL地址
            axios.defaults.baseURL = 'http://localhost:3000';
            // 配置请求头信息
            axios.defaults.headers['mytoken'] = 'hello';
            axios.get('axios-json').then(function(ret) {
                console.log(ret.data.uname);
            });
        </script>
    

    15.6 axios拦截器

    1. 请求拦截器

    在请求发出之前设置一些信息

    2. 响应拦截器

    在获取数据之前对数据做一些加工处理

           <script>
            // axios拦截器
    
            // 1. 请求拦截器
    
            // 添加一个请求拦截器
            axios.interceptors.request.use(function(config) {
                console.log(config.url);
                config.headers.mytoken = 'nihao';
                // 在请求发出之前进行一些信息设置
                return config;
            }, function(err) {
                // 处理响应的错误信息
                console.log(err);
            });
    
            // 2. 响应拦截器
    
            // 添加一个响应拦截器
            axios.interceptors.response.use(function(res) {
                // console.log(res);
                var data = res.data;
                // 在这里对返回的数据进行处理
                return data;
            }, function(err) {
                // 处理响应的错误信息
                console.log(err);
            });
    
            axios.get('http://localhost:3000/adata').then(function(data) {
                console.log(data);
            });
        </script>
    

    16. 接口调用-async/await用法

    16.1 async/await的基本用法

    • async/await是ES7引入的新的语法,可以更加方便的进行异步操作
    • async 关键字用于函数上(async函数的返回值是Promise实例对象)
    • await 关键字用于async 函数当中(await可以得到异步的结果)
            // async function queryData() {
            //     var ret = await axios.get('adata');
            //     // console.log(ret.data);
            //     return ret.data
            // };
    
            async function queryData() {
                var ret = await new Promise(function(resolve, reject) {
                        setTimeout(function() {
                            resolve('nihao');
                        })
                    })
                    // console.log(ret.data);
                return ret;
            };
    
            queryData().then(function(data) {
                console.log(data);
            });
    

    16.2 async/await 处理多个异步请求

    多个异步请求的场景

              async function queryData() {
                var ret = await new Promise(function(resolve, reject) {
                        setTimeout(function() {
                            resolve('nihao');
                        })
                    })
                    // console.log(ret.data);
                return ret;
            };
    
            queryData().then(function(data) {
                console.log(data);
            });
    

    17. Vue全家桶-前端路由

  • 相关阅读:
    转载viewstate(一) 太经典的东西 不得不转载保存下来
    Asp.Net中HttpModule的研究(转)
    linux学习笔记(9)
    老手经验谈:Linux驱动程序开发学习步骤(转)
    浅谈C中的malloc和free(1)
    ASP.NET的HttpModule和HttpHandler(转)
    C语言学习笔记(1)
    xcode 4 code sense
    不是bug 是教训
    win7 管理员 开关命令
  • 原文地址:https://www.cnblogs.com/counter/p/14753361.html
Copyright © 2011-2022 走看看