天天看点

Vue新手入门Vue概述

Vue概述

1.指令

v-cloak

防止页面加载时出现闪烁问题

<script type="text/css">
        [v - cloak] { display: none; }
</script>
 <div id="app" v-cloak>
</div>
           

v-text

  • v-text指令用于将数据填充到标签中,作用于插值表达式类似,但是没有闪动问题
  • 如果数据中有HTML标签会将html标签一并输出
  • 注意:此处为单向绑定,数据对象上的值改变,插值会发生变化;但是当插值发生变化并不会影响数据对象的值
<div v-text='msg'></div>
 <div v-text>{{msg}}</div>
           

v-html

  • 用法和v-text 相似 但是他可以将HTML片段填充到标签中
  • 可能有安全问题, 一般只在可信任内容上使用

    v-html

    ,永不用在用户提交的内容上
  • 它与v-text区别在于v-text输出的是纯文本,浏览器不会对其再进行html解析,但v-html会将其当html标签解析后输出。

v-pre

  • 显示原始信息跳过编译过程
  • 跳过这个元素和它的子元素的编译过程。
  • 一些静态的内容不需要编译加这个指令可以加快渲染

v-once

执行一次性的插值【当数据改变时,插值处的内容不会继续更新】

<!-- 即使data里面定义了msg 后期我们修改了 仍然显示的是第一次data里面存储的数据即 Hello Vue.js  -->
     <span v-once>{{ msg}}</span>    
<script>
    new Vue({
        el: '#app',
        data: {
            msg: 'Hello Vue.js'
        }
    });
</script>
           

v-model

双向数据绑定

  • 当数据发生变化的时候,视图也就发生变化
  • 当视图发生变化的时候,数据也会跟着同步变化

v-model是一个指令,限制在

<input>、<select>、<textarea>、components

中使用

<div id="app">
      <div>{{msg}}</div>
      <div>
          当输入框中内容改变的时候,  页面上的msg  会自动更新
        <input type="text" v-model='msg'>
      </div>
  </div>
           

mvvm

  • MVC 是后端的分层开发概念; MVVM是前端视图层的概念,主要关注于 视图层分离,也就是说:MVVM把前端的视图层,分为了 三部分 Model, View , VM ViewModel
  • m model
    • 数据层 Vue 中 数据层 都放在 data 里面
  • v view 视图
    • Vue 中 view 即 我们的HTML页面
  • vm (view-model) 控制器 将数据和视图层建立联系
    • vm 即 Vue 的实例 就是 vm

v-on

  • 用来绑定事件的
  • 形式如:v-on:click 缩写为 @click;
<div>{{num}}</div>
        <button v-on:click='num++'>点击</button>
        <button @click='num++'>点击</button>
<!-- 如果事件直接绑定函数名称,那么默认会传递事件对象作为事件函数的第一个参数 -->
<!-- 2、如果事件绑定函数调用,那么事件对象必须作为最后一个参数显示传递,
      并且事件对象的名称必须是$event -->
        <button @click='handle(123,456,$event)'>点击1</button>
           

事件修饰符

<!-- 阻止单击事件继续传播 -->
<a v-on:click.stop="doThis"></a>

<!-- 提交事件不再重载页面 -->
<form v-on:submit.prevent="onSubmit"></form>

<!-- 修饰符可以串联   即阻止冒泡也阻止默认事件 -->
<a v-on:click.stop.prevent="doThat"></a>

<!-- 只当在 event.target 是当前元素自身时触发处理函数 -->
<!-- 即事件不是从内部元素触发的 -->
<div v-on:click.self="doThat">...</div>
           

按键修饰符

在做项目中有时会用到键盘事件,在监听键盘事件时,我们经常需要检查详细的按键。Vue 允许为

v-on

在监听键盘事件时添加按键修饰符

<!-- 只有在 `keyCode` 是 13 时调用 `vm.submit()` -->
<input v-on:keyup.13="submit">

<!-- -当点击enter 时调用 `vm.submit()` -->
<input v-on:keyup.enter="submit">

<!--当点击enter或者space时  时调用 `vm.alertMe()`   -->
<input type="text" v-on:keyup.enter.space="alertMe" >

常用的按键修饰符
.enter =>    enter键
.tab => tab键
.delete (捕获“删除”和“退格”按键) =>  删除键
.esc => 取消键
.space =>  空格键
.up =>  上
.down =>  下
.left =>  左
.right =>  右

<script>
	var vm = new Vue({
        el:"#app",
        methods: {
              submit:function(){},
              alertMe:function(){},
        }
    })

</script>
           

自定义修饰符别名

在Vue中可以通过

config.keyCodes

自定义按键修饰符别名

<div id="app">
    预先定义了keycode 116(即F5)的别名为f5,因此在文字输入框中按下F5,会触发prompt方法
    <input type="text" v-on:keydown.f5="prompt()">
</div>

<script>
	
    Vue.config.keyCodes.f5 = 116;

    let app = new Vue({
        el: '#app',
        methods: {
            prompt: function() {
                alert('我是 F5!');
            }
        }
    });
</script>
           

v-bind 属性绑定

  • v-bind 指令被用来响应地更新 HTML 属性
  • v-bind:href 可以缩写为 :href;
<!-- 绑定一个属性 -->
<img v-bind:src="imageSrc">

<!-- 缩写 -->
<img :src="imageSrc">
           

分支结构 v-if

<div id="app">
        <div v-if='score>90'>优秀</div>
        <div v-else-if='score>60'>良好</div>
        <div v-else>不及格</div>
        <br>
        <!-- v-show控制显示与隐藏 -->
        <div v-show='false'>v-show测试</div>
    </div>
    <script src="./js/vue.js"></script>
    <script>
        var lk = new Vue({
            //el:元素挂载位置  data:模型数据(值是一个对象)
            el: '#app',
            data: {
                score: 55
            },
            //函数要定义在methods中
            methods: {
                handle: function() {
                    this.url = 'https://cn.vuejs.org/v2/api/#v-on'
                }
            }
        })
    </script>
           

v-show 和 v-if的区别

  • v-show本质就是标签display设置为none,控制隐藏
    • v-show只编译一次,后面其实就是控制css,而v-if不停的销毁和创建,故v-show性能更好一点。
  • v-if是动态的向DOM树内添加或者删除DOM元素
    • v-if切换有一个局部编译/卸载的过程,切换过程中合适地销毁和重建内部的事件监听和子组件

循环结构 v-for

<div id="app">
        <div>水果列表</div>
        <ul>
            <li v-for='item in fruits'>{{item}}</li>
        </ul>

        <ul>
            //:k的作用:帮助Vue区分不同的元素 从而提高性能
            <li :key='index' v-for='(item,index) in fruits'>{{item+'----'+index}}</li>
        </ul>
    </div>
    <script src="./js/vue.js"></script>
    <script>
        var lk = new Vue({
            //el:元素挂载位置  data:模型数据(值是一个对象)
            el: '#app',
            data: {
                fruits: ['apple', 'orange', 'banana']
            },
            //函数要定义在methods中
            methods: {

            }
        })
    </script>
           
  • 不推荐同时使用

    v-if

    v-for

  • v-if

    v-for

    一起使用时,

    v-for

    具有比

    v-if

    更高的优先级。

key 的作用

  • key来给每个节点做一个唯一标识
  • key的作用主要是为了高效的更新虚拟DOM

2.常用特性

表单

v-model

1.单选

<div>
   <span>性别:</span>
    <span>
          <input type="radio" id="male" value="1" v-model='gender'>
          <label for="male">男</label>
          <input type="radio" id="female" value="2" v-model='gender'>
          <label for="female">女</label>
    </span>
 </div>
           

2.多选 – hobby 要定义成数组 否则无法实现多选

<div>
                <span>爱好:</span>
                <input type="checkbox" id="ball" value="1" v-model='hobby'>
                <label for="ball">篮球</label>
                <input type="checkbox" id="sing" value="2" v-model='hobby'>
                <label for="sing">唱歌</label>
                <input type="checkbox" id="code" value="3" v-model='hobby'>
                <label for="code">写代码</label>
            </div>
           

3.下拉框和文本

<div>
                <span>职业:</span>
                <select v-model='occupation' multiple>
          <option value="0">请选择职业...</option>
          <option value="1">教师</option>
          <option value="2">软件工程师</option>
          <option value="3">律师</option>
        </select>
            </div>
            <div>
                <span>个人简介:</span>
                <textarea v-model='desc'></textarea>
            </div>
           

表单修饰符

  • .number 转换为数值
    • 注意点:
    • 当开始输入非数字的字符串时,因为Vue无法将字符串转换成数值
    • 所以属性值将实时更新成相同的字符串。即使后面输入数字,也将被视作字符串。
  • .trim 自动过滤用户输入的首尾空白字符
    • 只能去掉首尾的 不能去除中间的空格
  • .lazy 将input事件切换成change事件
    • .lazy 修饰符延迟了同步更新属性值的时机。即将原本绑定在 input 事件的同步逻辑转变为绑定在 change 事件上, 在失去焦点 或者 按下回车键时才更新
<!-- 自动将用户的输入值转为数值类型 -->
<input v-model.number="age" type="number">

<!--自动过滤用户输入的首尾空白字符   -->
<input v-model.trim="msg">

<!-- 在“change”时而非“input”时更新 -->
<input v-model.lazy="msg" >
           

自定义指令

Vue.directive('focus', {
            inserted: function(el) {
                // el表示指令所绑定的元素
                el.focus();
            }
        });
           

自定义局部指令

//自定义局部指定
            directives: {
                color: {
                    bind: function(el, binding) {
                        el.style.backgroundColor = binding.value.color
                    }
                }
            }
           

计算属性 computed

//计算属性,需要有返回值
            computed: {
                方法名: function() {
                    return 返回值
                }
            }
//使用时直接写方法名 不需要跟括号
           

侦听属性 watch

  • 使用watch来响应数据的变化
  • 一般用于异步或者开销较大的操作
  • watch 中的属性 一定是data 中 已经存在的数据
//侦听
            watch: {
                firstName: function(val) {
                  this.fullName = val + ' ' + this.lastName;
                },
                lastName: function(val) {
                  this.fullName = this.firstName + ' ' + val;
                }
            }
        });
           

过滤器 filter

过滤器三种使用方式

<div>{{msg | upper}}</div>
        <div>{{msg | upper | lower}}</div>
        <div :abc='msg | upper'>测试数据</div>
           

局部过滤器filters

//过滤器
            filters: {
                upper: function(val) {
                    return val.charAt(0).toUpperCase() + val.slice(1);
                }
            }
           

自定义过滤器filter

Vue.filter(‘过滤器名称’,函数)

Vue.filter('upper', function(val) {
          return val.charAt(0).toUpperCase() + val.slice(1);
         });
           
  • Vue.js允许自定义过滤器,可被用于一些常见的文本格式化。
  • 过滤器可以用在两个地方:双花括号插值和v-bind表达式。
  • 过滤器应该被添加在JavaScript表达式的尾部,由“管道”符号指示
  • 支持级联操作
  • 过滤器不改变真正的

    data

    ,而只是改变渲染的结果,并返回过滤后的版本
  • 全局注册时是filter,没有s的。而局部过滤器是filters,是有s的

生命周期

常用的 钩子函数

beforeCreate 在实例初始化之后,数据观测和事件配置之前被调用 此时data 和 methods 以及页面的DOM结构都没有初始化 什么都做不了
created 在实例创建完成后被立即调用此时data 和 methods已经可以使用 但是页面还没有渲染出来
beforeMount 在挂载开始之前被调用 此时页面上还看不到真实数据 只是一个模板页面而已
mounted el被新创建的vm.$el替换,并挂载到实例上去之后调用该钩子。 数据已经真实渲染到页面上 在这个钩子函数里面我们可以使用一些第三方的插件
beforeUpdate 数据更新时调用,发生在虚拟DOM打补丁之前。 页面上数据还是旧的
updated 由于数据更改导致的虚拟DOM重新渲染和打补丁,在这之后会调用该钩子。 页面上数据已经替换成最新的
beforeDestroy 实例销毁之前调用
destroyed 实例销毁后调用

数组变异方法

  • 在 Vue 中,直接修改对象属性的值无法触发响应式。当你直接修改了对象属性的值,你会发现,只有数据改了,但是页面内容并没有改变
  • 变异数组方法即保持数组方法原有功能不变的前提下对其进行功能拓展

push()

往数组最后面添加一个元素,成功返回当前数组的长度

pop()

删除数组的最后一个元素,成功返回删除元素的值

shift()

删除数组的第一个元素,成功返回删除元素的值

unshift()

往数组最前面添加一个元素,成功返回当前数组的长度

splice()

有三个参数,第一个是想要删除的元素的下标(必选),第二个是想要删除的个数(必选),第三个是删除 后想要在原位置替换的值

sort()

sort() 使数组按照字符编码默认从小到大排序,成功返回排序后的数组

reverse()

reverse() 将数组倒序,成功返回倒序后的数组

替换数组

  • 不会改变原始数组,但总是返回一个新数组
filter filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。
concat concat() 方法用于连接两个或多个数组。该方法不会改变现有的数组
slice slice() 方法可从已有的数组中返回选定的元素。该方法并不会修改数组,而是返回一个子数组

动态数组响应式数据

  • Vue.set(a,b,c) 让 触发视图重新更新一遍,数据动态起来
  • a是要更改的数据 、 b是数据的第几项、 c是更改后的数据
// Vue.set(vm.list, 2, 'lemon');
        vm.$set(vm.list, 1, 'lemon');
        // vm.info.gender = 'male';
        vm.$set(vm.info, 'gender', 'female');
           

3.组件

  • 组件 (Component) 是 Vue.js 最强大的功能之一
  • 组件可以扩展 HTML 元素,封装可重用的代

组件注册

1.全局注册

  • Vue.component(‘组件名称’, { }) 第1个参数是标签名称,第2个参数是一个选项对象
  • 全局组件注册后,任何vue实例都可以用
  • 组件参数的data值必须是函数同时这个函数要求返回一个对象
  • 组件模板必须是单个根元素
  • 组件模板的内容可以是模板字符串
//注册组件
//如果使用驼峰式命名组件,那么在使用组件的时候,只能在字符串模板中用驼峰的方式使用组件,但是
//在普通的标签模板中, 必须使用短横线的方式使用组件
        Vue.component('button-counter', {
            //data必须是一个函数
            data() {
                return {
                    count: 0
                }
            },
            //组件模板内容必须是单个跟元素
            template: `
            <button @click='handle'>点击了{{count}}次</button>
            `,
            methods: {
                handle: function() {
                    this.count += 2
                }
            }
        })
           

2.局部注册

var vm = new Vue({
            el: '#app',
            data: {

            },
            //局部组件,局部组件只能在注册他的父组件中使用
            components: {
              'hello-world': {
          		  data: function() {
                  return {
                    msg: 'HelloWorld'
                }
            },
            template: '<div>{{msg}}</div>'
        };
            }
        });
           

组件传值

  • 父组件发送的形式是以属性的形式绑定值到子组件身上。
  • 然后子组件用属性props接收
  • 在props中使用驼峰形式,模板中需要使用短横线的形式字符串形式的模板中没有这个限制
<div id="app">
        <div :style='{fontSize: fontSize + "px"}'>{{pmsg}}</div>
        <!-- 动态绑定父组件传值 -->
        <menu-item :title='dome' content='hellow' @enlarge-text='handle($event)'></menu-item>
    </div>
    <script type="text/javascript" src="js/vue.js"></script>
    <script type="text/javascript">
        Vue.component('menu-item', {
            //props接收传递过来的值
            props: ['title', 'content'],
            data() {
                return {
                    msg: '子组件'
                }
            },
            template: `
            <div>
                <div>{{msg+'----'+title+'----'+content}}</div>
                <button @click='$emit("enlarge-text",5)'>扩大父组件中字体大小					</button>
            </div>
            `
        })
        var vm = new Vue({
            el: '#app',
            data: {
                pmsg: '父组件',
                dome: '父组件传值',
                fontSize: 10
            },
            methods: {
                handle: function(val) {
                    // 扩大字体大小
                    this.fontSize += val;
                }
            }
        });
    </script>
           

数据交互

  • 兄弟之间传递数据需要借助于事件中心,通过事件中心传递数据
    • 提供事件中心 var hub = new Vue()
  • 传递数据方,通过一个事件触发hub.$emit(方法名,传递的数据)
  • 接收数据方,通过mounted(){} 钩子中 触发hub.$on()方法名
  • 销毁事件 通过hub.$off()方法名销毁之后无法进行传递数据
<div id="app">
        <div>父组件</div>
        <div>
            <button @click='handle'>销毁事件</button>
        </div>
        <test-tom></test-tom>
        <test-jerry></test-jerry>
    </div>
    <script type="text/javascript" src="js/vue.js"></script>
    <script type="text/javascript">
        //提供事件中心
        var hub = new Vue()

        Vue.component('test-tom', {
            data() {
                return {
                    num: 0
                }
            },
            template: `
            <div>
                <div>TOM:{{num}}</div>
                <div
                    <button @click='handle'>点击</button>
                </div>
            </div>
            `,
            methods: {
                handle: function() {
                    //触发兄弟组件的事件
                    hub.$emit('jerry-event', 2)
                }
            },
            mounted: function() {
                // 监听事件
                hub.$on('tom-event', (val) => {
                    this.num += val;
                });
            }
        })

        Vue.component('test-jerry', {
            data() {
                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() {
                //监听事件
                hub.$on('jerry-event', (val) => {
                    this.num += val;
                });
            }
        })

        var vm = new Vue({
            el: '#app',
            data: {

            },
            methods: {
                handle: function() {
                    //销毁事件
                    hub.$off('tom-event')
                    hub.$off('jerry-event')
                }
            }
        });
    </script>
           

插槽

<div id="app">
        <div>
            <alert-box>bug</alert-box>
            <alert-box>abc</alert-box>
            <alert-box></alert-box>

            <base-layout>
                <p slot='header'>标题信息</p>
                <!-- 使用template可插入多条 -->
                <template slot='header'>
                    <p>标题信息1</p>
                </template>
                <p>主要内容1</p>
                <template slot='footer'>
        <p>底部信息信息1</p>
      </template>
            </base-layout>
        </div>
    </div>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
        Vue.component('alert-box', {
            //通过slot设置插槽
            template: `
            <div>
            <strong>ERROR:</strong>
                <slot>默认内容</slot>
            </div>
            `
        })

        //具名插槽
        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: {

            },
            methods: {

            }
        });
    </script>
           

作用域插槽

<div id="app">
        <fruit-list :list='list'>
            <!-- slotProps是自定义的名字 -->
            <template slot-scope='slotProps'>
                <strong  v-if='slotProps.info.id==2' class="current">{{slotProps.info.name}}</strong>
                <span  v-else >{{slotProps.info.name}}</span>
            </template>
        </fruit-list>
    </div>
    <script type="text/javascript" src="js/vue.js"></script>
    <script type="text/javascript">
        Vue.component('fruit-list', {
            props: ['list'],
            template: `
            <div>
              <li :key='item.id' v-for='item in list'><slot :info='item'>{{item.name}}</slot></li>
            </div>
            `
        })
        var vm = new Vue({
            el: '#app',
            data: {
                list: [{
                    id: 1,
                    name: 'apple'
                }, {
                    id: 2,
                    name: 'orange'
                }, {
                    id: 3,
                    name: 'banana'
                }]
            },
            methods: {

            }
        });
    </script>
           

4.Promise、fetch、axios、async

Promise

<script type="text/javascript">
    /*
     1. Promise基本使用
           我们使用new来构建一个Promise  Promise的构造函数接收一个参数,是函数,并且传入两个参数:		   resolve,reject, 分别表示异步操作执行成功后的回调函数和异步操作执行失败后的回调函数
    */


    var p = new Promise(function(resolve, reject){
      //2. 这里用于实现异步任务  setTimeout
      setTimeout(function(){
        var flag = false;
        if(flag) {
          //3. 正常情况
          resolve('hello');
        }else{
          //4. 异常情况
          reject('出错了');
        }
      }, 100);
    });
    //  5 Promise实例生成以后,可以用then方法指定resolved状态和reject状态的回调函数 
    //  在then方法中,你也可以直接return数据而不是Promise对象,在后面的then中就可以接收到数据了  
    p.then(function(data){
      console.log(data)
    },function(info){
      console.log(info)
    });
  </script>
           

基于Promise发送Ajax请求

<script type="text/javascript">
    /*
      基于Promise发送Ajax请求
    */
    function queryData(url) {
     #   1.1 创建一个Promise实例
      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) {
            # 1.2 处理正常的情况
            resolve(xhr.responseText);
          }else{
            # 1.3 处理异常情况
            reject('服务器错误');
          }
        };
        xhr.open('get', url);
        xhr.send(null);
      });
      return p;
    }
	# 注意:  这里需要开启一个服务 
    # 在then方法中,你也可以直接return数据而不是Promise对象,在后面的then中就可以接收到数据了
    queryData('http://localhost:3000/data')
      .then(function(data){
        console.log(data)
        #  1.4 想要继续链式编程下去 需要 return  
        return queryData('http://localhost:3000/data1');
      })
      .then(function(data){
        console.log(data);
        return queryData('http://localhost:3000/data2');
      })
      .then(function(data){
        console.log(data)
      });
  </script>
           

Promise 基本AP

.then()

  • 得到异步任务正确的结果

.catch()

  • 获取异常信息

.finally()

  • 成功与否都会执行(不是正式标准)
<script type="text/javascript">
        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')
        //   });

        // --------------------------
        // 两种写法是等效的
        foo()
            .then(function(data) {
                console.log(data)
            }, function(data) {
                console.log(data)
            })
            //.finally()成功与否都会执行(尚且不是正式标准)
            .finally(function() {
                console.log('finished')
            });
    </script>
           

Promise 静态方法

//Promise.all()并发处理多个异步任务,所有任务都执行完成才能得到结果
        Promise.all([p1, p2, p3]).then(function(result) {
               console.log(result)
           })

        //Promise.race()并发处理多个异步任务,只要有一个任务完成就能得到结果
        Promise.race([p1, p2, p3]).then(function(result) {
            console.log(result)
        })
           

fetch

  • Fetch API是新的ajax解决方案 Fetch会返回Promise
  • fetch不是ajax的进一步封装,而是原生js,没有使用XMLHttpRequest对象。
  • fetch(url, options).then()
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);
            })
           

fetchAPI 中 响应格式

  • 用fetch来获取数据,如果响应正常返回,我们首先看到的是一个response对象,其中包括返回的一堆原始字节,这些字节需要在收到后,需要我们通过调用方法将其转换为相应格式的数据,比如

    JSON

    BLOB

    或者

    TEXT

    等等
/*
      Fetch响应结果的数据格式
    */
    fetch('http://localhost:3000/json').then(function(data){
      // return data.json();   //  将获取到的数据使用 json 转换对象
      return data.text(); //  //  将获取到的数据 转换成字符串 
    }).then(function(data){
      // console.log(data.uname)
      // console.log(typeof data)
      var obj = JSON.parse(data);
      console.log(obj.uname,obj.age,obj.gender)
    })
           

axios

  • 基于promise用于浏览器和node.js的http客户端
  • 支持浏览器和node.js
  • 支持promise
  • 能拦截请求和响应
  • 自动转换JSON数据
  • 能转换请求和响应数据
// axios put 请求传参
        axios.put('http://localhost:3000/axios/123', {
            uname: 'lisi',
            pwd: 123
        }).then(function(ret) {
            console.log(ret.data)
        })
           

axios 全局配置

// 配置请求的基准URL地址
        axios.defaults.baseURL = 'http://localhost:3000/';
        // 配置请求头信息
        axios.defaults.headers['mytoken'] = 'hello';

        axios.get('axios-json').then(ret => {
            console.log(ret.data.uname)
        })
           

axios 拦截器

  • 请求拦截器
    • 请求拦截器的作用是在请求发送前进行一些操作
      • 例如在每个请求体里加上token,统一做了处理如果以后要改也非常容易
  • 响应拦截器
    • 响应拦截器的作用是在接收到响应后进行一些操作
      • 例如在服务器返回登录状态失效,需要重新登录的时候,跳转到登录页
//请求拦截器
        axios.interceptors.request.use(function(config) {
                console.log(config.url)
                config.headers.mytoken = 'nihao';
                return config;
            }, function(err) {
                console.log(err)
            })
            //响应拦截器
        axios.interceptors.response.use(function(res) {
            // console.log(res)
            var data = res.data;
            return data;
        }, function(err) {
            console.log(err)
        })
           

async 和 await

  • async作为一个关键字放到函数前面
    • 任何一个

      async

      函数都会隐式返回一个

      promise

  • await

    关键字只能在使用

    async

    定义的函数中使用
    • ​ await后面可以直接跟一个 Promise实例对象
    • ​ await函数不能单独使用
  • async/await 让异步代码看起来、表现起来更像同步代码
# 1.  async 基础用法
    # 1.1 async作为一个关键字放到函数前面
	async function queryData() {
      # 1.2 await关键字只能在使用async定义的函数中使用      await后面可以直接跟一个 Promise实例对象
      var ret = await new Promise(function(resolve, reject){
        setTimeout(function(){
          resolve('nihao')
        },1000);
      })
      // console.log(ret.data)
      return ret;
    }
	# 1.3 任何一个async函数都会隐式返回一个promise   我们可以使用then 进行链式编程
    queryData().then(function(data){
      console.log(data)
    })

	#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);
      return ret.data;
    }

    queryData().then(function(data){
      console.log(data)
    })
           

5.路由、webpack

**v-router ** --包含嵌套路由

1.引入相关的库文件

2.添加路由链接

3.添加路由占位符(填充位)

4.创建路由组件

5.配置路由规则并创建路由实例

6.挂载路由实例对象

<!-- 1.引入相关的库文件 -->
    <script src="./lib/vue_2.5.22.js"></script>
    <script src="./lib/vue-router_3.0.2.js"></script>

 <div id="app">
        <!-- 2.添加路由链接 -->
        <router-link to="/user">User</router-link>
        <router-link to="/register">Register</router-link>

        <!-- 3.添加路由占位符(填充位) -->
        <router-view></router-view>
    </div>
 <script>
        // 4.创建路由组件
        const User = {
                template: '<h1>User 组件</h1>'
            }
            //嵌套路由模板
        const Register = {
            template: `<div>
            <h1>Register 组件</h1>
            <hr/>
            <router-link to="/register/tab1">tab1</router-link>
          <router-link to="/register/tab2">tab2</router-link>
            <router-view />
                </div>
            `
        }
        const Tab1 = {
            template: '<h3>tab1 子组件</h3>'
        }
        const Tab2 = {
            template: '<h3>tab2 子组件</h3>'
        }

        // 5.配置路由规则并创建路由实例
        const router = new VueRouter({
            // routes 是路由规则数组
            routes: [{
                //每个路由规则都是一个配置对象,其中至少包含 path 和 component 两个属性
                path: '/user',
                component: User
            }, {
                path: '/register',
                component: Register,
                //嵌套路由--通过chrldren 属性,为 /register 添加子路由规则
                children: [{
                    path: '/register/tab1',
                    component: Tab1
                }, {
                    path: '/register/tab2',
                    component: Tab2
                }]
            }, {
                //redirect 表示将要被重定向的新地址
                path: '/',
                redirect: '/user'
            }]
        })

        const vm = new new Vue({
            el: '#app',
            data: {},
            // 6.挂载路由实例对象
            // router: router
            router
        })
    </script>
           

动态路由

<router-link to="/user/1">User1</router-link>

const User = {
            props: ['id', 'uname', 'age'], //使用proos接收路由参数
            template: '<div> 用户id为:{{id}}--姓名为:{{uname}}--年龄为:{{age}}</div>'
        }

// 创建路由实例对象
        const router = new VueRouter({
            // 所有的路由规则
            routes: [{
                path: '/',
                redirect: '/user/1'
            }, {
                path: '/user/:id',
                component: User,
                //如果 props 被设置为true, route.params 将会被设置为组件属性
                // props: true
                // props: { uname: 'lisi',age: 20}

                //如果要传递id值  props的值应为函数类型
                props: route => ({
                    uname: 'lisi',
                    age: 20,
                    id: route.params.id
                })
            }]
        })
           

命名路由

在配置路由规则并创建路由实例时,添加 name 属性来进行命名

<!-- 使用命名路由 -->
        <router-link :to="{ name: 'user', params: {id: 3} }">User3</router-link>

// 创建路由实例对象
        const router = new VueRouter({
            // 所有的路由规则
            routes: [{
                // 命名路由
                name: 'user',
                path: '/user/:id',
                component: User,
                props: route => ({
                    uname: 'zs',
                    age: 20,
                    id: route.params.id
                })
            }]
        })
           

编程式导航

//跳转
this.$router.push('/register')
//后退
this.$router.go(-1)
           

webpack

1.基本使用步骤

​ ①新建项目空白目录,并运行

npm init -y

命令,初始化包管理配置文件package.json

​ ②新建 src 源代码目录

​ ③新建 src-> index.html 首页

​ ④初始化首页基本的结构

​ ⑤运行

npminstall jquery -S

命令,安装jQuery

2.在项目中安装和配置webpack

​ ①运行

npminstall webpack webpack-cli -D

命令,安装webpack 相关的包

​ ②在项目根目录中,创建名为webpack.config.js 的 webpack 配置文件

​ ③在 webpack 的配置文件中,初始化如下基本配置:

module.exports = {
	//编译模式
    mode: 'development' //两种模式 development production
}
           

​ ④ 在 package.json 配置文件中的scripts节点下,新增dev脚本如下:

"scripts": {
"dev": "webpack" // script 节点下的脚本,可以通过 npm run 名字 执行
}
           

​ ⑤ 在终端中运行

npm run dev

命令,启动webpack 进行项目打包。

​ 打包的入口文件为 src -> index.js

​ 打包的输出文件为 dist-> main.js

3.配置打包的入口与出口

​ 如果要修改打包的入口与出口,可以在 webpack.config.js 中新增如下配置信息:

const path = require('path')
module.exports = {
   entry: path.join(__dirname, './src/index.js'), //打包入口文件的路径
    output: {
        path: path.join(__dirname, './dist'), // 输出文件的存放路径
        filename: 'bundle.js' // 输出文件的名称
    }
}
           

4.配置 webpack 的自动打包功能

1.运行

npm install webpack-dev-server -D

命令,安装支持项目自动打包的工具

2.修改 package.json -> scripts 中的 dev 命令如下:

"scripts": {
"dev": "webpack-dev-server" // script 节点下的脚本,可以通过 npm run 名字 执行
}
           

3.将 src -> index.html 中, script 脚本的引用路径, 修改为 “/buldle.js”

4.运行

npm run dev

命令, 重新进行打包

5.在浏览器中访问 http://localhost:8080 地址, 查看自动打包效果

注意:

webpack-dev-server会启动一个实时打包的http服务器

webpack-dev-server打包生成的输出文件,默认放到了项目根目录中,而且是虚拟的、看不见的

5.配置 html-webpack-plugin 生成预览页面

1.运行

npm install html-webpack-plugin -D

命令, 安装生成预览页面的插件

2.修改 webpack.config.js 文件头部区域, 添加如下配置信息:

//导入生成预览页面的插件,得到一个构造函数
const HtmlWebpackPlugin = require('html-webpack-plugin')
const htmlPlguin = new HtmlWebpackPlugin({ //创建插件的实例对象
    template: './src/index.html', //指定要用到的模板文件
    filename: 'index.html' //指定生成的文件的名称,该文件存在于内存中,在目录中不显示
})
           

3.修改 webpack.config.js 文件向外暴露的配置对象, 新增如下配置节点:

module.exports = {
    plugins: [htmlPlguin], //plugins数组是 webpack 打包期间会用到的一些插件列表
}
           

6.配置自动打包相关参数

//package.json中的配置
// --open 打包完成后自动打开浏览器
// -- host 配置IP地址
// --port 配置端口
"scripts": {
"dev": "webpack-dev-server --open --host 127.0.0.1 --port 8888" // script 节点下的脚本,可以通过 npm run 名字 执行
}
           

webpack加载器 --通过loader打包非js模块

1.打包处理css文件

1.运行

npm install style-loader css-loader -D

安装处理css文件的loader

2.在 webpack.config.js 的module -> rules 数组中, 添加 loader 规则如下:

module: {
        rules: [
 //test 表示匹配的文件类型, use 表示对应要调用的loader,并且use数组中loader顺序是固定的
            { test: /\.css$/, use: ['style-loader', 'css-loader'}  ]
    }
           

2.打包处理less文件

1.运行

npm install less-loader less -D

2.在 webpack.config.js 的module -> rules 数组中, 添加 loader 规则如下:

module: {
        rules: [
 //test 表示匹配的文件类型, use 表示对应要调用的loader,并且use数组中loader顺序是固定的
     { test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader'] }  ]
    }
           

3.打包处理scss文件

1.运行

npm install sass-loader node-sass -D

2.在 webpack.config.js 的module -> rules 数组中, 添加 loader 规则如下:

module: {
        rules: [
 //test 表示匹配的文件类型, use 表示对应要调用的loader,并且use数组中loader顺序是固定的
    { test: /\.scss$/, use: ['style-loader', 'css-loader', 'sass-loader'] }  ]
    }
           

4.配置postCss自动添加css的兼容前缀

1.运行

npm install postcss-loader autoprefixer -D

2.在项目根目录中创建 postcss 的配置文件, postcss.config.js, 并初始化如下配置:

const autoprefixer = require('autoprefixer')
module.exports = {
    plugins: [autoprefixer] //挂载插件
}
           

3.在 webpack.config.js 的module -> rules 数组中, 修改css的 loader 规则如下:

module: {
        rules: [
 //test 表示匹配的文件类型, use 表示对应要调用的loader,并且use数组中loader顺序是固定的
  { test: /\.css$/, use: ['style-loader', 'css-loader', 'postcss-loader'] }  ]
    }
           

5.打包样式表中的图片和字体文件

1.运行

npm install url-loader file-loader -D

2.在 webpack.config.js 的module -> rules 数组中, 添加 loader 规则如下:

module: {
        rules: [
 //test 表示匹配的文件类型, use 表示对应要调用的loader,并且use数组中loader顺序是固定的
{ test: /\.jpg|png|gif|bmp|ttf|eot|svg|woff|woff2$/, use: 'url-loader?limit=16941' }  ]
    }
           

其中 ? 之后的是 loader的参数项

limit用来指定图片的大小,单位是字节(byte),只有小于 limit大小的图片,才会被转为base64图片

6.打包处理js文件中的高级语法

1.安装babel转换器相关的包:

npm install babel-loader @babel/core @babel/runtime -D

2.安装babel语法插件相关的包:

npm install @babel/preset-env @babel/plugin-transform-runtime @babel/plugin-proposal-class-properties -D

3.在项目根目录中, 创建 babel 配置文件 babel.config.js 并初始化基本配置如下:

module.exports = {
  presets: ['@babel/preset-env'],
  plugins: ['@babel/plugin-transform-runtime', '@babel/plugin-proposal-class-properties']
}

           

4.在 webpack.config.js 的module -> rules 数组中, 添加 loader 规则如下:

module: {
        rules: [
//exclude为排除项,表示 babel-loader 不需要处理的js文件
 { test: /\.js$/, use: 'babel-loader', exclude: /node_modules/ }  ]
    }
           

7.配置vue组件加载器

1.运行

npm install vue-loader vue-template-compiler -D

2.在 webpack.config.js 的module -> rules 数组中, 添加 vue-loader 的配置如下:

const VueLoaderPlugin = require('vue-loader/lib/plugin')
module.exports = {
  //plugins数组是 webpack 打包期间会用到的一些插件列表
    plugins: [htmlPlguin, new VueLoaderPlugin()], 
    module: {
        rules: [
//test 表示匹配的文件类型, use 表示对应要调用的loader,并且use数组中loader顺序是固定的
         { test: /\.vue$/, use: 'vue-loader' }
        ]
    }
}
           

8.在webpack项目中使用vue

1.运行

npm install vue -S

安装vue

2.在 src -> index.js 入口文件中, 通过 import Vue from ‘vue’ 来导入 vue 构造函数

3.创建 vue 的实例对象, 并指定要控制的 el 区域

4.通过 render 函数渲染App 根组件

// 1.导入 Vue 构造函数
import Vue from 'vue'
// 2.导入单App根组件
import App from './components/App.vue'

const vm = new Vue({
// 3.指定 vm 实例要控制的页面区域
    el: '#app',
// 4.通过 render 函数, 把指定的组件渲染到 el 区域中
    render: h => h(App)
})
           

9.webpack 打包发布

上线之前需要通过webpack将应用进行整体打包,可以通过 package.json 文件配置打包命令:

//在package.json文件中配置 webpack 打包命令
 //该命令默认加载项目根目录中的 webpack.config.js 配置文件
"scripts": {
  		  //用于开发调试的命令
        "dev": "webpack-dev-server --open --host 127.0.0.1 --port 8888",
          //用于打包的命令
        "build": "webpack -p"
    }
           

6.脚手架、组件库卡element-ui、项目配置

Vue 脚手架用于快速生成 Vue 项目基础架构,其官网地址为:https://cli.vuejs.org/zh/

安装3.x版本的Vue脚手架:

npm install -g @vue/cli

基于3.x版本的脚手架创建vue项目

//1.基于 交互命令行 的方式,创建新版vue项目
vue create 项目名(自定义)

//2.基于 图形化界面 的方式,创建新版vue项目
vue ui

//3.基于 2.x 的旧模板,创建旧版vue项目
npm install -g @vue/cli-init
vue init webpack my-project
           

Vue脚手架自定义配置

1.在项目的根目录创建文件 vue.config.js

2.在该文件中进行相关配置,从而覆盖默认配置

//vue.config.js
module.exports = {
    devServer: {
        // 自动打开浏览器
        open: true,
      	//配置默认端口号
        port: 8878
    }
}
           

Element-UI

官网为: https://element.eleme.cn/#/zh-CN --桌面端组件库

1.基于命令行方式手动安装

1.安装依赖包

npm install element-ui -S

2.导入 Element-UI 相关资源

//手动配置 element-ui
//导入组件库
import ElementUI from 'element-ui'
//导入组件相关样式
import 'element-ui/lib/theme-chalk/index.css'
//配置 Vue 插件
Vue.use(ElementUI)
           

2.基于图形化界面自动安装

1.运行

vue ui

打开图形化界面

2.通过Vue项目管理器,进入具体的项目配置面板

3.点击 插件 -> 添加插件,进入插件查询面板

4.搜索 vue-cli-plugin-element 并安装

5.配置插件,实现按需导入,从而减少打包后项目的体积

树形表格插件 --vue-table-with-tree-grid

//在main.js中
import TreeTable from 'vue-table-with-tree-grid'
Vue.component('tree-table', TreeTable)
           

富文本编辑器插件 --vue-quill-editor

//在main.js中
//导入富文本编辑器
import VueQuillEditor from 'vue-quill-editor'
//导入富文本编辑器对应的样式
import 'quill/dist/quill.core.css'
import 'quill/dist/quill.snow.css'
import 'quill/dist/quill.bubble.css'
//将富文本编辑器注册为全局可用组件
Vue.use(VueQuillEditor)
           

统计图插件 --echarts

//1.导入 echarts
    import echarts from 'echarts'
 <!-- 2.为ECharts准备一个具备大小(宽高)的Dom -->
 <div id="main" style="width: 700px;height:400px;"></div>
 // 3.基于准备好的dom,初始化echarts实例
     var myChart = echarts.init(document.getElementById('main'));
  // 4.指定图表的配置项和数据
     const result = _.merge(res.data, this.options)
    //5.展示数据
     myChart.setOption(result)
           

深拷贝插件 --lodash

import _ from 'lodash'
 _.merge(res.data, this.options)
           

进度条插件 --nprogerss

//在main.js中
//导入进度条对应的js和css
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
    //在request拦截器中,展示进度条 NProgress.start()
axios.interceptors.request.use(config => {
        NProgress.start()
        config.headers.Authorization = window.sessionStorage.getItem('token')
            // 在最后必须 return config
        return config
    })
    //在response拦截器中,隐藏进度条 NProgress.done()
axios.interceptors.response.use(config => {
    NProgress.done()
    return config
})
           

去除console插件 --balel-plugin-transform-remove-console

//在babel.config.js文件里的中
//这是项目发布阶段需要用到的babel插件
const prodPlugins = []
if (process.NODE_ENV === 'production') {
  prodPlugins.push('transform-remove-console')
}
//"plugins"数组中,插入
...prodPlugins
           

修改webpack的默认配置

默认情况下,vue-cli 3.0生成的项目,隐藏了webpack配置项,如果我们需要配置webpack

需要通过vue.config.js来配置。

在项目根目录中创建vue.config.js文件,

module.exports = {
    chainWebpack:config=>{
        //发布模式
        config.when(process.env.NODE_ENV === 'production',config=>{
            //entry找到默认的打包入口,调用clear则是删除默认的打包入口
            //add添加新的打包入口
            config.entry('app').clear().add('./src/main-prod.js')
        })
        //开发模式
        config.when(process.env.NODE_ENV === 'development',config=>{
            config.entry('app').clear().add('./src/main-dev.js')
        })
    }
}
           

补充:

chainWebpack可以通过链式编程的形式,修改webpack配置

configureWebpack可以通过操作对象的形式,修改webpack配置

通过externals加载外部CND资源

//在vue.config.js文件中,放在chainWebpack开发者模式中
 config.set('externals', {
        vue: 'Vue',
        'vue-router': 'VueRouter',
        axios: 'axios',
        lodash: '_',
        echarts: 'echarts',
        nprogress: 'NProgress',
        'vue-quill-editor': 'VueQuillEditor'
      })
    })
//然后在index.html的头部区域中,通过CDN加载js和css样式
    <% if(htmlWebpackPlugin.options.isProd){ %>
  <!-- nprogress 的样式表文件 -->
  <link rel="stylesheet" href="https://cdn.staticfile.org/nprogress/0.2.0/nprogress.min.css" />
  <!-- 富文本编辑器 的样式表文件 -->
  <link rel="stylesheet" href="https://cdn.staticfile.org/quill/1.3.4/quill.core.min.css" />
  <link rel="stylesheet" href="https://cdn.staticfile.org/quill/1.3.4/quill.snow.min.css" />
  <link rel="stylesheet" href="https://cdn.staticfile.org/quill/1.3.4/quill.bubble.min.css" />
  <script src="https://cdn.staticfile.org/vue/2.5.22/vue.min.js"></script>
  <script src="https://cdn.staticfile.org/vue-router/3.0.1/vue-router.min.js"></script>
  <script src="https://cdn.staticfile.org/axios/0.18.0/axios.min.js"></script>
  <script src="https://cdn.staticfile.org/lodash.js/4.17.11/lodash.min.js"></script>
  <script src="https://cdn.staticfile.org/echarts/4.1.0/echarts.min.js"></script>
  <script src="https://cdn.staticfile.org/nprogress/0.2.0/nprogress.min.js"></script>
  <!-- 富文本编辑器的 js 文件 -->
  <script src="https://cdn.staticfile.org/quill/1.3.4/quill.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue-quill-editor.js"></script>
  <% } %>
           

通过CDN优化ElementUI的打包

1.在main-prod.js中,注释掉element-ui按需加载的代码

2.在index.html的头部区域中,通过CDN加载element-ui的js和css样式

<!-- element-ui 的样式表文件 -->
  <link rel="stylesheet" href="https://cdn.staticfile.org/element-ui/2.8.2/theme-chalk/index.css" />
<!-- element-ui 的 js 文件 -->
  <script src="https://cdn.staticfile.org/element-ui/2.8.2/index.js"></script>
           

路由懒加载

1.安装

@babel/plugin-syntax-dynamic-import

2.在babel.config.js配置文件中声明该插件

//在"plugins"数组中
'@babel/plugin-syntax-dynamic-import'
           

3.将路由改为按需加载的形式

//注:webpackChunkName后面为分组名字,最后面是该组件路径
// import Cate from './components/goods/Cate.vue'
const Cate = () => import(/* webpackChunkName: "Cate_Params" */ './components/goods/Cate.vue')
// import Params from './components/goods/Params.vue'
const Params = () => import(/* webpackChunkName: "Cate_Params" */ './components/goods/Params.vue')

           

项目上线配置

1.创建一个新文件夹 运行

npm init -y

初始化

2.运行

npm install express

3.把build的dist文件夹复制到该文件夹内

4.创建app.js入口文件, 配置如下: 然后用node服务器运行该入口文件

const express = require('express')
const app = express()
app.use(express.static('./dist'))
app.listen(80, () => {
  console.log('server running at http://127.0.0.1');
})
           

5.开启gzip配置运行

npm install compression -D

//在app.js中
//网络传输压缩
const compression = require('compression')
//这行代码一定要写到静态资源托管之前
app.use(compression())
           

6.使用pm2管理应用,安装

npm install pm2 -g

使用pm2启动项目,在终端中输入命令:pm2 start app.js --name 自定义名称

查看项目列表命令:pm2 ls

重启项目:pm2 restart 自定义名称

停止项目:pm2 stop 自定义名称

删除项目:pm2 delete 自定义名称

7.Vuex

Vuex是实现组件全局状态(数据)管理的一种机制,可以方便的实现组件之间的数据共享

使用Vuex管理数据的好处:

A.能够在vuex中集中管理共享的数据,便于开发和后期进行维护

B.能够高效的实现组件之间的数据共享,提高开发效率

C.存储在vuex中的数据是响应式的,当数据发生改变时,页面中的数据也会同步更新

Vuex是实现组件全局状态(数据)管理的一种机制,可以方便的实现组件之间的数据共享

使用Vuex管理数据的好处:

A.能够在vuex中集中管理共享的数据,便于开发和后期进行维护

B.能够高效的实现组件之间的数据共享,提高开发效率

C.存储在vuex中的数据是响应式的,当数据发生改变时,页面中的数据也会同步更新

Vuex基本使用

1.安装

npm install vuex --save

2.导入vuex包

//在store文件夹或者store.js中
import Vuex from 'vuex'
Vue.use(Vuex)
           

3.创建store对象

//在store文件夹或者store.js中
const store = new Vuex.Store({
//state 中存放的就是全局共享的数据
  state: { count:0 }
})
           

4.将store对象挂载到vue实例中

new Vue({
	el:'#app',
  	render:h => h(app),
  	router,
  //将创建的共享数据对象,挂载到Vue实例中
  //所有的组件,就可以直接从store 中获取全局的数据了
  store
})
           

组件访问State数据

State提供唯一的公共数据源,所有共享的数据都要统一放到Store中的State中存储

方法一:

this.$store.state.数据名

--在< template >中可省略 this.

方法二:

<h3>当前最新的count值为:{{count}}</h3>
<script>
  import { mapState } from 'vuex'

  export default {
    computed: {
      ...mapState(['count'])
    }
  }
</script>
           

Mutation

Mutation用于修改变更$store中的数据,并且只能通过mutation变更Store数据,不可以直接操作Store中的数据

使用方法一:

//在store.js
mutations: {
    add(state,step){
      //第一个形参永远都是state也就是$state对象
      //第二个形参是调用add时传递的参数
      state.count+=step;
    }
  }

//在调用的文件中
methods:{
  Add(){
    //使用commit函数调用mutations中的对应函数,
    //第一个参数就是我们要调用的mutations中的函数名
    //第二个参数就是传递给add函数的参数
    this.$store.commit('add',10)
  }
}
           

使用方法二:

<button @click='sub(10)'>-1</button>
<script>
  import { mapState, mapMutations } from 'vuex'

  export default {
    computed: {
      ...mapState(['count'])
    },
    methods: {
      //获得mapMutations映射的sub函数
      ...mapMutations(['sub'])
    }
  }
</script>
           

Action

在mutations中不能编写异步的代码,会导致vue调试器的显示出错。

在vuex中我们可以使用Action来执行异步操作。

方法一:

//在store.js中
 mutations: {
    jia (state) {
      //变更状态
      state.count += 1
    }
  },
  actions: {
    //来执行异步操作,不能直接修改state中的数据
    addAsync (context) {//若传递有参数 (context, nn) 
      setTimeout(() => {
        context.commit('jia')
      }, 1000)
    }
    
//在要使用的文件的methods方法中定义,然后调用dome1函数即可
     dome1() {
        this.$store.dispatch('addAsync')//若传递有参数 ('addAsync',5)
      }
           

方法二:

//在store.js中同上

<button @click='调用的函数名'>-1</button>
//在要使用的文件的methods方法中
import {mapActions} from 'vuex'
methods:{
  ...mapActions(['调用的函数名'])
}
           

Getter

Getter用于对Store中的数据进行加工处理形成新的数据

它只会包装Store中保存的数据,并不会修改Store中保存的数据,当Store中的数据发生变化时,Getter生成的内容也会随之变化

使用方法一:

this.$store.getters.名称

使用方法二:

import { mapGetters } from 'vuex'
computed:{
  ...mapGetters(['调用名称'])
}