天天看點

Vue的學習總結自測(四)——v-model的原理,元件data為什麼是一個函數,keep-alive,父元件監聽子元件的生命周期11、父元件監聽子元件的生命周期12.keep-alive13、元件中 data 為什麼是一個函數14、v-model 的原理?

繼上一篇:

Vue的學習總結自測(三)——computed 和 watch 的差別、vue不能檢測到數組、對象的變動

本文目錄:

  • 父元件監聽子元件的生命周期
  • keep-alive
  • 元件中 data 為什麼是一個函數?
  • v-model 的原理

11、父元件監聽子元件的生命周期

比如有父元件 Parent 和子元件 Child,如果父元件監聽到子元件挂載 mounted 就做一些邏輯處理,可以通過以下寫法實作:

// Parent.vue
<Child @mounted="doSomething"/>

// Child.vue
mounted() {
  this.$emit("mounted");
}
           

以上需要手動通過 $emit 觸發父元件的事件,更簡單的方式可以在父元件引用子元件時通過 @hook 來監聽即可,如下所示:

//  Parent.vue
<Child @hook:mounted="doSomething" ></Child>

doSomething() {
   console.log('父元件監聽到 mounted 鈎子函數 ...');
},

//  Child.vue
mounted(){
   console.log('子元件觸發 mounted 鈎子函數 ...');
},    

// 以上輸出順序為:
// 子元件觸發 mounted 鈎子函數 ...
// 父元件監聽到 mounted 鈎子函數 ...
           

當然 @hook 方法不僅僅是可以監聽 mounted,其它的生命周期事件,例如:created,updated 等都可以監聽。

12.keep-alive

keep-alive 是 Vue 内置的一個元件,可以使被包含的元件保留狀态,避免重新渲染 ,其有以下特性:

  • 一般結合路由和動态元件一起使用,用于緩存元件;
  • 提供 include 和 exclude 屬性,兩者都支援字元串或正規表達式, include 表示隻有名稱比對的元件會被緩存,exclude 表示任何名稱比對的元件都不會被緩存 ,其中 exclude 的優先級比 include 高;
  • 對應兩個鈎子函數 activated 和 deactivated ,當元件被激活時,觸發鈎子函數 activated,當元件被移除時,觸發鈎子函數 deactivated。
<keep-alive>
    <loading></loading>
</keep-laive>
           
被keep-alive包裹的動态元件或router-view會緩存不活動的執行個體,再次被調用這些被緩存的執行個體會被再次複用,對于我們的某些不是需要實時更新的頁面來說大大減少了性能上的消耗,不需要再次發送HTTP請求,但是同樣也存在一個問題就是被keep-alive包裹的元件我們請求擷取的資料不會再重新渲染頁面,這也就出現了例如我們使用動态路由做比對的話頁面隻會保持第一次請求資料的渲染結果,是以需要我們在特定的情況下強制重新整理某些元件
           

1.利用include、exclude屬性

<keep-alive include="bookLists,bookLists">
      <router-view></router-view>
</keep-alive>
<keep-alive exclude="indexLists">
      <router-view></router-view>
</keep-alive>
           

2.官方提出的解決方案響應路由參數的變化

3.利用meta屬性

export default[
 {
  path:'/',
  name:'home',
  components:Home,
  meta:{
    keepAlive:true //需要被緩存的元件
 },
 {
  path:'/book',
  name:'book',
  components:Book,
  meta:{
     keepAlive:false //不需要被緩存的元件
 } 
]
           
<keep-alive>
  <router-view v-if="this.$route.meta.keepAlive"></router-view>
  <!--這裡是會被緩存的元件-->
</keep-alive>
<keep-alive v-if="!this.$router.meta.keepAlive"></keep-alive>
<!--這裡是不會被緩存的元件-->
           

13、元件中 data 為什麼是一個函數

為什麼元件中的 data 必須是一個函數,然後 return 一個對象,而 new Vue 執行個體裡,data 可以直接是一個對象?
// data
data() {
  return {
    message: "子元件",
    childName:this.name
  }
}

// new Vue
new Vue({
  el: '#app',
  router,
  template: '<App/>',
  components: {App}
})
           

因為元件是用來複用的,且 JS 裡對象是引用關系。

  • 如果元件中 data 是一個對象,那麼這樣作用域沒有隔離,子元件中的 data 屬性值會互相影響。
  • 如果元件中 data 選項是一個函數,那麼每個執行個體可以維護一份被傳回對象的獨立的拷貝,元件執行個體之間的 data 屬性值不會互相影響;而 new Vue 的執行個體,是不會被複用的,是以不存在引用對象的問題。

14、v-model 的原理?

我們在 vue 項目中主要使用 v-model 指令在表單 input、textarea、select 等元素上建立雙向資料綁定,我們知道 v-model 本質上不過是文法糖,v-model 在内部為不同的輸入元素使用不同的屬性并抛出不同的事件:

  • text和textarea元素使用value屬性和input時間;
  • checkbox和radio使用checked屬性和change事件;
  • select字段将value作為prop并且将change作為事件
以input表單元素為例:
<input v-model = 'something'>
相當于
<input v-bind:value='something' v-on:input='something = $event.target.value'>
           

如果在自定義元件中,v-model 預設會利用名為 value 的 prop 和名為 input 的事件,如下所示:

父元件:
<ModelChild v-model="message"></ModelChild>

子元件:
<div>{{value}}</div>

props:{
    value: String
},
methods: {
  test1(){
     this.$emit('input', '小紅')
  },
},
           

繼續閱讀