Vue的自定義組件、自定義指令、自定義事件、組件通信


1. 自定義組件( 插件 )

案例: 封裝一個 Loading 組件
Loading是用來做什么的?
基於用戶體驗
loading使用方式很多

  1. 第三方的ui庫/組件庫
  2. 自定義封裝
    1. 過程:
    2. 創建一個目錄文件夾,稱之為Loading
    3. 在loading中創建一個叫做component目錄,用來放模板
    4. 在Loading目錄下創建一個index.js
      import Vue from 'vue' import tpl from './component/index.html' const Loading = { // 自定義封裝組件,這個loading對象中必須有一個關鍵key install () {//一定要用install方法 Vue.component( 'Loading', { template: tpl }) } } export default Loading 
    1. 使用:

2. 自定義指令

  1. 指令是用來操作DOM

  2. 指令的使用形式: 屬性

  3. 自定義指令方式有兩種:

    • 全局注冊指令
      • Vue.directive( 指令的名稱, 指令的配置項 )
    • 局部注冊指令
      • directives: {
        ‘指令名稱’: 指令的配置項
        }
  4. 研究:

    • 指令的配置項提供了5個鈎子函數
    • 以及鈎子函數中的參數
      • console.log( ‘el’,el ) // el 指令綁定的元素
      • console.log( ‘binding’,binding ) // 指令的詳細信息
      • console.log( ‘vnode’, vnode ) // 當前綁定元素的信息
      • console.log( ‘oldVnode’,oldVnode ) // 上一個綁定元素的信息
  5. 案例: 打開網頁,input自動獲得焦點

 <div id="app"> <div class="box"> <button @click = 'flag = false'> 點擊 </button> <input type="text" v-if = "flag" v-focus.yyb v-model = "msg"> <input type="text" v-if = "flag" v-focus v-model = "msg"> </div> </div> 
 Vue.directive( 'focus',{//全局注冊指令 bind ( el,binding,vnode,oldVnode ) { //調用一次,指令一綁定在元素身上就會觸發 // console.log( 'bind focus' ) // console.log( 'el',el ) // el 指令綁定的元素 // console.log( 'binding',binding ) // 指令的詳細信息 // console.log( 'vnode', vnode ) // 當前綁定元素的信息 // console.log( 'oldVnode',oldVnode ) // 上一個綁定元素的信息 // el.style.background = 'red' }, inserted ( el,binding,vnode,oldVnode ) { // 當前綁定的元素插入父節點時調用 el.focus() if( binding.modifiers.yyb ){ el.style.color = 'green' }else{ el.style.color = 'red' } console.log( binding ) console.log( 'inserted ' ) }, update ( el, binding, vnode, oldVnode ) { // 當前指令綁定的元素發生改變 console.log( 'update' ) console.log( 'el',el ) // el 指令綁定的元素 console.log( 'binding',binding ) // 指令的詳細信息 console.log( 'vnode', vnode ) // 當前綁定元素的信息 console.log( 'oldVnode',oldVnode ) // 上一個綁定元素的信息 }, componentUpdated ( el,binding,vnode,oldVnode) { //當前綁定元素發生改變,或是子元素發生改變 console.log( 'componentUpdated' ) }, unbind ( el,binding,vnode,oldVnode) { // 組件銷毀時觸發 console.log( 'unbind' ) } }) new Vue({ el: '#app', data: { msg: 1000, flag: true }, directives: {//局部注冊指令 'focus': { bind () { }, inserted () { }, update () { }, componentUpdated () { }, unbind () { } } } }) 

3. 自定義的事件

  • v-on:click = ‘aa’
  • v-on:yyb = ‘aa’
  • v-on:before-enter: ‘’
  • v-on:aa = ‘fn’
  1. 自定義事件
    事件的發布
    事件的訂閱
    <div id="app"></div> 
     var vm = new Vue({ el: '#app' }) vm.$on(事件的名稱,事件的回調) //事件的發布 vm.$on('aa',function(){ alert( 'aa' ) }) // 事件的訂閱 // vm.$emit(事件的名稱) vm.$emit( 'aa' ) 
  2. 自定義事件的使用形式
    1. 組件生命周期中發布事件,通過某一個事件處理程序調用
  <div id="app"> <button @click = 'fn'> 點擊 </button> </div> 
   var vm = new Vue({ el: '#app', methods: { fn () { this.$emit('aa') } }, mounted () {//組件生命周期中發布事件,通過某一個事件處理程序調用 this.$on('aa',function(){ alert('aa') }) } }) 
  1. 綁定在組件身上 , 通過 v-on 綁定,可以實現子父組件通信

4. 組件通信 單項數據流 >9種

  1. 父子組件通信:父組件將自己的數據傳遞給子組件

    1. 子組件把父組件的數據通過屬性綁定的形式傳遞給自己,單項數據綁定

      <Son :aa = "money"></Son>

    2. 子組件在自己的配置項中通過 props 來接收這個屬性

        Vue.component('Son',{ template: '#son', // props: ['aa'], props: { // 屬性: 屬性的數據類型 給數據做屬性驗證,驗證數據類型 'aa': Number } }) 
    1. 這個屬性可以直接向全局變量一樣使用
      <p> 我老爸給了我:{{ aa }} 錢 </p> 
  2. 子父組件通信 :子組件將數據發送給父組件

    1. 方法1,自定義事件

      • 流程:
      1. 父組件中定義一個數據,然后在methods定義一個方法用來修改這個數據
        Vue.component('Father',{ template: '#father', data () { return { num: 0 } }, methods: { add ( val ) { console.log('add') this.num += val } } }) 
      1. 父組件通過自定義事件的形式,將父組件的一個方法傳遞給子組件

        <Son @aa = 'add'></Son>

      2. 子組件可以通過 this.$emit( 自定義事件名稱,參數1,參數2…) 來訂閱這個自定義事件

        Vue.component('Son', { template: '#son', data () { return { money:1000 } }, methods:{ give () { this.$emit('send',this.money)//子組件通過this.$emit來訂閱這個自定義事件 } } }) 
    2. 方法2,父組件將一個方法直接通過單向數據綁定的形式傳遞給子組件,子組件通過props接收,然后直接使用

    3. 方法3,父組件可以將一個對象型的數據傳遞給子組件,子組件修改了這個數據,父組件也同樣會修改

      • 這個形式違反了單向數據流,用的少
  3. 非父子組件通信

    1. 使用ref鏈綁定
      • ref不僅可以綁定組件,也可以綁定普通元素
      <!-- 舉例 --> <div id="app"> <Brother ref="brother"></Brother> <hr> <Sister ref="sister"></Sister> </div> <template id="brother"> <div> <h3>brother</h3> <button @click="give">傳遞數據</button> <p>brother的數據是:{{ money }}</p> </div> </template> <template id="sister"> <div> <h3>sister</h3> <p>sister的數據是:{{ money }}</p> </div> </template> 
     //非父子組件通信:通過ref鏈,ref鏈的綁定必須通過父組件來看 Vue.component ('Brother',{ template:'#brother', data () { return { money:1000 } }, methods:{ give (){ this.$parent.$refs.sister.money=this.money//通過父級找到子級 } } }) Vue.component ('Sister',{ template:'#sister', data (){ return { money:0 } } }) new Vue({ el: '#app', // mounted (){ // console.log(this) // } }) 
    1. 使用事件總線(bus總線)
    <!-- 舉例 --> <div id="app"> <Brother></Brother> <hr> <Sister></Sister> </div> <template id="brother"> <div> <h3>brother</h3> <button @click="give">傳遞</button> <p>brother的數據是:{{ money }}</p> </div> </template> <template id="sister"> <div> <h3>sister</h3> <p>sister的數據是:{{ money }}</p> </div> </template> 
      //非父子組件通信:事件總線,通過事件來做 // 事件的發布 $on(方法名稱,回調函數) // 事件的訂閱 $emit(方法名稱) //通過new Vue開辟另外一個實例,再用這個實例上面的$on和$emit方法 var bus = new Vue() Vue.component('Brother', { template: '#brother', data() { return { money: 1000 } }, methods: { give() { bus.$emit('give',this.money)//通過參數的形式傳遞數據 } } }) Vue.component('Sister', {//自己管理自己的數據 template: '#sister', data() { return { money: 0 } }, mounted () {//組建一創建就要有這個數據 bus.$on('give', (val) => {//這里要用箭頭函數,否則this會丟失 this.money += val }) } }) new Vue({ el: '#app', }) 
  4. 多組件的狀態共享 vuex( 目前不講, 改天)

  5. 多級組件通信 ( $attr 擴展 )

  6. vue-router ( 目前不講, 改天)

  7. 在一個組件當中,自己的數據由自己管理


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM