• vue开发必须知道的九大秘法


    近年来,vue越来越火,使用它的人也越来越多。vue基本用法很容易上手,但是还有很多优化的写法你就不一定知道了。本文列举了一些vue常用的开发技巧。

    require.context()

    在实际开发中,绝大部分人都是以组件化的方式进行开发。随之而来就有了许多的组件需要引入。比如以下场景:

    import outExperInfo from "@/components/userInfo/outExperInfo";
    import baseUserInfo from "@/components/userInfo/baseUserInfo";
    import technicalExperInfo from "@/components/userInfo/technicalExperInfo";
    import skillExperInfo from "@/components/userInfo/skillExperInfo";
    
    components:{
        outExperInfo,
        baseUserInfo,
        technicalExperInfo,
        skillExperInfo
    }
    

    这样写并没有错,但是仔细观察发现写了很多重复的代码,这个时候利用require.context()可以写成:

    const path = require('path')
    const files = require.context('@/components/userInfo', false, /.vue$/)
    const userComponents = {}
    files.keys().forEach(key => {
     const name = path.basename(key, '.vue')
     userComponents[name] = files(key).default || files(key)
    })
    components:userComponents
    

    这样不管需要引入多少组件,都可以使用这一个方法。


    路由的按需加载

    随着项目功能模块的增加,引入的文件数量剧增。如果不做任何处理,那么首屏加载会相当的缓慢,这个时候,路由按需加载就闪亮登场了。

    webpack< 2.4 时
    {
     path:'/',
     name:'home',
     components:resolve=>require(['@/components/home'],resolve)
    }
     
    webpack> 2.4 时
    {
     path:'/',
     name:'home',
     components:()=>import('@/components/home')
    }
    

    import()方法是由es6提出的,动态加载返回一个Promise对象,then方法的参数是加载到的模块。类似于Node.js的require方法,主要import()方法是异步加载的。


    动态组件

    场景:如果项目中有tab切换的需求,那么就会涉及到组件动态加载,一般写法如下:

    <component v-bind:is="currentTab"></component>
    

    这样写也没有错,但是如果这样写的话,每次切换的时候,当前组件都会销毁并且重新加载下一个组件。会消耗大量的性能,所以 就起到了作用。

    <keep-alive>
     <component v-bind:is="currentTab"></component>
    </keep-alive>
    

    有的小伙伴会说,这样切换虽然不消耗性能了,但是切换效果没有动画效果了,别着急,这时可以利用内置的

    <transition>
    <keep-alive>
     <component v-bind:is="currentTab"></component>
    </keep-alive>
    </transition>
    

    components和vue.component

    前者是局部注册组件,用法如下:

    export default{
     components:{home}
    }
    

    后者是全局注册组件,主要针对一些全局使用的组件,用法如下:

    Vue.component('home',home)
    

    Vue.nextTick

    Vue.nextTick()方法在下次DOM更新循环结束之后执行延迟回调,因此可以页面更新加载完毕之后再执行回调函数。下面介绍几个常用场景:

    场景一

    <template>
        <div>
            <div ref = "ref"/>
        </div>
    </template>
    <script>
    export default {
        created(){
            console.log(this.$refs.ref)
            //undefined
        })
    }
    }
    </script>
    

    因为这个时候created阶段dom并未完全渲染完成,所以获取值为undefined,我们对其改造一下:

    <template>
        <div>
            <div ref = "ref"/>
        </div>
    </template>
    <script>
    export default {
        created(){
            Vue.nextTick(()=>{
                console.log(this.$refs.ref)
            })
            //<div></div>
            
        })
    }
    }
    </script>
    

    这样就可以获取到dom了。

    场景二

    <template>
        <div>
            <div v-if="visible" ref = "ref"/>
        </div>
    </template>
    <script>
    export default {
        data() {
            return {
              visible: false
            };
        },
        showRef() {
            this.visible = true;
            console.log(this.$refs.ref);
            //undefined
        },
    }
    }
    </script>
    

    因为这个时候虽然visible的值为true,但是页面dom并没有更新完成,所以获取值为undefined,我们对其改造一下:

    <template>
        <div>
            <div v-if="visible" ref = "ref"/>
        </div>
    </template>
    <script>
    export default {
        data() {
            return {
              visible: false
            };
        },
        showRef() {
            this.visible = true;
            Vue.nextTick(()=>{
                console.log(this.$refs.ref)
            })
            //<div></div>
        },
    }
    }
    </script>
    

    这样就可以获取到dom了。


    Vue.directive

    场景:官方给我们提供了很多指令,但是我们如果想将文字变成指定的颜色定义成指令使用,这个时候就需要用到Vue.directive,示例如下:

    // 全局定义
    Vue.directive("change-color",function(el,binding,vnode){
     el.style["color"]= binding.value;
    })
     
    // 使用
    <template>
        <div v-change-color>{{message}}
        </div>
    </template>
    <script>
     export default{
         data(){
          return{
          color:'green'
          }
         }
     }
    </script>
    

    Vue.set()

    当在项目中直接设置数组的某一项的值,或者直接设置对象的某个属性值,这个时候,你会发现页面并没有更新。这是因为Object.defineprototype()限制,监听不到变化。

    解决方式:

    • this.$set(你要改变的数组/对象,你要改变的位置/key,你要改成什么value)
    this.$set(this.arr, 0, "OBKoro1"); // 改变数组
    this.$set(this.obj, "c", "OBKoro1"); // 改变对象
    
    • 数组原生方法触发视图更新,vue可以监听到数组原生方法导致的数据数据变化
    splice()、 push()、pop()、shift()、unshift()、sort()、reverse()
    

    意思是使用这些方法不用我们再进行额外的操作,视图自动进行更新。
    推荐使用splice方法会比较好自定义,因为slice可以在数组的任何位置进行删除/添加操作


    事件修饰符

    • .stop:阻止冒泡
    • .prevent:阻止默认行为
    • .self:仅绑定元素自身触发
    • .once: 2.1.4 新增,只触发一次
    • passive: 2.3.0 新增,滚动事件的默认行为 (即滚动行为) 将会立即触发,不能和.prevent 一起使用
    • .sync 修饰符

    从 2.3.0 起vue重新引入了 .sync 修饰符,但是这次它只是作为一个编译时的语法糖存在。它会被扩展为一个自动更新父组件属性的 v-on 监听器。示例代码如下:

    <comp :foo.sync="bar"></comp>
    

    会被扩展为:

    <comp :foo="bar" @update:foo="val => bar = val"></comp>
    

    当子组件需要更新 foo 的值时,它需要显式地触发一个更新事件:

    this.$emit('update:foo', newValue)
    

    长列表性能优化(数据冻结)

    众所周知,vue会通过object.defineProperty对数据进行劫持,进而实现页面实时相应数据的变化,然而我们有些时候,需要的仅仅就是纯粹的展示数据,因为数据不会有任何改变,我们就不需要vue来劫持我们的数据。在数据量很大的情况下,这可以很明显的减少加载时间。

    那么如何实现禁止vue劫持我们的数据尼?可以通过object.freeze方法来冻结数据,冻结之后数据也就不能再修改了。示例如下:

    let longList = [
        {name:'monkeysoft'},
        ...
    ]
    this.longList = Object.freeze(longList)
    
  • 相关阅读:
    Ⅰ.Spring的点点滴滴--序章
    Ⅶ.AngularJS的点点滴滴-- 事件
    Ⅵ.AngularJS的点点滴滴-- 指令
    vue路由跳转
    使用<a-select>时,placeholder不起作用
    动态配置生成echarts图表
    elementui resetFields()不起作用
    input输入框与button按钮之间存在空隙
    一个怂女婿的成长笔记【二十二】
    一个怂女婿的成长笔记【七】
  • 原文地址:https://www.cnblogs.com/monkeySoft/p/13255242.html
Copyright © 2020-2023  润新知