溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

詳解Vue文檔中幾個易忽視部分的剖析

發(fā)布時間:2020-08-30 13:59:32 來源:腳本之家 閱讀:134 作者:geekarl 欄目:web開發(fā)

針對Vue文檔中部分大家可能不會去研讀的內(nèi)容,我做了個小總結(jié),作為有經(jīng)驗者的快餐,不是特別適合初學(xué)者,可能有不妥之處,希望大家多提建議。

節(jié)省代碼量的mixin

mixin概念:組件級可復(fù)用邏輯,包括數(shù)據(jù)變量/生命周期鉤子/公共方法,從而在混入的組件中可以直接使用,不用重復(fù)寫冗余邏輯(類似繼承)

使用方法:

在某一公共文件夾pub下創(chuàng)建mixin文件夾,其下創(chuàng)建mixinTest.js

const mixinTest = {
  created() {
    console.log(`components ${this.name} created`)
  },
  methods: {
    hello() {
      console.log('mixin method hello')
    }
  }
}
export default mixinTest

在組件中引用剛才的公共混入文件并使用

import mixinTest from '../pub/mixin/mixinTest.js'
export default {
  data() {
    return {
      name: 'hello'
    }
  },
  mixins: [mixinTest],
  methods: {
    useMixin() {
      this.hello()
    }
  }
}

ps: 若是使用Vue.mixin()這個方法,則會影響之后創(chuàng)建的所有Vue示例,慎用!

注意mixin的幾個特性:

  1. 混入的數(shù)據(jù)變量是淺合并,沖突時以組件內(nèi)的數(shù)據(jù)優(yōu)先(對象里面的自定義變量)
  2. 混入的生命周期函數(shù)內(nèi)的邏輯會與組件內(nèi)定義的生命周期函數(shù)邏輯進行合并,并且先執(zhí)行(created/mounted/destroy)
  3. 混入的值為對象的選項,會混合成一個對象,沖突后也是以組件內(nèi)鍵名優(yōu)先(data/method/components/directives)

slot內(nèi)容分發(fā)

slot概念引入:Vue跟React在寫法上的不同就在于組件與子組件內(nèi)部元素的組織上,在組件里面沒有children元素供我們訪問和展現(xiàn)(暫不考慮render函數(shù)),取而代之的API是slot

使用場景定義:

  1. 自定義的子組件里面有嵌套的HTML或者其他自定義的標(biāo)簽組件
  2. 這個自定義的子組件是寫在父組件里面,嵌套的東西也放在父組件里面
  3. 通過在子組件的模板里面使用<slot></slot>標(biāo)簽,從而達到渲染寫在父組件里的嵌套標(biāo)簽的效果
  4. 本質(zhì)是把父組件放在子組件里的內(nèi)容,插到了子組件的位置,多個標(biāo)簽也會一起被插入
<template>
  <div id="app"> 
    <self-component> <!--self-component表示自定義的組件-->
      <span>12345</span> <!--父組件里的嵌套標(biāo)簽--> 
    </self-component> 
  </div> 
</template>
<script>
export default {
  components: [selfComponent]
}
</script>

<!--self-component的組件模板-->
<template>
  <div>
    <button><slot></slot></button>
  </div>
</template>
<script>
export default {
  // 只有子組件的模板里面有slot標(biāo)簽,才能取到寫在自定義組件里面的標(biāo)簽的渲染引用
}
</script>

slot特性的進階兩點:

slot插入內(nèi)容的編譯作用域:被分發(fā)的內(nèi)容的作用域,根據(jù)其所在模板決定

  1. 具體內(nèi)容寫的位置,決定了編譯的作用域(大部分情況都是在父組件作用域下)
  2. 2.1.0+新增作用域插槽,從而可以把子組件的屬性暴露給父組件中寫在子組件內(nèi)的內(nèi)容使用
  3. 子組件中的slot標(biāo)簽可以直接寫自定義屬性,然后父組件寫在slot中的標(biāo)簽加上slot-scope屬性
<!-- 父組件模板 -->
<child :items="items">
 <!-- 作用域插槽也可以是具名的 -->
 <li slot="item" slot-scope="props" class="my-fancy-item">{{ props.text }}</li>
</child>

<!-- 子組件模板 -->
<ul>
 <slot name="item" v-for="item in items" :text="item.text">
  <!-- 這里寫當(dāng)父組件引用子組件但沒寫內(nèi)部內(nèi)容時展示的東東 -->
 </slot>
</ul>

slot的name屬性來指定標(biāo)簽插入的位置,也就是文檔里面的具名插槽(這個官方文檔說的明白)

  1. 在子組件的模板里面寫的slot有個name屬性(<slot name="foo"></slot>)
  2. 在父組件中寫子組件里面的插槽內(nèi)容,指明slot屬性(<p slot="foo">123</p>)
  3. 父組件的內(nèi)容就會對應(yīng)slot==name放到正確的位置
  4. 沒有指明slot屬性的就會默認(rèn)放到匿名插槽的位置上

動態(tài)組件

動態(tài)組件這個特性,很多人寫的Vue項目也不少,但也沒用到過這個,有必要多說幾句

動態(tài)組件適用情況:

  1. 單頁應(yīng)用,部分組件的切換不涉及路由,只是頁面有一塊區(qū)域的組件要變更
  2. 變更的組件參數(shù)定義上是一致的,比如都是對話框,要傳一個對象進去,但對象里面的數(shù)據(jù)結(jié)構(gòu)不同
  3. 通過使用component的is屬性,避免在template中的冗余組件代碼,避免多個v-if模板代碼更加整潔

使用的方法(借鑒文檔):

<keep-alive>
  <component v-bind:is="currentView">
  <!-- 組件在 vm.currentview (對應(yīng)組件名稱)變化時改變! -->
  <!-- 非活動組件將被緩存!可以保留它的狀態(tài)或避免重新渲染 -->
  </component>
</keep-alive>

注意點:

  1. 動態(tài)切換的組件都要引入到父組件中,渲染是動態(tài)的,但引入不是。
  2. <keep-alive>包裹動態(tài)組件時,會緩存不活動的組件實例,提高性能,避免重復(fù)渲染(keep-alive不會渲染額外DOM結(jié)構(gòu))
  3. <keep-alive>有include和exclude這兩個屬性,用于指定緩存和不緩存的組件(傳入字符串/數(shù)組/正則)
  4. 另一種避免重新渲染的方法是為標(biāo)簽增加屬性v-once,用于緩存大量的靜態(tài)內(nèi)容,避免重復(fù)渲染。

ps:<keep-alive>不會在函數(shù)式組件中正常工作,因為它們沒有緩存實例。

動畫與過渡

其實很多前端工程師第一次用Vue的動畫和過渡都是通過庫組件來做到的,所以對這塊沒怎么深挖,各種過渡特效和按鈕動畫就跑起來了,現(xiàn)在就看下文檔,補補課

前端實現(xiàn)動畫的基本方法分為三種種:css3的過渡和keyframe/javascript操縱dom/使用webgl或者canvas來獨立實現(xiàn),其中第三種是作為展示動畫,與交互結(jié)合較少,而Vue作為一個框架,其支持動畫基是從前兩種入手的,從官方文檔提到的四種支持就可以看出這一點。不過官方文檔是從DOM過渡和狀態(tài)過渡兩個方面來講解,前者是DOM的消失和出現(xiàn)的動畫等屬性的變化,后者是頁面上某些值的變化。

DOM屬性的改變

若是單個元素/組件的顯隱,在組件外面包裹一層<transition></transition>,而后選擇是css過渡還是javascript過渡

CSS過渡:

  1. vue提供了六個樣式后綴,本質(zhì)是在dom過渡的過程中動態(tài)地添加和刪除對應(yīng)的className。(-[enter|leave]-?[active|to]?)
  2. 如果用css庫來輔助開發(fā),可以在transiton這個標(biāo)簽上定義自定義過渡類名,也是六個屬性。([enter|leave]-?[active|to]?-class)
  3. 常見的一種效果是元素首次渲染的動畫,如懶加載圖片飛入,這個時候要在transiton標(biāo)簽上加上appear,另有三個屬性可指定(appear-?[to|active]?-class)
<!-- 每種CSS動畫庫對應(yīng)的class命名規(guī)則可能不同,所以根據(jù)不同庫要自己寫,以animate.css為例 -->
<transition
  name="custom-classes-transition"
  enter-active-class="animated tada"
  leave-active-class="animated bounceOutRight"
  :duration="{ enter: 500, leave: 800 }"
>...</transition>
<!-- duration屬性可以傳一個對象,定制進入和移出的持續(xù)時間-->

JS過渡:

  1. 因為現(xiàn)在很多動畫庫需要工程師調(diào)用庫提供的函數(shù),把dom元素傳入進行處理,這個時候需要這種方式
  2. 通過在transiton這個標(biāo)簽上添加監(jiān)聽事件,共8個([before|after]?-?[enter|leave]-?[cancelled]?)
  3. 監(jiān)聽事件的回調(diào)函數(shù)的第一個參數(shù)都是el,為過渡的dom元素,在enter和leave這兩個還會傳入done作為第二個參數(shù)
  4. 元素首次渲染的動畫,可以指定的監(jiān)聽事件有4個([before|after]?-?appear和appear-cancelled)
<template>
  <transition v-bind:css="false"
  v-on:before-enter="beforeEnter" v-on:enter="enter"
  v-on:leave="leave" v-on:leave-cancelled="leaveCancelled">
    <!-- 對于僅使用 JavaScript 過渡的元素添加 v-bind:css="false",Vue 會跳過 CSS 的檢測 -->
  </transition>
</template>
<script>
methods: { // 以Velocity庫為例
  beforeEnter: function (el) {/*...*/},
 // 此回調(diào)函數(shù)是可選項的設(shè)置
 enter: function (el, done) {
  // Velocity(el, { opacity: 1, fontSize: '1.4em' }, { duration: 300 })
  done() //回調(diào)函數(shù) done 是必須的。否則,它們會被同步調(diào)用。
 },
 leave: function (el, done) {
  // Velocity(el, { translateX: '15px', rotateZ: '50deg' }, { duration: 600 })
  done()
 },
 leaveCancelled: function (el) {/*...*/}
}
</script>

多元素過渡其實就是一句話:照常使用v-if/v-else的同時對同一種標(biāo)簽加上key來標(biāo)識

Vue對于這種多元素動畫有隊列上的處理,這就是transiton這個標(biāo)簽上的mode屬性,通過指定(in-out|out-in)模式,實現(xiàn)消失和出現(xiàn)動畫的隊列效果,讓動畫更加自然。

<transition name="fade" mode="out-in">
 <!-- ... the buttons ... -->
</transition>

多組件過渡也是一句話:用上一節(jié)提到的動態(tài)組件,即可完成。

針對列表過渡,其本質(zhì)仍是多個元素的同時過渡,不過列表大部分是通過數(shù)組動態(tài)渲染的,因此有獨特的地方,不過整體的動畫思路不變。具體有以下幾點

  1. 使用transitoin-group這個組件,其需要渲染為一個真實元素,可以通過tag這個屬性來指定。
  2. 列表的每個元素需要提供key屬性
  3. 使用CSS過渡的話,要考慮到列表內(nèi)容變化過程中,存在相關(guān)元素的定位改變,如果要讓定位是平滑過渡的動畫,要另外一個v-move屬性。 這個屬性是通過設(shè)置一個css類的樣式,來將創(chuàng)建元素在定位變化時的過渡,Vue內(nèi)部是通過FLIP實現(xiàn)了一個動畫隊列,只要注意一點就是過渡元素不能設(shè)置為display:inline,這里需要文檔上的代碼做一個簡短的demo:(其實通過在li上設(shè)置過渡transition屬性也可以實現(xiàn)v-move的效果)
<template>
  <button v-on:click="shuffle">Shuffle</button>
  <transition-group name="flip-list" tag="ul">
    <li v-for="item in items" v-bind:key="item">{{ item }}</li>
  </transition-group>
</template>
<script>
import _ from 'lodash';
export default {
  data() {
    return {
      items: [1,2,3,4,5,6,7,8,9]
    }
  },
  methods: {
    shuffle: function () {
      this.items = _.shuffle(this.items)
    }
  }
}
</script>
<style lang="css">
.flip-list-move {
 transition: transform 1s;
}
</style>

數(shù)值和屬性動態(tài)變化

這一部分的動畫主要是針對數(shù)據(jù)元素本身的特效,比如數(shù)字的增減,顏色的過渡過程控制,svg動畫的實現(xiàn)等,其本質(zhì)都是數(shù)字/文本的變化。 我自己總結(jié)就是:通過利用Vue的響應(yīng)式系統(tǒng),把數(shù)字的變化通過外部庫把DOM上對應(yīng)數(shù)值的變化做出連續(xù)的效果,如1->100是個數(shù)字遞增的連續(xù)過程,黑色->紅色的過程。官方文檔主要是用幾個示例代碼來說明,其本質(zhì)步驟如下:

  1. 在頁面上通過input的雙向綁定修改某一變量a,還有一個處理dom上的過渡效果的變量b
  2. 這個數(shù)據(jù)被watcher綁定(watch對象中某個屬性是這個變量a),觸發(fā)邏輯
  3. 在watcher里面的邏輯就是通過外部過渡庫,指定初始值b和最終值a,是把b的值最后改為a
  4. DOM上綁定的變量就是b,如果某些復(fù)雜情況可能是基于b的計算屬性,從而把b的變化過程展現(xiàn)出來

上面這個思路走一遍下來就完成了一個單元級別的動畫效果,這種類似的流程其實是很常見的需求,所以有必要把這個過程封裝成一個組件,只暴露要過渡的值作為入口,每次改變這個值都是一個動畫過渡效果。組件封裝需要在上面四個步驟的基礎(chǔ)上添加mounted生命周期規(guī)定初始值即可,同時原來的兩個值a/b在組件里面作為一個值,可以用watch對象中的newValue和oldValue作為區(qū)分。   至于最后的SVG,其本質(zhì)也是數(shù)字的過渡,只不過里面涉及的狀態(tài)變量更多,代碼更長而已,不過純前端頁面這種需求倒還是不多的,不過作為愛好倒可以鼓搗一些好玩的小demo,不過肯定需要設(shè)計師的參與,要不那些參數(shù)可不好調(diào)出來吶。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持億速云。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI