間歇性筆記--Vue組件間通訊傳值的各類方式

組件間通訊傳值的各類方式與場景

通常狀況下,組件間的通訊傳值分爲三種狀況:vue

  1. 父組件向子組件(跨級)通訊傳值;
  2. 子組件向父組件(跨級)通訊傳值;
  3. 兄弟組件間通訊傳值;

父組件向子組件(跨級)通訊傳值

  • 使用prop傳值,子組件使用props接受數據vuex

    parent.vue
        //部分代碼省略---
        <child 
            :prop='data'>
        </child>
    
        child.vue
        props:['data'],
    複製代碼

    使用場景:
    對子組件進行傳值,不會對子組件進行操做;
    注意:數組

    1. 當綁定靜態數據時,最好也使用v-bind,否則Vue會所有當成字符串處理(字符串傳遞除外);
    2. 可使用v-bind='propObj'的方式,propObj是一個有屬性的對象;
    3. 可使用v-bind='$props'的方式,將父組件的props傳值給子組件;
    4. 單向數據流,不容許在子組件中修改prop;
    5. 當但願prop在子組件能夠當作本地data使用時,能夠在data中複製localData=this.data。可是若prop爲數組或者對象時,需使用深拷貝;
    6. 當但願在子組件對prop進行轉換時,可使用計算屬性轉換。可是若prop爲數組或者對象時,需使用深拷貝;
      computed:{
              myDataTrim(){
                  return this.myData.trim();
              }
          }
      複製代碼

    7.子組件中,style/class不容許接收;瀏覽器

  • 插槽
    能夠經過插槽的方式,將父組件的內容傳遞到子組件,能夠在子組件中設置默認值。bash

    parent.vue
        //部分代碼省略---
        <child>
            hello
        </child>
    
        child.vue
        <div>
            <slot>
                默認值
            </slot>
        </div>
        //渲染結果:<div>hello</div>
    複製代碼

    使用場景:
    傳遞給子組件,在子組件特定的位置渲染展現出來。傳遞的內容甚至能夠爲DOM元素、組件等。
    注意:ide

    1. 使用具名插槽能夠指定父組件內容傳遞的位置;
      parent.vue
          //部分代碼省略---
          <child>
              <template v-slot:slotName>
                  hello
              </template>
              //默承認以使用兩種方式
              <template v-slot:default>
                  world
              </template>
              //or
              world
          </child>
      
          child.vue
          <div>
              <slot name='slotName'>
                  默認值1
              </slot>
              <div>
                  <slot>
                      默認值2
                  </slot>
              </div>
          </div>
      複製代碼
    2. v-slot通常寫在template中;
    3. 縮寫。v-slot --> #,特殊狀況:默認插槽#default;
  • 父組件獲取子組件實例(ref)
    在父組件中調用子組件時,設置ref屬性,而後就能夠經過this.$refs[設置的值]獲取子組件的實例。函數

    parent.vue
        //部分代碼省略---
        <child ref='childRef'>
        </child>
        //methods
        getChildData(){
            let data=this.$refs.childRef.data;
        }
    複製代碼

    使用場景:
    當父組件想獲取子組件的數據、方法時,能夠經過這種方式進行獲取數據、調用方法;
    注意:學習

    1. ref設置在DOM元素上時,獲取的是DOM元素;
    2. $refs是一個對象,收集全部設置過ref的DOM元素或組件實例;
  • 非prop特性(attrs)  
  當父組件設置的特性在子組件中沒有被接收時,會收集在`attrs`對象中;
    使用場景:ui

    1. 當某些特性不想直接綁定在根元素上,能夠經過v-bind:$attrs綁定在特定的元素上;
    2. 能夠將這些特性經過v-bind:$attrs傳遞給子組件的子組件---跨級傳值; 注意:
    3. 子組件中設置inheritAttrs:false,可使非prop的特性不綁定在根元素上;
    4. style/class沒法取消綁定;
  • children  
  能夠獲取子組件的實例,進而能夠獲取/設置子組件數據,也能夠調用子組件的方法;  
  能夠經過`children[0].$children`跨級獲取組件的實例;
    使用場景:this

    1. 獲取子組件的實例;
    2. 當組件層級不是很深時,能夠經過這種方式跨級獲取組件實例; 注意:
    3. 不適應組件層級較深的狀況;

子組件向父組件(跨級)通訊傳值

  • $emit(自定義事件名[,...param])
    父組件綁定自定義組件,子組件中調用; 傳遞參數能夠爲零個或者多個;
    parent.vue
        //部分代碼省略---
        <child
            @event1='handMethod()'>
        </child>
    
        child.vue
        methods:{
            setparent(){
                this.$emit('handMethod');
            }
        }
    複製代碼
    使用場景:
    通常狀況下,子組件調用父組件方法的方法;
  • 插槽prop
    在子組件中的slot上v-bind進行綁定,這樣就能夠經過v-slot:slotName:props的方法接收數據了,全部的插槽prop都接收在一個對象中;
    parent.vue
        //部分代碼省略---
        <child>
            <template v-slot:slot1='data'>
                data.data
            </template>
        </child>
    
        child.vue
        <slot name ='slot1' :data='data'></slot>
    複製代碼
    使用場景:
    當組件內部使用了循環,可是又想讓不一樣的數據有不一樣的展示方式時使用;
  • 組件上使用v-model
    實現數據的"雙向綁定";
    在父組件使用v-model綁定須要進行"雙向綁定"的數據,在子組件能夠經過model:{}進行設置v-model綁定的prop和事件名,而後能夠在須要調用的地方調用;
    parent.vue
        //部分代碼省略---
        <child v-model='data'>
        </child>
    
        child.vue
        <div>
            <input 
                type='text'
                :value='data'
                @input="$emit('customEvent', $event.target.value)">
        </div>
        export default {
            model:{
                prop:'data',
                event:'customEvent',
            },
            props:[data]
        }
    複製代碼
    使用場景:
    通常在須要父子組件的數據須要進行"雙向綁定"的狀況下,進行使用;
    注意:
    1. 這是一個語法糖,並非真正意義上的雙向綁定,在子組件中,讓父組件綁定一個prop以及一個自定義事件;
    //前面的例子
        <child v-model='data'>
        </child>
        or 
        <child 
            :data='data'
            @customEvent='data=$event'
            >
        </child>
    複製代碼
  • .sync---也是語法糖
    當子組件向修改一個prop時,能夠經過修改父組件的數據,從而達到修改的目的;
    parent.vue
        //部分代碼省略---
        <child :title.sync='title'>
        </child>
    
        child.vue
        this.$emit('unpdate:title',newData);
    複製代碼
    使用場景:
    子組件想修改prop的值時;
    注意:
    1. 這也是一個語法糖。讓父組件綁定一個prop以及一個自定義事件---update:[prop的名字];
    parent.vue
        //部分代碼省略---
        <child 
            :title='title'
            @update:title='title=$event'>
        </child>
    複製代碼
  • listeners  
  一個對象。包含了父做用域中的 (不含 .native 修飾器的) v-on 事件監聽器;  
  能夠經過`v-on="listeners"`,這樣能夠跨級調用祖先的方法;
    使用場景:
    1. 能夠在子組件中對父組件的方法進行調用;
    2. 能夠達到跨級通訊的功能;
  • parent  
  能夠獲取父組件的實例,進而能夠獲取/設置父組件數據,也能夠調用父組件的方法;  
  能夠經過`parent[0].$parent`跨級獲取組件的實例;
    使用場景:
    1. 獲取父組件的實例;
    2. 當組件層級不是很深時,能夠經過這種方式跨級獲取組件實例; 注意:
    3. 不適應組件層級較深的狀況;

$attrs$listeners

能夠在子組件中再經過v-bind:$attrs以及v-on="$listeners"的方式進行跨級的通訊傳值;
好比能夠實現.syncv-model的功能(須要最初傳入的組件配合);

兄弟組件以及跨多級組件間傳值

  1. vuex 使用的很少,並且相關的內容挺多的。等有空詳細看看再總結一下。官方文檔
  2. eventBus 建一個空的Vue實例做爲中央事件總線; 進行將其定義在全局;
    let bus = new Vue();
    //一個組件中綁定
    bus.$on('evnet1',()=>{
    
    });
    組件銷燬前
    beforeDestroy(){
        bus.$off('evnet1');
    }
    //另一個組件中調用
    bus.$emit('evnet1'[,...param]);
    複製代碼
  3. 數據存儲在瀏覽器;---騷操做
  4. 經過路由傳值; 在created鉤子函數中,獲取$route的值,進行相應的操做。

後記

對一些經常使用的組件間通訊傳值方法的使用與場景的理解,理解的比較粗略。後續可能會對Vuex以及provide/inject等方法進行一些學習---看狀況而定。

相關文章
相關標籤/搜索