vue知识点总结

440 阅读13分钟

Vue

vue的语法知识点

  1. null与undefined都不显示
  2. 其他全是json格式字符串
  3. 当data中的属性挂载到vue的实例上的时候,会给每一个属性都加上set、get方法,有这两个方法就是响应式,没有就不是
  4. 原生的方法改变对象和数组不具备响应式
  5. vue对数组的原型进行了重定向,对一些方法进行了二次封装,使这几个方法具有响应式,具体都有push、pop、unshift、shift、sort、reverse、splice
  6. vue实例里的方法,如果不是箭头函数,那么this指的是当前vue实例,如果是箭头函数,指的是window

vue中的指令

按照v-xxx处理的,它使vue中规定给元素设置的自定义属性 当vue执行的时候会把这个带有特殊指令的标签按照指令进行特殊处理

  1. v-html、v-text将指定的内容放到容器
  2. v-bind: 它可以使行间的普通属性进行动态取值,可以简写成:
  3. v-on: 它可以给当前元素绑定on事件,可以简写为@
  4. v-once 用v-once获取的值只会刷新一次,以后就算数据更新,视图也不改变了,用法<div v-once>{{msg}}</div>
  5. v-if v-else-if v-else 判断,相当于把原生的条件写在标签上,如果使用true就显示,使对dom的卸载与加载
  6. v-show 它也是判断元素的显示隐藏的,它控制的是行间样式 display,如果为false就是none,适用于频繁显示隐藏的场景
  7. v-model 双向绑定,适用于表单元素
  8. v-for它是vue中渲染数据的,用法v-for="item,index in 循环对象"
    • 特点:
    • 循环的是数组,item是每一项,index是索引
    • 循环的是对象,item是属性值,index是属性名
    • 循环的是数字,item是循环次数,index是索引,数字是几循环几次
    • 循环的是字符串 item就是当前的哪个字符,index是索引
    • 剩下的就不会执行了

vue中的事件

  1. 当执行函数的时候带(),那e就成了形参,如果不带就是事件对象,可以使用$event来占位解决问题
  2. @click事件执行早于数据更新
  3. @change事件执行晚于数据更新
<div @click="fn">{{msg}}</div>

事件修饰符

事件修饰符就是用来修饰你此次的事件行为的,可以链式调用 用法: @click.修饰符="执行的函数"

  1. .stop 阻止事件冒泡
  2. .prevent 阻止事件的默认行为
  3. .capture 控制方法在捕获阶段执行,从外而内,如给单一的设置就遵循 原生中先捕获,然后目标源,最后冒泡的规则
  4. .once 只让当前方法触发一次,不会阻止事件的冒泡
  5. .self 只有点击自己的时候才能触发方法,如果不是点击的自己,冒泡都不能够触发

键盘事件修饰符

用法:@keydwn.修饰符="函数" 可以链式调用,多个的情况下就是需要同时按着几个键 写成code码也行

  • .enter 按下enter的时候执行
  • .ctrl 按下ctrl时候才执行
  • .c按下c才执行
  • .ctrl.c同时按下ctrl和c执行

vue里面的style和class

  1. :class={box:true} 当前的box是css样式类名,如果后面为true就加,不是就不加
  2. :class="[x]" 可以取data里的值,且可以取多个值,先向css找,找不到再找data
  3. :style={color:aa} aa是data里的变量
  4. :style=[x] x是data里的变量,可以写多个

vue表单元素的用法

单选框

  1. 都会按照v-model进行分组,单选框的数据是一个单一的值
  2. 每一个都有一个value值,谁被选中,那当前data中的数据就是谁的value
        <input type="radio" value="0" v-model="sex">男
        <input type="radio" value="1" v-model="sex">女
//sex:0让他默认选男

复选框

  1. 按照v-model进行分组,复选框的数据是一个数组
  2. 谁被选中,谁的value就被放进数组
        <div @change="brand">
            <input type="checkbox" value="1" v-model="checkList">1
            <input type="checkbox" value="2" v-model="checkList">2
            <input type="checkbox" value="3" v-model="checkList">3
        </div>
//checkList: []

methods函数

  • methods是一个对象,存储的是一些函数
  • 里面的方法会被添加到vue的实例上 方法执行的时候可以不添加小括号

filters过滤

  • filters对象存储的这些方法是为了专门进行二次数据处理的
  • filter中的方法也会被添加到vue的实例上
  • 方法执行的时候可以不加小括号,方法里的第一个形参就是管道符左边的值
  • 管道符 |
    //<div>{{msg|toFixed}}</div>
    let vm = new Vue({
        el: "#app",
        data: {
            msg: 1.111
        },
        methods: {}
        filters: {
            toFixed(value) {
                return value.toFixed(2);//保留两位小数
            }
        }
    })

computed计算属性

  • computed中的属性最终也会被挂载到当前vue的实例上
  • 注意:虽然看着是一个函数,但它其实是一个属性
  • 在视图里面不能加()执行,它存储的只是当前函数返回的值
  • 定义的时候当成函数去定义,使用的时候当成值去使用

computed的缓存机制

  • 计算属性有自己的缓存机制,当第一次执行的时候,产生了一个值,缓存下来,以后当视图重新刷新的时候,当前的resover会看依赖的this.text属性有没有发送改变,如果没有发生改变,就不会重新执行,会拿以前的缓存直接赋值到视图中
  • 默认只有一个get,想用set需要手动设置
       computed: {
            reverse() { //不是一个函数
                return this.text+1;
            },
            ss: {
                get() {
                    //只要你获取ss,那么get执行,获取到的就是return的
                    return this.text * 100;
                },
                set(value) {
                    //重新ss赋值,value就是那个值,最新的
                    return this.text * 100;
                    /* 
                    在computed里面return不要用异步,因为会显示undefined,页面不显示
                     */
                }
            }
        }

watch监听器

  • 这里存放的是方法,监听谁名字就是谁,一旦对应的值发生改变,函数就执行
  • watch支持异步
data:{msg:10},
watch:{
            msg(value) {
                console.log(value);
                setTimeout(()=>{
                    this.aa = this.aa * value;
                },1000)
                
            }
}

生命周期

  1. beforeCreate 此函数执行代表要开始初始化实例了,这是data和methods中的数据还没有挂载到实例上
  2. created 初始化完成,可以拿到数据了,在这里替换data里的数据不会引发视图的再次更新,因为模板还没有被挂载,平时在这里发送请求
  3. beforeMount 生成的dom模板挂载到真实的dom上之前,在这里修改数据不会引发视图的刷新
  4. mounted 挂载完成,此时页面已经正常显示了,可以拿到渲染完成以后的dom元素
  5. beforeUpdate 初次渲染的时候不会执行,当后期改变响应数据的时候会执行,代表改变数据之前
  6. updated 初次渲染不会执行,代表数据修改完成
  7. beforeDestroy 不会执行,除非手动添加vm.$destroy(),代表销毁当前vue实例之前
  8. destroyed 不会执行,除非手动添加vm.$destroy(),代表已经销毁当前vue实例

$destroy()

beforeDestroy与destroyed的触发条件,一旦销毁完成,那么当前页面就不具备响应式了

let vm=new Vue({});
vm.$destroy();

分类

  • beforeCreate,created,beforeMount,Mounted在第一次初始化的时候执行,以后不会执行
  • beforeUpdate,updated在初次渲染的时候不会执行,后期响应式数据改变才执行
  • beforeDestroy,destroyed只有在销毁的时候才会执行,销毁方法vm.$destroy(),销毁以后页面就是死页面了,不是响应式了

模板

  • 如果vue在初始化的时候有template选项,就把template的属性值进行编译,然后把app元素进行替换
  • 模板里的元素可以正常使用小胡子语法,与正常在body里写其他的没有区别
  • template只能有一个根元素,写在外面是为了复用
<body>
    <div id="app">
    </div>
    <div id="app1"></div>
    <template id="first">
        <div>
            {{msg}}
        </div>
    </template>
</body>

 let vm = new Vue({
        el:"#app",
        data: {
            msg: 100
        },
        template: '#first'
    })
    let vm1 = new Vue({
        el:"#app1",
        data: {
            msg: 100
        },
        template: '#first'
    })

组件

组件化思想

  • 组件:就是把相同功能,结构,样式的代码封装到一起,以后你想使用这部分需求的话,就直接调用这个组件就好,实现了代码的复用率,减少了代码的冗余
  • 特点可复用、方便维护、vue创建的组件都是一个独立的个体,拥有自己完整的vue实例,且不同组件之间的数据互不干扰、组件还可以进行嵌套
  • 类别全局组件局部组件
  • 全局组件在当前vue里自己身上有一个component属性,他执行可以 创建除一个全局组件
<body>
    <div id="app">
        <com></com>
        <com></com>
    </div>
</body>

    Vue.component('com',{
        data(){
            return {
                msg:100
            }
        },
        methods:{},
        template:'<div>{{msg}}我是com组件</div>'
    });
    let vm=new Vue({
        el:"#app",
    })

组件的命名规则

  1. 给组件起名字的时候,如果组件名字开头大写了,那使用的时候可以不区分大小写
  2. 组件起名字的时候不能全是大写
  3. 起名字的时候如果是驼峰命名法,那使用的时候以-隔开,如:ComPu使用的时候写成com-pu
  4. 组件名字不能和h5的标签名重复,例如不可以使用div

组件的调用

  1. 双闭合标签
  2. 单闭合标签
    • 这种形式其实是不规范的,当前组件可以正常渲染,但是他下面的东西就不能正常渲染了,不过在页面最后可以用这种
    <div id="app">
        <com-pu>55</com-pu>
        <div>123</div>
        <com-pu />
    </div>
        Vue.component('ComPu', {
        data() {
            return {
                msg: '我是组件'
            }
        },
        template: `<div>
                     {{msg}}
                     <slot></slot>
                     <span>123</span>
                   </div>`
    });

插槽slot

  • slot的使用可以让组件变化的个性化,可以在使用组件的时候,在组件标签内传递一些东西到组件内部,(在组件内部使用slot标签进行接收)
  • slot插槽可以使用一个,也可以使用多个,如果使用多个的话就要具名化插槽
  • 具名化:给slot加一个name属性,给要添加的内容最外面的template加一个v-slot:属性名,这个slot的name值与template的v-slot值要对应
  • 给插槽插入东西的时候,要拿template包起来
    <div id="app">
        <com>
            <template v-slot:first>
                <div>
                  <span>111</span>  
                  <index></index> 
                </div>            
            </template>
        </com>
    </div>


        Vue.component('ComPu', {
        data() {
            return {
                msg: '我是组件'
            }
        },
        template: `<div>
                     {{msg}}
                     <slot name='first'></slot>
                   </div>`
    });

组件的生命周期

组件虽然小,但是他也属于vue的实例,也有自己的生命周期 当我渲染父级组件的时候,也需要把子级组件拿到,等子级渲染完,父级才能把他渲染到页面上

局部组件

局部组件跟全局组件一样,都有他自己的实例,自己的生命周期,自己的data.... 流程:

  • 创建组件
  • 注册组件 在用的实例里面添加components对象,将局部组件的名字放进去
  • 使用组件
   let com1={
       template:'<div>我是局部组件</div>',
   }
    let vm = new Vue({
        components:{
            com1
        }
    })

组件的使用

父传子

  1. 在子组件中设置props(是个数组)来接受父亲从那里传递过来的属性信息,接收后,会把当前接收的属性挂载到当前的组件实例上
  2. 也可以写成对象的格式,前面是名字,后面是数据类型,如果数据类型不匹配就报错,但是不影响代码运行,很鸡肋
  3. :ss="true"还可以传递一个指定的值
  4. 还可以给每一个属性设置一个的对象,可以设置一些其他的东西,如格式校验、默认值
  <div id="app">
      <com :num="msg" :ss="1111"></com>
  </div>

 let com={
        template:'<div>{{ss}}我是com组件{{num}}</div>',
        // props:["num"],
        // props:{
        //     num:Number
        // },
        props:{
            ss:{
                required:true,//必须传
                validator(val){
                    console.log(val)
                    return val>1000
                },//val是接收的值,返回的true就是成功,false就是不合格,只会提示,但是不会影响渲染
            },
            num:{
                type:[String,Boolean,Number],//检验数据类型
                default:'我是默认值',
            }
        },
        /* 
        props接收行间从父级传过来的值,而且会挂载到当前的组件实例
        */
    };
        let vm=new Vue({
        el:"#app",
        data:{
            msg:100
        },
        components:{
            com
        }
    })
vue的数据流

vue的数据流是单向的,只能从外边流向里边,不能倒着流,而且不能从里面进行更改

子改父

儿子直接修改父亲的数据是不可行的,但是父亲自己改自己的数据是可以的,这时候在父亲身上定义一个改数据的方法,传递给儿子 vue实例身上有 $emit发布$on订阅方法

兄弟之间的参数相互传递

创建一个事件车,作为中介:例如

let eventBus = new Vue();//事件车
/* 
我们可以在其他组件内通过 eventBus.$on('事件池子类型',函数)存储方法
然后在其他组件内通过 eventBus.$emit('事件池子类型')执行方法
 */

组件之间的通信

$refs$parent$children
  1. $refs拿到指定的子级,用法:给子级的组件身上添加一个ref='自定义名' 使用的时候在父级组件上用this.$refs.自定义名.变量=值
    • $refs还可以用来获取dom元素,用法没有改变,与上面一致
    • 名字不能重复,重复了会取最后一个
  2. $parent 在子组件上可以获取到父级组件 用法:this.$parent.变量=某个值
  3. $children 在父组件上获取到全部的子组件,但是是一个数组 用法this.$children[索引].变量=某个值
provide、inject
  • provide是进行传参的,将后代要用的传递给this._provide,后代使用的话只需要用inject接收即可
  • provide可以写成对象的模式,也可以写成函数返回对象的模式
  • 写成对象的时候 传递函数的时候,会传递不上
  • 写成函数的时候,会形成闭包,等挂载完成以后再传
  • 查看是否挂载上,this._provide
  • 如果想让数据变化变成响应式的,就需要在设置的时候注意点,在data里面存成一个对象,注意必须要是对象,单个的值不行
  • inject是接受变量用的,在子孙级别使用是个数组,接收的时候带引号,
  • 注意:想子改父级的话还是需要获取父级方法,改变,或者$parent
    let son={
        template:"#son",
        inject:["r"]
    }
    let father={
        template:"#father",
        components:{
            son
        }
    }
    let vm=new Vue({
        el:"#app",
        data:{
            r:{
            // 必须是可监听的对象才是响应式
                num:0
            }
        },
        provide(){
            return {
                // num:0,
                r:this.r
            }
        },
        components:{father}
    })

浅谈vue中的get和set

  • 当Vue初始化的时候,他会基于Object.defineProperty()方法去给data中的所有属性加get和set监听器
  • vue内置的objerver/defineRecitve函数,会帮我们去递归调用Object.defineProperty,利用递归的形式给每一个属性加上set和get
  • vm.$set(obj,"ee",100)后期这样添加属性也是响应式的,因为$set函数会帮我们去调用Object.defineProperty,
  • 获取数据的时候执行get,return的值赋值给当前获取的属性,更改的时候执行set,set的return值不管用
    let vm=new Vue({
        el:"#app",
        data:{
            ss:100,
            obj:{
                aa:123,
            }
        }
    })

Vuex

  • vuex就是把组件中的公共的状态(数据)抽离出来,存放到一个全局的单例模式中,以后不管哪个组件想使用公共的状态,就直接去单例模式中获取就好了
  • 单例模式中的状态是响应式的,只要状态被改变了,那所有使用到该状态的组件会全部更新
  • 如果你的项目是小型的,那就没有必要使用vuex
  • 如果是中大型的项目,而且项目里的组件传参很复杂,这时候你不得不使用公共状态管理工具了Vuex 1. vuex里存储的状态是响应式的,组件中如果使用了vuex中的状态,后期状态更新,那组件会自动更新 2. 不能直接修改vuex里的状态,如果想修改必须commit一个mutations中的函数,这样方便我们去追踪修改的记录
  • 用法:创建一个Vuex.Store实例
  • 在根目录引入,这样在vm里每一个组件都会增加一个$store的属性这个store的属性值就是当前的仓库
    let store = new Vuex.Store({
        state: {
            count : 10
        }
    })

    let vm = new Vue({
        el: "#app",
        store: store //导入vuex
    })

state

  • state对象是存放公共状态的地方,类似于vue实例中的data
  • 是响应式的
  • 获取方法this.$state.state.count
  • 获取方法可以简化,写在vm的computed对象内
        state: {
            count : 10
        }

mutations

  • mutations是Vuex存放函数的地方,类似于vue实例中的methods
  • 这里面必须是同步函数,官方规范,虽然写异步也能执行,但是会影响调试工具的输出
  • 参数 + 这里面的函数第一个值都是固定的,state,代表的是state对象 + 第二个值叫做载荷,就是执行commit传递进来的参数,最好是一个对象,因为在调试工具中便于观察
  • 执行里面的函数的方法 this.$store.commit('函数名','传参')
        mutations:{
            add(state,payload){}
        }

        //    add(context){
        //        this.$store.commit('add')
        //    }

actions

  • 这里也是执行函数的,但是这里可以放异步
  • 是一个对象
  • 这里面的第一个参数是context代表的是this.mutations这个对象
  • ations中不可以改变state的值,但是可以执行commit,以此来触发mutations里的函数
  • 函数执行:this.$store.dispatch('add');
        mutations:{
            add(state,payload){}
        },
        actions:{
           add(context){
               setTimeout(()=>{context.commit('add')})
           }
        }
        // methods:{
        //     change(){
        //         this.$store.dispatch('add');
        //     }
        // }

getters

  • 是一个对象
  • 这里存储的是vuex的计算属性

modules

  • 作用:将状态进行细分
  • 先写成一个个的小对象,然后在vuex里用modules(是个对象)导入
  • 浏览器会自动将这些小的对象进行合并分类 + 只有state里面的会单个的合并成一个对象,然后放在全局state里 + 其他的都是合并到全局的各个类,但里面的this指向的还是自己的小模块,如果重名了,会合并成一个事件池子,如果想让他重名了也不合并,就在小模块里加上nameSpace=true,那它就会在除了state的其他前面加个名字/
  • 使用的时候,...Vuex.mapActive('名字',['add1'])这样就可以利用语法糖,且使用的时候直接使用add1即可,add1于active不是固定的
    let first = {
        //这是组件一的状态库
        state: {
            num: 100
        }
    };
    let two = {
        //这是组件一的状态库
        state: {
            num: 200
        },
        getters:{
            add(){
                return this.num
            }
        }
    };
        let store = new Vuex.Store({
        modules: {//他会自动将这些合并分类
            com1: first,
            two: two
        }
    })
使用的小技巧,语法糖
  • 可以使用...Vuex.map方法来展开需要的项或方法,如
  • 在组件的computed中使用...Vuex.mapState(['num','msg'])展开state里面的num和msg,是语法糖
  • 支持展开的都有getters, state,mutations,actions
		 computed:{
            ...Vuex.mapState(['num', 'msg'])
        },
        methods:{
            ...Vuex.mapMutations(['add'])
        }

VueRouter

  • 路由的原理就是通过监听页面的hash值的变化,从而去切换hash对应的组件
  • 步骤: 1. 创建(注册)路由 2. 配置路由映射表 3. 在根目录导入路由
  • 在根目录下导入路由会给全部的子组件包括自己添加一个$route的属性
  • 使用方法 1. 在根元素里面用router-link标签 2. router-link里面的to属性对应的就是要展示的页面 3. router-link默认渲染成a标签,tag属性可以改变成button标签和li标签 4. router-view标签是用来展示页面的,一个view只能展示一个页面,切换新组件,那之前的组件就会销毁 5.
    <div id="app">
        <div>
                <router-link to="organizer" tag="button">组织结构</router-link>
                <router-link to="customer">客户管理</router-link>
            <router-view></router-view>
        </div>
    </div>
    let organizer = {
        template: `
        <div>组织结构</div>
        `
    };
    let customer = {
        template: `
        <div>客户管理</div>
        `
    };
    let router = new VueRouter({//注册路由
        /* 
        routes配置路由映射表
        */
        routes: [{
                path: '/organizer',
                component: organizer
            },
            {
                path: '/customer',
                component: customer
            }
        ]
    });
    let vm = new Vue({
        el: "#app",
        components: {
            customer,
            organizer
        },
        router//在根目录导入路由
        /* 
        在vue根目录下导入路由,会给所有的子组件身上增加$route属性,自己身上也会增加
        */
    })

$router身上几个切换路由的方法

  1. push('path') 跳转到指定的路由对应的组件
  2. go(num) 前进或后退到指定的路由对应的组件
  3. forward() 前进,相当于go(1)
  4. back() 后退,相当于go(-1)
  5. replace('path') 替换当前的组件,打开一个新的组件,但是之前的组件的历史记录就没有了

用法:this.$route.方法

路由的嵌套

  • 因为一个router-view标签只能显示一个页面,那我想在子页面再来一个路由就要在子页面的template根元素下再设置一个router-view
  • 子级路由写在父级路由映射表内,用children,是个数组,里面也是小对象(一个个的路由映射表)
  • 子路由的路径太长了可以省略父级路径,他会把前面省略的自动补全,注意这样写的时候不要带/,否则会当做绝对路径
    let router = new VueRouter({
      routes:[
      {
        path: '/organizer',
        component: organizer,
      },
      {
        path: '/customer',
        component: customer,
        children:[
          {
            path:'/customer/my',
            // path:'my',与上相同
            component:my,
          }
        ]
      }
    ]
    });

命名路由

  • 给路由映射表内的小对象设置个name属性,后期可以基于这个属性值进行跳转
  • 命名路由的好处:传参的时候可以用params和query
  • 默认的那种path要么手写在后面加?或这query,不支持params传参
<router-link :to="{name:'cur',query:{lx:'my'}}"></router-link>
//<router-link :to="{name:'cur',params:{lx:'my'}}"></router-link>
//<router-link to="curout?lx=my"></router-link> 默认的,与上相同
//映射表
    router: [{
      path: 'curout',
      component: 'curout',
      name: 'cur'
    }]

动态路由

  • 他可以试下传递参数,当配置路由映射表的时候,可以写一个动态的参数,比如'/detail/:ss',此时的ss就是一个动态的参数,这时候页面的hash只要与前面的/detail对应就行,后面写什么都可以
  • 里面那个传参可以在this.$route.params里获取到
   let routes = [
      {
        path: '/detail/:id', // 动态路由  '/detail/1' '/detail/2'  /detail/3
        component: first
      }]
  • 动态路由的好处就是减少了组件的加载和销毁,节省了性能,但是切换路由的时候,组件没有对应的回调函数(也就是组件创建与销毁时候的created等几个生命周期函数)去执行
  • 解决方法,在根目录的watch中监听$route,传两个参数to,from,只要路由切换这个函数就会被触发 + to里面是到哪里去的路由信息 + from是从哪里来的路由信息 + 在这里面可以做一些判断,拯救一下没有回调函数的弊端
      watch: {
        // 只要路由切换,当前的$route就会被监听到,然后执行监听函数
        $route(to, from) {
          console.log(to); // to是到哪去 去之后的路由的信息
          console.log(from); // from从哪里来 来之前的路由的信息
          // 对路由变化作出响应...
        }
      }

路由传参

  • 动态路由传参 + 页面刷新参数接收不会消失 + 通过hash值进行传参,参数暴露在url上
  • query传参 1. 通过hash值进行传参,参数暴露在url上,不美观不安全 2. 刷新页面参数不会丢失 3. 配合path或router-link跳转来使用 4. 参数接收的是字符串类型
  • params传参 1. 参数不会暴露在url上,美观,安全 2. 刷新页面参数会丢失 3. 配合name或router-link来跳转的 4. 参数接收的是原来的类型
<router-link :to="{name:'cur',query:{lx:'my'}}"></router-link>
//<router-link :to="{name:'cur',params:{lx:'my'}}"></router-link>
//<router-link to="curout?lx=my"></router-link> 默认的,与上相同

路由重定向

  • 路由是从上到下匹配的,找到会停止查找
  • 当为/时,将地址换为redirect内的内容,并切换对应的组件
  • *是全部的意思,一般放在最下面,匹配的是找不到的页面
      {
        path:'/',
        redirect:'/detail'
      },
            {
        path:'*',
        redirect:'/重定向页面'
      },

vueRouter导航守卫

  • 全局前置守卫router.beforeEach
    1. 在路由触发后,跳转前执行
    2. 参数回调函数(to,from,next)=>{}
    3. to是到哪去from从哪里来next类似于express里面的next中间件,不写就不执行跳转,里面也可以写地址,代表跳转到指定地址
  • 全局解析守卫router.beforeResolve
  • 全局后置钩子router.afterEach((to, from) => {})
    • 当跳转完成以后执行,与beforeEach的区别在于回调函数内没有next
  • 路由独享守卫
    • 在每个路由的小对象里面设置beforeEnter属性,值是(to, from, next) => {}
  • 组件内的守卫
    • 参数都是(to, from, next) => {}
    • beforeRouteEnter
      • 在渲染该组件之前执行
      • 这里没有this,因为还没有创建组件实例
      • 不过可以给next传递一个回调函数,当导航被确认以后执行回调
    • beforeRouteUpdate
      • 在当前路由改变,但是该组件被复用时候调用,一般指的是:id动态路由
      • 可以访问this实例
    • beforeRouteLeave
      • 导航离开该组件对应路由前往笑一个路由时候执行
      • 可以访问this

完整的导航解析流程

  1. 导航被触发。
  2. 在失活的组件里调用 beforeRouteLeave 守卫。
  3. 调用全局的 beforeEach 守卫。
  4. 在重用的组件里调用 beforeRouteUpdate 守卫 (2.2+)。
  5. 在路由配置里调用 beforeEnter。
  6. 解析异步路由组件。
  7. 在被激活的组件里调用 beforeRouteEnter。
  8. 调用全局的 beforeResolve 守卫 (2.5+)。
  9. 导航被确认。
  10. 调用全局的 afterEach 钩子。
  11. 触发 DOM 更新。
  12. 调用 beforeRouteEnter 守卫中传给 next 的回调函数,创建好的组件实例会作为回调函数的参数传入。

自定义指令

Vue.directive('power', {
  //当被绑定的元素插入到dom的时候执行该钩子函数
  inserted: function (el, obj) {
    /* 
    el是当前操作的元素
    obj是当前自定义指令的一些信息,其中value就是指令传进来的值
    */
    let power = store.state.power;
    let value = obj.value;
    if (!power.includes(value)) { el.parentNode.removeChild(el); }
  }
})

vue-cli

  • 他会帮我们把webpack等相关信息全部都配置完毕,我们只主要基于脚手架就可以构建一个项目
  • 安装 npm install -g @vue/cli
  • 安装成功以后在终端输入vue -version查看版本

使用脚手架创建项目

  • vue create 项目名称 注意:项目名不能使用汉字,不要是纯数字
  • 输入完成后回车,选择一些配置项
  • Manually select features手动配置

项目的结构

  • public 存放的是一些公共的东西
    • index.html 当前主页面的html模板
    • xxx 以后还有可能存放别的模板
  • src 这里存储的是我们开发时候的项目的源代码
    • assets 存放的是项目里的静态资源
      • xxx.png
      • xxx.css
      • components 存放的是当前项目的公共的组件
      • views(pages) 存放的是页面级的大组件
    • App.vue 项目页面的入口文件,一个项目只有一个
    • main.js webpack编译或者打包的入口文件

    Vue.mixin

    全局混入,可以在每一个vue实例上添加公共的东西, 如果实例上有就以实例上为主,没有就添加 在生命周期函数内,先执行Vue.mixin里的, 它也有自己的生命周期

    //混入num
    Vue.mixin({
    		data(){
         return {num:10
         }}
    		})
    

    局部混入

    创建一个对象,写上要混入的东西 在实例内用mixins:[对象名],(想给谁混就给谁添加)