vue開發必須知道的九大祕法

近年來,vue愈來愈火,使用它的人也愈來愈多。vue基本用法很容易上手,可是還有不少優化的寫法你就不必定知道了。本文列舉了一些vue經常使用的開發技巧。前端

require.context()

在實際開發中,絕大部分人都是以組件化的方式進行開發。隨之而來就有了許多的組件須要引入。好比如下場景:vue

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()能夠寫成:node

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


路由的按需加載

隨着項目功能模塊的增長,引入的文件數量劇增。若是不作任何處理,那麼首屏加載會至關的緩慢,這個時候,路由按需加載就閃亮登場了。es6

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()方法是異步加載的。web


動態組件

場景:若是項目中有tab切換的需求,那麼就會涉及到組件動態加載,通常寫法以下:數組

<component v-bind:is="currentTab"></component>
複製代碼

這樣寫也沒有錯,可是若是這樣寫的話,每次切換的時候,當前組件都會銷燬而且從新加載下一個組件。會消耗大量的性能,因此 就起到了做用。性能優化

<keep-alive>
 <component v-bind:is="currentTab"></component>
</keep-alive>
複製代碼

有的小夥伴會說,這樣切換雖然不消耗性能了,可是切換效果沒有動畫效果了,彆着急,這時能夠利用內置的dom

<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方法會比較好自定義,由於splice能夠在數組的任何位置進行刪除/添加操做


事件修飾符

  • .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)
複製代碼

最後,若是你們想和我一塊兒討論探索前端,能夠關注一下個人公衆號,不按期更新干貨,更可加入技術羣交流討論。

相關文章
相關標籤/搜索