美文网首页前端开发那些事儿Vue
这些vue技巧,你值得拥有

这些vue技巧,你值得拥有

作者: 辉夜真是太可爱啦 | 来源:发表于2020-06-28 17:03 被阅读0次
    分享我在vue开发中积累的开发技巧总结,有些会结合使用环境或者是我的个人网站(https://www.cooldream.fun/home)中的使用实例来说明,毕竟光有技巧也要考虑结合使用环境,这才能做到对于学习状态的加深印象以及实际使用的事半功倍,话不多说,我是想到啥写到啥,不要因为有些可能有点low或者用的不多就看一半就关了,希望你能够耐心看完,多多少少肯定对你还是有点帮助的,最后,也希望阅读我的这篇博客能给我一个点赞,你们的赞是我更新的最大动力!

    1.动态组件 <component :is='组件名'></component>

    结合v-for循环使用

    • 使用环境

      如图,这是一个v-for渲染的列表(只是目前这个版块才刚开始做,目前只有一个),圆圈内的就是一个组件,也就是要v-for动态组件


      image
    • 实际使用

    一开始就是基本的组件引入了

    import ColorIn from '@/components/Magic/ColorIn.vue'
    import LineIn from "@/components/Magic/LineIn.vue";
    import LineIn from "@/components/Magic/Header.vue";
    import LineIn from "@/components/Magic/Footer.vue";
    
    export default{
          components:{
            ColorIn,
            LineIn,
            Header,
            Footer
        }
    }
    

    接下来就是动态v-for动态组件的使用,componentList:['ColorIn','LineIn','Header','Footer']使用下面的代码即可将代码依次循环

    <component v-for="(item,index) in componentList" :key="index" :is="item"></component>
    

    编译以后的效果就是

    <ColorIn></ColorIn>
    <LineIn></LineIn>
    <Header></Header>
    <Footer></Footer>
    

    2.watch进阶使用

    立即执行

    • 使用环境

    例如场景为页面一进来就调用拉取列表数据getList(),然后监听路由的$route.query.id然后触发列表数据的更新

    • 实际使用

    为了让它一开始就执行,我们需要在created()生命周期中执行一次拉取数据的方法

    watch:{
        '$route.query.id':{
            handle(){
                this.getList();
            },
        }
    },
    created(){
        this.getList();
    },
    

    但是使用immediate即可立即执行,改写以后的代码如下

    watch:{
        '$route.query.id':{
            handle(){
              this.getList();
            },
            immediate:true
        }
    },
    

    深度监听

    • 使用环境

    在监听对象的时候,对象的内部属性发生变化watch无法监听到,这种时候就需要使用深度监听,详情请看我的这一篇博客Vue由浅入深系列(二)详解Watch侦听器

    • 实际使用

    只需要设置deep:true即可开启深度监听

    data(){
        return{
            queryList:{
                count:0,
                name:'',
            }
        }
    },
    watch:{
        queryList(newValue,oldValue){
            //do something
        }
    },
    

    计算属性之setter

    data(){
        return{
            firstName:'',
            lastName:'',
        }
    },
    computed:{
        fullName:{
            get(){
                return `${this.firstName} ${this.lastName}`;
            },
            set(newValue){
                let names=newValue.split(' ');
                this.firstName=names[0];
                this.lastName=names[1];
            }
        }
    },
    

    $on('hook:生命周期')来简化window监听

    • 实际使用

    先来看一下平常的使用方法

    mounted () {
        window.addEventListener('resize', this.resizeHandler);
    },
    beforeDestroy () {
        window.removeEventListener('resize', this.resizeHandler);
    }
    

    改写以后的代码为,相比于上面的写法,这个写法的好处在于可以开启一个事件监听器的同时,就在beforeDestroy生命周期中挂载一个删除事件监听器的事件。比上面的写法会更加安全,更加有助于避免内存泄露并防止事件冲突

    mounted () {
      window.addEventListener('resize', this.resizeHandler);
      this.$on("hook:beforeDestroy", () => {
        window.removeEventListener('resize', this.resizeHandler);
      })
    }
    

    子组件@hook:生命周期监听子组件的生命周期回调

    • 实际使用
    <child @hook:mounted="listenChildMounted" />
    

    v-pre

    • 使用环境

    不需要编译的html代码可以使用v-pre,可以提高性能

    • 实际使用
    <span v-pre>{{message}}</span>    //就算data里面定义了message,渲染完也是{{message}}
    

    v-once

    • 使用环境

    只需要渲染一次,适用于渲染完以后就不会更新的内容,降低性能开销

    • 实际使用
    <span v-once>{{message}}</span>    //message的值会编译后渲染,但是编译以后再次修改message的值不会触发更新
    
    • v-pre与v-once的区别

    v-pre相当于不编译,直接显示,v-once相当于只编译一次,后面的更新不编译了

    Vue.set()

    • 使用环境

    当你利用索引直接设置一个数组项时或你修改数组的长度时,由于Object.defineprototype()方法限制,数据不响应式更新

    • 实际使用
    this.$set(arr,index,item);
    

    keep-alive

    • 使用环境

    当这个页面没有数据更新,或者是想保存状态,下次进来还是这样子的时候,例如淘宝查看列表页,点进去查看详情之后,返回列表页依旧到上次浏览到的地方,都可以使用keep-alive

    $route路由信息

    • $route.query.id

    用来拿取路由传值的信息,比如路由的后缀?id=1,$route.query.id拿到的值为1

    • $route.meta.flag

    用来拿取路由meta中的信息,路由信息里的meta是可以自定义属性的,我一般导航栏当前选中的nav用来和$route.meta.flag进行匹配,来拿到当前页面应该激活哪一个选项卡

    • base路由

    比方说百度的所有路由前缀要加/baidu,那么可以设置路由的base为/baidu

    export const router = new Router({
      base:'/baidu/',
    }
    

    此外,打包的时候,请修改config/index.jsbuild块中的assetsPublicPath为 '/baidu/',不然打包以后是找不到资源文件路径的

    module.exports = {
        build:{
            assetsPublicPath: '/baidu/',
        }
    }
    
    • 全局路由钩子

    使用场景一般为用户的登录鉴权

    router.beforeEach((to, from, next) => {
      //一定要调用next()才能到下一个页面
      if (path === '/login') {
        next()
      }else{
        if(token){
          next();
        }else{
          next('/login');
        }  
      }
    })
    
    • 组件路由钩子中访问this

    组件路由的钩子一开始还未初始化,不能访问到vue实例
    beforeRouteEnter (to, from, next) {
    // 这里还无法访问到组件实例,this === undefined
    next( vm => {
    // 通过 vm 访问组件实例
    })
    }

    样式穿透

    • 使用环境

    一般在修改插件样式的时候使用的比较多

    • 实际使用

    分为两种,一般stylus中使用>>>less中使用/deep/sass没有使用经验,不予说明

    
    >>>.el-dialog .el-dialog__body{
      padding 0
      text-align center
      border-radius 0 0 4px 4px
    }
    /deep/.el-dialog .el-dialog__body{
      padding 0
      text-align center
      border-radius 0 0 4px 4px
    }
    

    Object.freeze()

    • 使用环境

    我们都知道vue是使用Object.defineProperty对数据进行双向绑定,而对于只做展示使用的长列表,可以使用Object.freeze()进行冻结,使它无法被修改,从而提高性能

    • 实际使用
    getList().then(res=>{
        this.list=Object.freeze(res.data.result);
    })
    

    值得注意的是,改变list的值不会更新,但改变引用会触发更新

    组件通信技巧

    • props
    • $emit
    • $attrs & $listeners
    • provide & inject
    • vuex
    • Observable
    • eventBus
    • $refs
    • slot-scope & v-slot
    • scopedSlots
    • $parent & $children & $root

    详细使用可以查看我的这一篇博客一篇文章看懂Vue.js的11种传值通信方式

    mixins混入的使用

    • 使用环境

    一般获取验证码,收藏,点赞等公用且逻辑一样(有些逻辑是根据页面的不同而不同的不建议使用混入)等场景都可以使用混入

    • 实际使用

    这里我直接封装了一个vue新开窗口的混入方法,引入了以后,混入中的所有data,methods,以及生命周期都会共享

    //openWindow.js
    export default {
      methods:{
        openUrl(url){
          const link= this.$router.resolve({path: url});
          window.open(link.href,'_blank');
        },
      }
    }
    
    //其他页面使用
    import openWindow from "../../mixins/openWindow";
    
    export default{
        mixins:[openWindow],
    }
    
    • 注意点(使用的页面统称为组件)

    ① 混入比组件优先执行

    ② 当混入中的属性或者方法与组件中的属性或者方法名称相同时,以组件中的值为准(结合上一条规则,因为混入先执行,所以组件会将混入覆盖)

    ③ 比方说A页面和B页面都使用了同一个混入,A页面与B页面的状态同样是独立的

    qs

    • 使用场景,get传输的时候都是路由拼接方式(?a=1&b=2),而不是json方式

    • 实际使用

    //安装依赖
    npm install qs --save
    
    //页面中或者直接api.js中直接序列化使用
    import qs from 'qs'
    qs.stringify(params)
    
    //axios拦截器中直接使用
    import qs from 'qs'
    axios.interceptors.request.use(
      config => {
        if (config.method === 'get') {
          config.data = qs.stringify(config.data)
        }
    )
    

    v-for绑定key不建议使用index,建议使用另外的并且值唯一的变量,例如后台给你的id

    • 主要原因

    有的时候v-for列表可能存有删除,交换位置等操作,这种时候index的顺序变换会导致同一条数据,在此刻的index置换,所以,不建议v-for的key绑定index

    v-for不建议配合v-if

    • 主要原因

    v-for的优先级比v-if高,也就是说,假设总计50条数据,即使经过v-if以后,只剩下25条显示,但是v-for早就循环了一遍50条数据,解决办法就是用一个计算属性先将数据过滤了以后,v-for循环过滤了之后的数据

    document.body.contentEditable

    • 操作方法

    打开控制台,输入document.body.contentEditable=true,然后敲回车,网页可以像word一样编辑,很方便对于页面的布局抗压能力做测试

    相关文章

      网友评论

        本文标题:这些vue技巧,你值得拥有

        本文链接:https://www.haomeiwen.com/subject/tonvfktx.html