1. 程式人生 > 前端設計 >這些vue技巧,你值得擁有

這些vue技巧,你值得擁有

分享我在vue開發中積累的開發技巧總結,有些會結合使用環境或者是我的個人網站(www.cooldream.fun/home)中的使用例項來說明,畢竟光有技巧也要考慮結合使用環境,這才能做到對於學習狀態的加深印象以及實際使用的事半功倍,話不多說,我是想到啥寫到啥,不要因為有些可能有點low或者用的不多就看一半就關了,希望你能夠耐心看完,多多少少肯定對你還是有點幫助的,最後,也希望閱讀我的這篇部落格能給我一個點贊,你們的贊是我更新的最大動力!

1.動態元件 <component :is='元件名'></component>

結合v-for迴圈使用

  • 使用環境

    如圖,這是一個v-for渲染的列表(只是目前這個版塊才剛開始做,目前只有一個),圓圈內的就是一個元件,也就是要v-for動態元件

  • 實際使用

一開始就是基本的元件引入了

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

  • 實際使用 我們一般平常使用的都是getter,但其實它還有個setter,當計算屬性的fullName觸發更新的時候,就會觸發setter回撥,計算屬性詳情請看我的這一篇部落格Vue由淺入深系列(三)詳解Computed計算屬性
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一樣編輯,很方便對於頁面的佈局抗壓能力做測試