vue.js

引入

1、cdn引入

开发环境cdn:

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

生产环境cdn:

<script src="https://cdn.jsdelivr.net/npm/vue"></script>

2、下载与引入

通过官网下载源码,并且通过<script>引入

3、npm安装

vue的MVVM

Vue的原理

  1. 通过建立虚拟dom树document.createDocumentFragment(),方法创建虚拟dom树。

  2. 一旦被监测的数据改变,会通过Object.defineProperty定义的数据拦截,截取到数据的变化。

  3. 截取到的数据变化,从而通过订阅者——发布者模式,触发Watcher(观察者),从而改变虚拟dom的中的具体数据。

  4. 最后,通过更新虚拟dom的元素值,从而改变最后渲染dom树的值,完成双向绑定。

Vue的模式是m-v-vm模式,即(model-view-modelView),通过modelView作为中间层(即vm的实例),进行双向数据的绑定与变化。

而实现这种双向绑定的关键就在于:

Object.defineProperty订阅——发布者模式这两点。

下面我们通过实例来实现Vue的基本双向绑定。

Vue的options选项

el:vue实例管理哪一个DOM

data:组件化中必须传对象

methods:vue实例中的方法

components:组件

computed:计算属性

watch:监视,是一个对象。

键是需要观察的表达式,

值是:

  • 回调函数
  • 方法名
  • 包含选项的对象

created :function(){}

mounted:

Vue的生命周期

生命周期

诞生到消亡的整个过程。

Vue指令

插值指令

v-once 后面没有表达式。让显示的东西不响应式,即后期修改了对象属性值页面上的显示的不同步变化。

v-html 后面写属性名。把属性值以html的形式插入到此标签里面。

v-text 后面写属性名。把属性值以文本的形式插入到此标签里面。标签原有的内容会被覆盖。

v-pre 后面没有表达式。去除{{}}表达式效果,使里面的文本原封不动显示出来。

v-cloak 后面没有表达式。给元素添加一个属性,这个属性可以添加css样式,使其隐藏。vue解析以后就去除这个属性。用于解决界面闪烁。

v-for

循环数据。

<body>
<div id="app">
    <!-- v-for -->
    <ul>
        菜式
        <li v-for="(item,index) in food">{{index+1}}、{{item}}</li>
        <!-- item为属性值,index为索引值,v-for会循环每一个元素并且创建相同的元素节点显示数据 -->
        <li v-for="(value,key,index) in person">{{index+1}},{{key}},{{value}}</li>
        客人
        <!--v-for还可以遍历对象,value为对象属性值,key为对象属性名,index为索引-->
        <li v-for="(item,index) in food" :key="item">{{index+1}}、{{item}}</li>
        <!--可以为对应的元素添加key属性,当我们对数组进行增删改时,可以提高更新虚拟DOM的性能-->
    </ul>
</div>
</body>
<script>
    const app = new Vue({
        el:"#app",
        data:{
            food:["大鸡腿","土豆丝","土豆丝","嫩鲍鱼"],
            person:{
                name:"xiaoming",
                age:19,
                height:178
            }
        },
    })
</script>

以下方法对数组元素进行操作时,dom同步更新。(响应式)

  1. push() 后面添加
  2. pop() 后面删除
  3. shift() 前面删除
  4. unshift() 前面添加
  5. splice() 切割、拼接
  6. sort() 排序
  7. reverse() 倒序

通过索引值修改数组元素不会同步更新到页面 --> arr[0]="aaaaaa";

通过Vue实现的修改数组元素方法实现响应式Vue.set(arr,index,value) -(目标数组,目标索引,要修改的值)。

v-bind

​ 动态绑定属性值。会把标签里面属性值当作一个变量传到vue中,把变量的值返回到标签得属性。

<body>
<div id="app">
    <!-- v-bind -->
    <a v-bind:href="src">v-bind的使用</a>
    <a :href="src">v-bind的简写</a>
    <div :my="src">v-bind可以为任意的属性赋值</div>
    <p class="title" :class="{active:true,line:flag}">
        对象语法:通过对象的键作为类名,值(boolean)作为判断是否采用,值也可以用data里面的属性代替。会拼接原有的class。</p>
    <p :class="arr">数组语法:跟对象语法相似。</p>
    <div :style="style">直接绑定设置style</div>
    <input :value="age">设置计算属性,计算属性设置在computed里,虽然定义是函数,但是是一个属性,使用时不加()。
</div>
</body>
<script>
    const app = new Vue({
        el:"#app",
        data:{
            src:"https://www.baidu.com",
            flag:false,
            arr:["active","line"],
            style:{
                width:"100px",
                height:"100px",
                backgroundColor:"green"
            },
            value:10
        },
        computed:{
            age:function(){
                return this.value + 12;
            }
            /*
            上面的计算属性的真面目
            age:{
                set:function(value){
                    //this.value=value; 实际上我们会让set空着,只是用get。
                },
                get:function(value){
                    return this.value + 12;
                }
            }
             */
        }
    })
</script>

computed和methods

也可以把计算属性直接定义在methods里面,但是为什么要使用computed呢?

因为在methods里的function,每一次使用都会执行。

但是多次调用computed里的计算属性时,他只执行了一次后形成了缓存,如果value值不发生变化,后续都使用这个缓存。性能比methods好。

v-on

事件监听,当用户触发事件时执行特定的方法。

</body>
<div id="app">
    <button v-on:click="fn1()">v-on的使用</button>
    <button @click="fn2(2)">v-on可以简写为@click,函数体还可以传递参数</button>
    <button @click="fn3(name)">以对象属性作为参数</button>
    <button @click="fn4($event)">获取事件对象用$event</button>
    <div @click="Div()">
        <p @click.stop="Button()">使用.stop修饰符取消事件冒泡</p>
    </div>
<form action="test.html">
    <input type="text" @keyup.enter="keyUp()">当用户使用键盘事件且点击Enter时触发事件<br/>
    <input type="submit" value="提交" @click.prevent="mySubmit()">使用.prevent修饰符阻止默认事件
</form>
    <button @click.once="Once()">用户第一次点击时触发</button>
</div>
</body>
<script>
    const app = new Vue({
        el:"#app",
        data:{
            name:"shabi"
        },
        methods:{
            fn1(){console.log(1);},
            fn2(a){console.log(a)},
            fn3(name){console.log(name);},
            fn4(e){console.log(e);},
            Div(){console.log("div")},
            Button(){console.log("button")},
            mySubmit(){console.log("submit")},
            keyUp(){console.log("key up!")},
            Once(){console.log(1)}
        }
    })
</script>

.prevent 阻止默认行为,相当于原生preventDefault

.stop 阻止冒泡传播,相当于stopPropergation

.once 当前函数指回执行一次

.self 只有点击元素本身才会触发这个函数

.capture 在捕获阶段执行,相当于ele.addEventListener('click',fn,==false==)

.passive 先执行默认,后执行此函数

v-if , v-else-if , v-else

条件判断,使元素进行显示或者不显示。

<body>
<div id="app">
    <div v-if="flag">
        <h4>if的值或条件判断结果为true时显示</h4>
    </div>
    <div v-else>当v-if不显示时显示</div>
    ----------------------------------
    <div v-if="score>=90">优秀</div>
    <div v-else-if="score>=80">良好</div>
    <div v-else-if="score>=60">及格</div>
    <div v-else>不及格</div>
</div>
</body>
<script>
    const app = new Vue({
        el:"#app",
        data:{
            flag:true,
            score:85
        },
    })
</script>

v-show

语法与v-if一样。

但是不显示时,v-if的元素不存在于document上,v-show元素存在只是display=none。

v-if是对dom进行增加和删除,v-show是对dom进行display=block/none;

v-model

Vue的核心特性之一是双向绑定,vue的响应式原理是实现了数据->视图,接下来我们要学习 视图->数据的原理。

v-model是一个指令,限制在<input>、<select>、<textarea>、components中使用。

<body>
<div id="app">
    <form action="#">
        <input type="text" v-model="name">v-model的使用,在表单元素上添加v-model,他的值为data里面的变量。</br>
        <h4>{{name}}</h4>输入框文字变化,name的值动态变化,即双向绑定。</br>
        <input type="text" :value="name" @input="name = $event.target.value">双向绑定原理</br>

        v-model的单选框radio使用:
        男<input type="radio" value="男" name="sex" v-model="sex">
        女<input type="radio" value="女" name="sex" v-model="sex"><br>

        v-model的多选框checkbox使用:
        苹果 <input type="checkbox" value="苹果" name="fruit" v-model="fruit">
        香蕉 <input type="checkbox" value="香蕉" name="fruit" v-model="fruit">
        西瓜 <input type="checkbox" value="西瓜" name="fruit" v-model="fruit">
        (使用数组接收)<br>

        v-model的下拉框select的使用:
        <select v-model="sport">
            <option value="唱">唱</option>
            <option value="跳">跳</option>
            <option value="rap">rap</option>
            <option value="篮球">篮球</option>
        </select>
    </form>
</div>
</body>
<script>
    const app = new Vue({
        el:"#app",
        data:{
            name:"小明",
            sex:'',
            fruit:[],
            sport:'rap'
        },
    })
</script>

v-model值绑定:使用单选,多选,下拉框的时候,不用再html上写死,可以把可选项写到data数组里面,再用v-for写入到html中,是页面更加灵活。

.lazy(取代 input 监听 change 事件),使得输入框失去焦点时数据才更新。

.number(输入字符串转为有效的数字),输入框的内容都当作字符串处理,这个可以让他转换为数字类型。

.trim(输入首尾空格过滤),过滤内容两边的空格。

Vue组件化

组件化是vue.js中的重要思想

  • 它提供一种抽象,让我们可以开发出一个个独立使用的小组件来构造我们的应用。
  • 任何的应用都会被抽象成一棵组件树。

注册组件基本步骤

  • 创建组件构造器
  • 注册组件
  • 使用组件
<body>
<div id="app">
    <my-cpn></my-cpn><!--3、组件的使用-->
</div>
</body>
<script>
    // 1、创建组件构造器对象
    const cpnC = Vue.extend({
        template:
    `<div>
        <h1>标题</h1>
        <p>内容1</p>
        <p>内容2</p>
    </div>`
    })
    // 2、注册组件
    Vue.component('my-cpn',cpnC);//参数为标签名,组件构造器
</script>

全局组件和局部组件

全局组件

意味着可以在多个Vue实例中使用。上面那种方式就是全局组件的创建方式,把创建和注册的步骤写在实例的外面。

局部组件

在特定的Vue实例中使用。第二步注册的是否在要使用的Vue实例的Components里面注册局部组件。

const app = new Vue({
    el:"#app",
    data:{},
    components:{
        // 2、注册局部组件  标签名:构造器对象
        cpn:cpnC
    }
})

父组件和子组件

Vue实例也可以看作是最大的父组件,叫做root component,其他的组件都属于他的子组件。

必须在Vue实例中注册了才可以在HTML中使用。

组件注册语法糖

// 省去Vue.extend创建组件对象,注册组件时直接创建对象。
Vue.component('my-cpn',{
    template:
        `<div>
            <h1>标题</h1> 
            <p>内容1</p>
            <p>内容2</p>
        </div>`
});
//使用<my-cpn></my-cpn>
//如果是局部组件就在component里面写:
components:{
    Cpn:{
        template:
        `<div>
            <h1>标题</h1>
            <p>内容</p>
         </div>`
    }
}

组件模板抽离

使用script标签

把模板写到script标签里面,type="text/x-template",通过id获取。

<script type="text/x-template" id="cpn"></script>

使用template标签

把模板写到template标签里面,通过id获取。

<template id="cpn"></template>

组件的数据存放

组件内部不能直接访问Vue实例里面的data,而在注册组件时,可以有自己的data、methods等。这个data不是一个对象类型而是一个函数,并且需要return一个对象,这个对象才是组件真正能访问的数据。

<template id="cpn">
    <div>模板
        <h2>{{title}}</h2>
        <p>{{content}}</p>
    </div>
</template>

<script>
    Vue.component("cpn",{
        template: '#cpn',
        data(){
            //这是组件访问数据的地方。
            return{
                title:"这是一个标题",
                content:"这是一段文字"
            }
        }
    })
</script>

为什么组件的data是一个函数?

因为函数返回的时一个对象,每个组件访问data时都会返回唯一的一个对象,当组件需要对数据进行操作的时候,指挥操作自己的对象数据,而不会影响到其他组件的数据。如果data时一个对象,那么每次操作数据时其他组件也会同步变化。

父子组件之间的通信

子组件不能直接访问父组件的数据,所以需要父组件与子组件之间进行通信。

  • props 父-->子
  • $emit 子-->父
父传子 props

props可以是数组、对象、字符串、Boolean、Function等...

// props:["film"],可以写成数组形式  
props:{//也可以写成对象
    film:{
        type:Array,//类型
        required:true,//是否必须传值
        default:'当没有传值时默认的值',
        default(){
            //也可以写成函数形式
            return 0;
        }
    }
}

1、父组件定义一个属性info,应用子组件的标签双向绑定或普通绑定自定义属性:myinfo="info";

2、子组件的option写一个props,里面有一个属性叫myinfo的空对象用于接收数据

3、在子组件模板使用myinfo

props属性校验

在子组件中进行,即使验证失败会有错误提示,但是组件会正常渲染。

props: {
    data: {
        type: String,//type的类型是任意类型
        default: "defalutData",
                     //如果type类型是Array或Object,dafalut必须是一个函数,他的返回值为默认值
        require: true//声明这个参数是否必须传入
    }
}
子传父 $emit

$emit用于触发当前实例上的事件,附加参数都会传给监听器回调。

使用:

原理:

1、子组件定义属性categories,并且在组件某个地方触发发送函数btnClick

2、btnClick通过this.$emit('my-event',this.categories)把自定义事件发送个事件池。

3、父组件在事件池中取出@my-event="myfn(a)"自定义事件和方法

4、myfn(a)通过接收的参数a获取到emit过来的参数。

on:监听当前实例上的自定义事件。事件可以由 vm.emit 触发。回调函数会接收所有传入事件触发函数的额外参数。

this.$on('my-event',(value)={
    console.log(value);
})

监听自定义事件my-event,每当触发此事件后都会触发$on。

父子组件的访问方式

父组件访问子组件children/refs

$children

methods:{
    btnClick(){
        console.log(this.$children.name);
        //this.$children保存组件的某些信息,可通过这个来访问组件的属性
    }
}

可以在mounted或者函数里面打印this.$children,是一个数组,包含了所有组件的信息。

通常来说我们不使用children,因为children是一个数组,里面存了全部组件对象,而且不是响应式的。当我们添加了组件时,数组下标就发生了变化,此时以前指定的组件就变了。

$refs

更好的方法

<div id="app">
    <tag ref="one"></tag>
    <tag ref="two"></tag>
    <!--在子组件上添加ref属性-->
    <tag></tag>
    <button @click="btnClick">btn</button>
</div>
<script>
    //父组件的方法可以直接获取到refs对象,包含了有ref属性的所有组件
    methods:{
        btnClick(){
            this.$refs.one.showMessage();
            this.$refs.two.showMessage();
            //通过设置的ref精准获取到特定的组件
        }
    }
</script>

子组件标签上设置ref属性,触发事件就可以打印refs,通过refs.name就可以找到对应的组件

子组件访问父组件$parent

$parent指代组件的上一层组件,不建议使用。

因为组件是可以复用的,当复用的情况不一样是会造成$parent指代不明。

<template id="temp">
    <div>
        <p>子组件</p>
        <button @click="btnClick">btn</button>
        <!--在组件内部监听事件-->
    </div>
</template>
<script>
    components:{
        tag:{
            template:"#temp",
                methods:{
                    btnClick(){
                        console.log(this.$parent.info)
                        //触发事件时直接访问$parent,即直接访问上一层的组件。
                        console.log(this.$root)
                       //触发事件时访问$root,即直接访问Vue实例。
                    }
                }
        }
    }
</script>

组件信息通讯EventBus

EventBus--事件总线--完全的发布订阅模式。

原理:无论是父子组件还是兄弟组件或者不相关的组件,只要保证每个组件都可以获取到这个==事件池==即可。

Slot插槽

组件的插槽让组件具有更强的扩展性,让使用者决定组件内部的展示。

基本使用<slot>

插槽定义在子组件,父组件使用子组件<son></son>时,在中间使用标签就会代替掉子组件的插槽。中间不使用插槽则使用子组件的默认标签。

具名插槽的使用

<div id="app">
    <tag>
        <span slot="title">这是标题</span><!--通过slot名找到指定的spot-->
        <p slot="content">这是内容</p><!--通过spot名找到指定的spot-->
    </tag>
</div>

<template id="temp">
    <div>
        <slot name="title"></slot>
        <p>子组件</p>
        <slot name="content"></slot>
    </div>
</template>

子组件定义插槽时给插槽加name,父组件使用插槽时给标签加上slot=name就会用上指定的插槽。

编译作用域

<div id="app">
    <tag v-show="show"></tag><!--这个show使用的是Vue实例的show-->
</div>

<template id="temp">
    <div>
        <p v-show="show">子组件</p><!--这个show使用的是组件里面的show-->
    </div>
</template>

父组件模板的所有东西都会在父级作用域内编译;子组件模板的所有东西都会在子级作用域内编译。父子组件之间不能直接访问。

作用域插槽

当我们需要对组件进行数据自定义显示的时候,可用到作用域插槽进行自定义。

父组件替换插槽标签,但是内容由子组件来提供。

<div id="app">
    <tag></tag><!--普通显示-->
    <tag>
        <template slot-scope="slot"><!--利用template标签的slot-scope属性获取子组件的作用域为slot-->
        <span>{{slot.data.join(" - ")}}</span><!--slot.data即为子组件的data-->
    </template>
    </tag>
</div>

<template id="temp">
    <div>
        <slot :data="language"><!--自定义一个属性并且存需要的数据,以便于使用的时候获取-->
            <ul>
                <li v-for="i in language">{{i}}</li>
            </ul>
        </slot>
    </div>
</template>

在子组件的插槽使用双向绑定一个自定义属性data="language"

父组件使用时,要在外面包一层template标签,使用slot-scope="slot"属性。

slot就代表着子组件的作用域。

作用域插槽不能使用具名插槽??

ES6-Modules

模块化的两个核心

导出和导入。

export

注意要使用import和export的script标签要加上type="module"

export let name="Hello";//导出一个变量

let width = 100;
let height =120;
export {
  width,height
}
//以对象形式导出一组变量

const Student = {
  name:"xiaoming",
  height:168,
  weight:90
}

export {Student}//导出一个对象
export {Student as stu}//还可以给对象起别名

export function run(){
  console.log("Run run run....");
}
//导出一个函数

export default function(){
  console.log(123)
}
//默认导出,不需要给名字,让接收者命名。且仅允许存在一个默认导出。

import

import {name,Student,run} from './export.js';
/*导入变量。函数,对象等(可一次导多个),都要用大括号把名字包裹住,名字要对应上传过来的变量名。*/

import fun from './export.js';
/*如果是default就不需要大括号,这里的名字可随便取。*/

import * as obj from './export.js';
/*把全部导出的东西存到obj对象里面。*/

webpack

何为webpack

从本质上来讲,webpack是一个js应用静态模块打包工具。

webpack安装

webpack依赖于node环境,node有各种各样的依赖包,为了可以管理大量的依赖包,会一起安装上npm管理工具,类似于Maven。(node packages manager)

下··

webpack起步

webpack配置

Vue CLI

CLI:command-Line Interface,翻译为命令行界面,俗称脚手架。

Vue CLI是一个官方发布的vue.js项目脚手架。

vue-cli可以快速创建Vue开发环境以及对应的webpack配置。

Vue CLI使用前提:node.js

cli2创建方式:

vue init webpack projectname

运行环境runtime-compiler和runtime-only

cli3创建方式:

vue create projectname 
//命令行进行配置,选择router和vuex,不用手动配置
vue ui //或者通过图形界面进行配置,狭隘后还要手动引入包和配置信息,烦

Vue-Router

认识路由

vue-router基本使用

路由的初始化

(项目生成时已经完成)

使用路由

1、创建路由组件

2、导入组件,配置路由映射

3、在Vue实例中挂载创建的路由实例

用代码代替router-link

结果:

一些细节
{
  routes: [
    {
/*用于初始化时进入的路径,这里第一次进入时默认进入\home*/
      path:'',
      redirect:'/home'
    }],
  mode:"history", /*改为history模式,去除哈希值‘#’*/
  linkActiveClass:'active' /*处于活跃状态下的class*/
}

<router-link>的其他属性:

router-link默认渲染成a标签,使用tag="button"可以渲染成button。

让router-link使用replaceState模式(不可返回),使用replace属性。

标签活动时(被点击等等)会自动生成两个class,其中一个是router-link-active,可通过这个class给标签设置样式,如果觉得此class过长可以为此改名。active-class="active"

动态路由的使用

路由的懒加载

一个项目最后被打包的时候最终是放在一个js文件中,全部页面都放在一个js必然会很大,但我门第一次请求这个页面时可能需要花费一定的时间,甚至用户界面还会出现短暂的空白。如要避免这种情况,使用懒加载把:不同的路由对应的组件分割成不同的代码块,然后当路由被将访问时才加载对应组件,这样就更加高效了。

<img src="C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20200729095516035.png" alt="image-20200729095516035" style="zoom:67%;" />

使用懒加载:当用户使用组件时再import。

vue-router嵌套路由

实现路由嵌套有两个步骤:

1、创建对应子组件,并在路由映射中配置对应的子路由。路径不需要加 /

2、组件内部使用router-view标签

vue-router参数传递

当进行路由跳转时,通常需要传递参数,传递参数有两种方式:

$route.params.value

传递一个参数时使用params

配置路由格式(动态):/router/:id

传递方式:在path后面跟上对应的值

传递后形成路径:/router/123/router/asd

$route.query.value

传递大量参数时使用query

配置路由格式:/router,普通配置

传递方式:双向绑定路由to,绑定的值是个对象,包含url属性和query属性,query包含需要传递的参数。

传递后形成路径:/router?id=123/router?name=asd

通过$route.query.value获取传过来的属性

用button实现query传参
<button @click="toProfile">档案</button>
<script>
toProfile(){
  this.$router.push(//使用query时push传递一个对象
    {
      path:'/profile',
      query:{       //query是一个对象
        name:"Goku",
        height:180,
        age:18
      }
  })
}
</script>

1、父组件主页面设置事件

2、事件函数使用this.$route.push({}),对象有url和query属性,query里面即为传递过去的参数。

3、子组件中的computed中使用this.$route.query.value获取到值

4、页面上使用计算属性显示值

route 和router

this.$router 是个路由导航对象,用它可以方便的使用JS代码实现编程式路由导航,如页面前进、后退、跳转等。

this.$route 是路由参数对象,路由中的所有参数, params、query 都属于它。

this.$router 用来发送。

this.$route用于接收信息。

vue-router导航守卫

1、全局导航钩子

分为前置守卫(beforeEach)+ 后置钩子(afterEach)

beforeEach:在在路由跳转前触发,参数包括to,from,next(参数会单独介绍)三个,这个钩子作用主要是用于登录验证,也就是路由还没跳转提前告知,以免跳转了再通知就为时已晚。

router.beforeEach((to,from,next)=>{
  document.title = to.matched[0].name;
  next();
})

afterEach和beforeEach相反,他是在路由跳转完成后触发,参数包括to,from没有了next。

单独路由独享钩子
组件内的钩子

keep-alive

?????????

默认情况下,一旦显示了另一个组件,上一个被覆盖的组件就会被销毁,下次再显示时再创建组件。使用keep-alive标签后组件不会频繁地被创建和销毁。

属性:

exclude + name1,name2... 把此组件排除在外,它们会被创建和消除。

include + name1,name2... 包括这些组件,他们不会被创建和消除。

Vuex

Vuex简单介绍

Vuex是一个专为Vue.js应用开发的状态管理模式,Vuex是一个状态管理工具。

它采用集中式储存管理应用的所有组件的状态,并以相应规则保证状态可预测的方式发生变化。简单来说就是把多个组件共享的数据储存在一个对象里面,然后把这个对象放在Vue实例中让其他组件可以共同使用。Vuex还实现了响应式,多个组件间公用一个状态。

什么时候需要共享一个状态?

  • 用户登录状态,用户名称,头像等
  • 商品的收藏
  • 购物车的商品

单页面状态管理

state改变引起actions改变,用户事件(在view上)可以引起状态改变。

多页面状态管理

使用VueX

vuex-devtools 和 mutations

vuex-devtools时一个浏览器插件,方便调试vue程序。

mutations是vuex中作为修改状态的东西,下面会详细介绍。

Vuex的核心概念

state

用于存放状态信息。

单一状态树:也叫单一数据源。即只用一个state。

Vuex可实现响应式数据,但是要遵循一些条件:

  1. 提前在store中初始化所需的数据
  2. 给state对象添加新属性是使用以下方式
    • Vue.set(obj,"proper","value")
    • 用新对象给旧对象赋值

任何页面都可以使用$store访问store里面的属性。

getters

相当于计算属性 ,当需要使用经过变化的state数据时使用。

区别:里面的函数有两个默认的形参,第一个是state,第二个是getters,不接受其他的参数。

不接受其他函数,如果需要传参数,需要在里面return一个函数。

getters:{
    fun(state){
      return function (age) {
        return state.students.filter(s=>s.age > age)//返回年龄大于参数age的学生 对象
      }
    }//下图使用
}

使用的时候是$store.getters.fun

mutations

mutations,突变,转变,改变

state唯一的更新方式时通过mutations。

mutations必须是同步方法,因为devtools可帮我们捕捉mutation的快照,如果是异步方法devtools无法捕捉。

mutations可分成两部分:

  • type事件类型
  • handler回调函数,该回调函数的第一个参数是state
传参:(参数也可以是对象)

1、绑定事件,在事件函数里面使用this.$store.commit('type',value);这种方法只能发一个参数。
2、type是store里面mutations里面的函数名

3、mutations对应上的函数第一个参数是state(固定),第二个可以自定义形参用于接收数据

4、在mutations里面操作state数据。

另一种提交风格
mutations的类型常量

action

在vuex中想要进行异步操作,可以用action来取代mutations。action类似于mutation,只是它主要用于进行异步请求(网络请求)。

ps.初学阶段好像在mutation上异步也没啥影响。。。所以action...暂时没啥作用....

module

当项目越来越大的时候,state显得越来越臃肿,但是又提倡使用单一状态树,所以使用module解决。

分模块。

modules:{
  a:{
    state:{},
    mutations:{},
    actions:{},
    getters:{}
  },
  b:{
    state:{},
    mutations:{},
    actions:{},
    getters:{}
  }
}

???

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,951评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,606评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,601评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,478评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,565评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,587评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,590评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,337评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,785评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,096评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,273评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,935评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,578评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,199评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,440评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,163评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,133评论 2 352

推荐阅读更多精彩内容

  • 一、什么是Vue.js 1. vue是一种数据驱动的前端框架 this.msg="我爱你",通过改变数据,然后自动...
    在路上919阅读 1,597评论 0 2
  • 一、了解Vue.js 1.1.1 Vue.js是什么? 简单小巧、渐进式、功能强大的技术栈 1.1.2 为什么学习...
    蔡华鹏阅读 3,319评论 0 3
  • 动态绑定class : class:[ name?success:error,name?success:error...
    游_弋阅读 275评论 0 2
  • Vue不支持IE8以及以下版本。 想要使用Vue的话可以通过直接下载vue.js,放置到项目中写好路径就可以,或者...
    酥枫阅读 626评论 0 0
  • 渐变的面目拼图要我怎么拼? 我是疲乏了还是投降了? 不是不允许自己坠落, 我没有滴水不进的保护膜。 就是害怕变得面...
    闷热当乘凉阅读 4,241评论 0 13