Vue音樂播放器學習筆記(5) - mixin混合 + ( vm.$options ) + ( Vue.extend( options ) ) + ( Vue.directive全局自定義指令 和 directives局部自定義指令 ) + ( 動態組件 和 is屬性 )

[一] Vue mixins(混合)

(一) 不同組件引用mixin

mixin.js       



export const mixinUse = {
  data() {
    return {
      show: false
    }
  },
  created() {
    this.go()
  },
  methods: {
    go() {
      this.show = !this.show
    }
  },
  mounted() {
    console.log('這是mixin中的mounted()鉤子函數,先執行')
  }
}
-----------------------------------------------------------------------------------
hellowWorld.vue    主頁面,引用 modelA組件 和 mixin.js




<template>
  <div>
    這是主頁面
    <modelA v-show="show"></modelA>
    <div @click="go">點擊顯示</div>
  </div>
</template>

<script>
  import ModelA from 'components/modela/modela.vue'
  import {mixinUse} from '@/mixin.js'

  export default {
    mixins: [mixinUse],
    components: {
      ModelA
    },
    mounted() {
      console.log('這是主頁面的mounted()鉤子函數,后執行')
    }
  }
</script>-----------------------------------------------------------------------------------
modelA組件       引用 modelB組件 和 mixin.js




<template>
  <div class="modelA">
    這是model A的內容AAAAAAAAAAA
    <modelB v-show="!show"></modelB>
    <div @click="go" style="margin-top: 20px">點擊-顯示model'B</div>
  </div>
</template>


<script type="text/ecmascript-6">
  import ModelB from 'components/modelb/modelb.vue'
  import {mixinUse} from '@/mixin.js'

  export default {
    mixins: [mixinUse],
    components: {
      ModelB
    }
  }
</script>



 

(1) 合并 (組件和mixin中相同生命周期鉤子函數的執行順序)

  • 當我們在組件上應用Mixin的時候,有可能組件與Mixin中都定義了相同的生命周期鉤子,這時候鉤子的執行順序的問題凸顯了出來。默認Mixin上會首先被注冊,組件上的接著注冊,這樣我們就可以在組件中按需要重寫Mixin中的語句。組件擁有最終發言權。

(2) 沖突 (組件和mixin中都有同名的method方法時,mixin中的方法被重寫)

//mixin


const hi = {
  methods: {
    sayHello: function() {
      console.log('hello from mixin!')
    }
  },
  mounted() {
    this.sayHello()
  }
}

-----------------------------------------------------------------------------
//vue instance or component



new Vue({
  el: '#app',
  mixins: [hi],
  methods: {
    sayHello: function() {
      console.log('hello from Vue instance!')
    }
  },
  mounted() {
    this.sayHello()
  }
})
 
// Output in console
> hello from Vue instance!
> hello from Vue instance!

你可能已經注意到這有兩個console.log而不是一個——

這是因為第一個函數被調用時,沒有被銷毀,它只是被重寫了。我們在這里調用了兩次sayHello()函數。


(二) 全局mixin(使用Vue.mixin({xxx})方法)

  • 全局Mixin被注冊到了每個單一組件上。因此,它們的使用場景極其有限并且在使用的時候我們需要非常小心。一個我能想到的用途就是類似于插件,你需要賦予它訪問所有東西的權限。但即使在這種情況下,我也對你正在做事情的充滿警惕,尤其當你打算為應用增加通能的時候,這樣做可能對你來說是個潘多拉的盒子。

Vue.mixin({
  mounted() {
    console.log('hello from mixin!')
  }
})
 
new Vue({
  ...
})

(1) 合并 (全局mixin與組件內mixin 中的生命周期鉤子函數的執行順序)

  • 每次創建組件時,全局mixin都會添加到組件實例中,如果全局mixin和組件內mixin有同名的鉤子函數,鉤子函數都會執行,并且先執行先執行全局后執行組件內。

(2) 沖突 (全局mixin與組件內mixin 中的非鉤子函數沖突時,全局mixin被重寫)

  • 對于非鉤子函數,組件實例的對象屬性,組件內的會覆蓋全局的。

(3) 實現全局mixin的鉤子函數在指定組件中執行/不執行

  • 在時機使用過程中,如果希望鉤子函數中的代碼只在指定的組件中執行,可以使用組件自定義options來實現( vm.$options )
main.js中的全局mixin 


Vue.mixin({
  created() {
    if (this.$options['isMixin']) {    // 如果組件中存在isMixin的自定義選項,就往下執行
      console.log('如果組件isMixin選項存在就輸出這段文字')
    }
  }
})

---------------------------------------------------------------------------
helloWorld.vue組件


  export default {
    isMixin:{
      a:true   // 這里可以隨便寫,只要ismixin存在即可
    },
    created() {
      console.log('組件中的console.log')
    },
    mounted() {
      console.log('這是主頁面的mounted()生命周期鉤子函數,后執行')
    }
  }
</script>


輸出結果:
main.js?1c90:19如果組件isMixin選項存在就輸出這段文字
HelloWorld.vue?3c12:24組件中的console.log
HelloWorld.vue?3c12:27這是主頁面的mounted()生命周期鉤子函數,后執行

總結:Vue混合策略

vue ( mixin ) 和 組件 有相同的生命周期鉤子函數時候,執行順序是:先執行mixin再組件

vue ( mixin ) 和 組件 有相同非鉤子函數時候,執行組件中的非鉤子函數,mixin都被重寫

對于鉤子函數,會添加到一個函數數組里,執行順序從前到后

對于組件的對象屬性(methods等),后面的會覆蓋前面的

最好不要用全局mixin


[二] vm.$options

  • 類型:Object
  • 詳細:用于當前 Vue 實例的初始化選項。需要在選項中包含自定義屬性時會有用處


new Vue({
  customOption: 'foo',      // customOption是實例的初始化選項
  created: function () {
    console.log(this.$options.customOption) // => 'foo'
  }
})

----------------------------------------------------------------------------------------

new Vue({
  el: '#app',
  router,
  template: '<App/>',
  components: {App},
  author: {
    name: 'wu',
    age: '27'
  },
  created() {
    console.log(this.$options.author, 'this.$options')  
         // => Object {name: "wu", age: "27"} "this.$options"
  }
})


[三] Vue.extend( options )

參數:
{Object} options
用法:
使用基礎 Vue 構造器,創建一個“子類”。參數是一個包含組件選項的對象。它的目的是創建一個Vue的子類并且返回相應的 constructor。
data 選項是特例,需要注意 - 在 Vue.extend() 中它必須是函數

[四] Vue.directive 自定義指令

(1)鉤子函數

指令定義函數提供了幾個鉤子函數 (可選):

  • bind:只調用一次,指令第一次綁定到元素時調用,用這個鉤子函數可以定義一個在綁定時執行一次的初始化動作。
  • inserted:被綁定元素插入父節點時調用 (父節點存在即可調用,不必存在于 document 中)。
  • update:所在組件的 VNode 更新時調用,但是可能發生在其孩子的 VNode 更新之前。指令的值可能發生了改變也可能沒有。但是你可以通過比較更新前后的值來忽略不必要的模板更新 (詳細的鉤子函數參數見下)。
  • componentUpdated:所在組件的 VNode 及其孩子的 VNode 全部更新時調用。
  • unbind:只調用一次,指令與元素解綁時調用。

(2)鉤子函數參數

  • el:指令所綁定的元素,可以用來直接操作 DOM 。
  • binding:一個對象,包含以下屬性:
    name:指令名,不包括 v- 前綴。
    value:指令的綁定值,例如:v-my-directive="1 + 1", value 的值是 2。
    oldValue:指令綁定的前一個值,僅在 update 和 componentUpdated 鉤子中可用。無論值是否改變都可用。
    expression:綁定值的字符串形式。例如 v-my-directive="1 + 1" ,expression 的值是 "1 + 1"。
    arg:傳給指令的參數。例如 v-my-directive:foo,arg 的值是 "foo"。
    modifiers:一個包含修飾符的對象。例如:v-my-directive.foo.bar, 修飾符對象 modifiers 的值是 { foo: true, bar: true }。
    vnode:Vue 編譯生成的虛擬節點,查閱 VNode API 了解更多詳情。
    oldVnode:上一個虛擬節點,僅在 update 和 componentUpdated 鉤子中可用。
全局自定義指令:Vue.directive('xx', { xx })
獲取焦點



// 注冊一個全局自定義指令 v-focus,作用:獲取焦點

Vue.directive('focus', {

    // inserted鉤子函數,作用:當綁定元素插入到 DOM 中
    // 鉤子函數參數: el綁定的元素,binding對象(包含name,value,arg等)

  inserted: function (el, binding) {  
    // 聚焦元素
    el.focus()
  }
})


使用: <input v-focus>


 // inserted鉤子函數:被綁定元素插入父節點時調用 (父節點存在即可調用,不必存在于document 中)。


-----------------------------------------------------------------------

/*簡單模式*/
Vue.directive('minLength',function(){
  /*在bind和update階段觸發*/
})


局部自定義指令:組件中接受一個 directives 的選項: (注意:這里是directives,是復數)
改變字體顏色


directives: {
  focus: {
    // 指令的定義---
    inserted: function (el, binding) {}
  }
}
--------------------------------------------------------------------------------------


  export default {
    directives: {   // 局部自定義指令,注意有s
      color: {    // v-name
        inserted: function(el, binding) {  // inserted鉤子函數,綁定元素插入DOM中時生效
          el.style = 'color:' + binding.value    // el指令綁定的元素,binding對象,有value等屬性
        }
      }
    },
    data() {
      return {
        model: '',
        showOrHide: true,
        color: 'red'
      }
    },
//    mixins: [mixinUse],
    components: {
      ModelA
    },
    isMixin: {
      a: true
    },
    created() {
      console.log('組件中的console.log')
    },
    mounted() {
      console.log('這是主頁面的mounted()生命周期鉤子函數,后執行')
    },
    methods: {
      xianShi() {
        this.showOrHide = !this.showOrHide
      }
    }
  }




使用: <div v-color="color">v-color指令,綁定元素內的顏色</div>

           data() {
             return {
               color: 'red'
            }


(3)注意:當使用路由并且使用keep-alive的時候,自定義指令(v-focus)在inserted等鉤子函數中使用獲得焦點的函數將失效,因為keep-alive會保存狀態,沒有重新加載,即el綁定的元素已經插入dom中,所以inserted失效,這時要使用keep-alive對應的生命周期鉤子函數( activated ) ,keep-alive 組件激活時調用。( deactivated 停用時調用 )


   activated() {
      this.$refs.input2.focus()
    }

[5] 動態組件 和 is屬性

  • 通過使用保留的 <component> 元素,動態地綁定到它的 is 特性,我們讓多個組件可以使用同一個掛載點,并動態切換:
  • is屬性 : 用于動態組件且基于 DOM 內模板的限制來工作。
tab切換


<template>
  <div class="table">
    <div>這是tab組件頁面</div>
    <div>
      <div @click="go('Tab1')">選項一</div>
      <div @click="go('Tab2')">選項二</div>
    </div>
    <component :is="currentTab"></component>    // <component>元素綁定is,讓組件共用一個掛載點
  </div>
</template>

<script type="text/ecmascript-6">
  import Tab1 from './tab1.vue'
  import Tab2 from './tab2.vue'
  export default {
    data() {
      return {
        currentTab: 'Tab1'
      }
    },
    components: {
      Tab1,
      Tab2
    },
    methods: {
      go(tab) {
        this.currentTab = tab
      }
    }
  }
</script>
效果圖
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 這篇筆記主要包含 Vue 2 不同于 Vue 1 或者特有的內容,還有我對于 Vue 1.0 印象不深的內容。關于...
    云之外閱讀 5,082評論 0 29
  • 1.安裝 可以簡單地在頁面引入Vue.js作為獨立版本,Vue即被注冊為全局變量,可以在頁面使用了。 如果希望搭建...
    Awey閱讀 11,108評論 4 129
  • Vue 實例 屬性和方法 每個 Vue 實例都會代理其 data 對象里所有的屬性:var data = { a:...
    云之外閱讀 2,245評論 0 6
  • 文/孤鳥差魚 難得有人欣賞 你的乖張 別失了模樣
    孤鳥差魚閱讀 169評論 6 3
  • 一 我愿與你泛舟于大海 要是海風把我們的船吹翻 我們就遨游海底 做一條歡快的魚兒 二 我給你搬個板凳 你坐在門前,...
    暮雨清風閱讀 312評論 50 16