vue組件間傳值---下到上 篇

$emit:向父級傳值

單純從emit角度而言沒啥好說的

組件內(nèi)部$emit('someEvent')
使用組件時:<SomeComponent @someEvent="functionToHandleSomeEvnent">,注意這里不傳參,someEvent需保持一致
son組件

<template>
  <div class="son">
    <h1>這是son組件</h1>
    <span>來自father的值(fatherToSon1):{{fatherToSon1}}
      <button @click="changeFatherToSon1">使用emit</button>
    </span>
  </div>
</template>
<script>
  export default {
    name: "Son",
    data(){
      return {
        sonData:1
      }
    },
    props: {
      fatherToSon1: Number,
    },
    methods: {
      changeFatherToSon1() {
        this.$emit('changeFatherToSon1',2)
      }
    }
  }
</script>

father組件
在使用son組件的地方注冊一個和son組件中emit第一個參數(shù)一樣名字的函數(shù),簡單來說,就是son組件emit時的第一個參數(shù)要和使用son組件時@后面寫的保持一致。(@可以理解為給某一個類型的事件綁定一個處理函數(shù)@事件類型=處理該事件的函數(shù),像@click是vue幫我們定義好的,而@changeFatherToSon1是我們自己定義的)

<template>
  <div class="father">
    <h1>這是father組件</h1>
    <p>來自ancestors的值:{{provideFromAncestors}}</p>
    <button @click="showRef">$ref訪問子組件</button>
    <Son ref="son":fatherToSon1="fatherToSon1" @changeFatherToSon1="changeFatherToSon1"/>
    <Son/>
    <br>
  </div>
</template>

<script>
  import Son from './Son'
  export default {
    name: "Father",
    components: {
      Son
    },
    data() {
      return {
        fatherToSon1: 1,
      }
    },
    methods: {
      changeFatherToSon1(value) {
        this.fatherToSon1 = value
      },
    }
  }
</script>

$emit相關(guān)變種

1、$emit('update:value',someValue)

son組件

<template>
  <div class="son">
    <h1>這是son組件</h1>
    <span>
        來自father的值(fatherToSon2):{{fatherToSon2}}
        <button @click="changeFatherToSon2">使用update:value+@update:value</button>
    </span>
  </div>
</template>

<script>
  export default {
    name: "Son",
    data(){
      return {
        sonData:1
      }
    },
    props: {
      fatherToSon2: Number
    },
    methods: {
      changeFatherToSon2() {
        this.$emit('update:value1',20)
      },
    }
  }
</script>

father組件

<template>
  <div class="father">
    <h1>這是father組件</h1>
    <Son ref="son" :fatherToSon2="fatherToSon2" @update:value1="value=>{this.fatherToSon2=value}"         
    />
    <Son/>
    <br>
  </div>
</template>

<script>
  import Son from './Son'
  export default {
    name: "Father",
 
    components: {
      Son
    },
    data() {
      return {
        fatherToSon2: 10,
      }
    },
  }
</script>

這里value=>{this.fatherToSon2=value}也可以單獨(dú)抽出一個函數(shù)。
父組件還有一種語法糖的寫法

<template>
  <div class="father">
    <h1>這是father組件</h1>
    <Son ref="son" :fatherToSon2="fatherToSon2" :value2.sync="fatherToSon2"         
    />
    <Son/>
    <br>
  </div>
</template>

<script>
  import Son from './Son'
  export default {
    name: "Father",
    components: {
      Son
    },
    data() {
      return {
        fatherToSon2: 10,
      }
    },
  }
</script>

@update:value1="value=>{this.fatherToSon2=value}"改為:value2.sync="fatherToSon2"即可

2、$emit('input')

注意,input事件是vue幫我們定義好的,我們通過emit來觸發(fā),以達(dá)到通信的目的,其實(shí)和正常的$emit發(fā)射自定義事件是差不多的
son組件

<template>
  <div class="son">
    <h1>這是son組件</h1>
    <span>
      來自father的值(fatherToSon5):{{fatherToSon5}}
        <button @click="changeFatherToSon5">emit('input')+@input</button>
    </span>

  </div>
</template>

<script>
  export default {
    name: "Son",
    data(){
      return {
        sonData:1
      }
    },
    props: {
      fatherToSon5: Number,
    },
    methods: {
      changeFatherToSon5(){
        this.$emit('input',20000)
      },
    }
  }
</script>

<style scoped>
  .son {
    background-color: darkgray;
    color: white;
  }
</style>

Father組件

<template>
  <div class="father">
    <h1>這是father組件</h1>
    <Son ref="son"  
            :fatherToSon5="fatherToSon5" @input="value=>{this.fatherToSon5=value}"
    />
    <Son/>
    <br>
  </div>
</template>

<script>
  import Son from './Son'

  export default {
    name: "Father",
    components: {
      Son
    },
    data() {
      return {
        fatherToSon5: 10000
      }
    },
 
  }
</script>

這里其實(shí)也有個語法糖叫v-model,v-model其實(shí)可以理解為:value="somevalue" @input="value=>this.somevalue=value"的簡寫形式,當(dāng)我們把這個v-model掛到組件上時,就可以形成一種新的組件通信方法。
其中子組件不需要改動,父組件修改

<template>
  <div class="father">
    <h1>這是father組件</h1>
    <Son ref="son"  
            v-model="fatherToSon5" 
    />
    <Son/>
    <br>
  </div>
</template>

<script>
  import Son from './Son'

  export default {
    name: "Father",
    components: {
      Son
    },
    data() {
      return {
        fatherToSon5: 10000
      }
    },
  }
</script>

emit相關(guān)的到這里就結(jié)束了

$root和$parent

這里和$children和$refs類似,$parent取當(dāng)前組件實(shí)例的父組件實(shí)例,而$root取到根節(jié)點(diǎn)的組件,往往是app組件

$parent:向上派發(fā)事件

此處需要結(jié)合$emit一起食用
emit往往用于子組件通知父組件更新某個父組件的值,但是當(dāng)組件層級達(dá)到三層即(son-father-grandpa)時,需要在son中使用$parent.$emit進(jìn)行事件發(fā)射如果層級更深顯然不可能無限$parent,于是我們需要讓子組件調(diào)用$eventDispatch,讓這個子組件向上的每一級父組件都進(jìn)行$emit,一旦調(diào)用emit的組件的父組件監(jiān)聽了對應(yīng)的事件,那么就會執(zhí)行。

  Vue.prototype.$eventDispatch = function (event, value) {
    let parent = this.$parent
    while (parent) {
      parent.$emit(event, value)
      parent = parent.$parent
    }
  }

舉例:我們在ancestors上監(jiān)聽了emitToUpper事件

<template>
  <div class="ancestors">
    <h1>這是祖先組件</h1>
    <grand-pa @emitToUpper="dispatchToAncester"/>
  </div>
</template>

<script>
  import GrandPa from './GrandPa'
  export default {
    name: "Ancestors",
    components:{
      GrandPa
    },
    methods:{
      dispatchToAncester(value){
        console.log(`ancestors監(jiān)聽到了一個事件,值為${value}`);
      },
    }
  }
</script>
<style scoped>
</style>

同樣的,在app組件也可以進(jìn)行監(jiān)聽emitToUpper事件

<template>
<Ancestors @emitToUpper="dispatchToApp"/>
</template>

<script>
import Ancestors from '@/components/Ancestors'
export default {
  name: 'App',
  components: {
    Ancestors
  },
  methods:{
    dispatchToApp(value){
      console.log(`app監(jiān)聽到了一個事件,值為${value}`);
    }
  }
}
</script>
<style>
</style>

只要監(jiān)聽了@emitToUpper事件的組件都會觸發(fā)對應(yīng)的函數(shù)

<template>
  <div class="son">
    <h1>這是son組件</h1>
    <button @click="emitToUpper">使用$eventDispatch發(fā)射事件</button>
  </div>
</template>

<script>
  export default {
    name: "Son",
    methods: {
      emitToUpper(){
        this.$eventDispatch('emitToUpper','aaaa')
      },
    }
  }
</script>
<style scoped>
</style>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 組件插槽 組件的最大特征就是復(fù)用性,而用好插槽能大大提高組件的課復(fù)用能力 我的理解:就是通過組件(comp...
    黑云閱讀 518評論 0 1
  • 前言 Vue基本用法很容易上手,但是有很多優(yōu)化的寫法你就不一定知道了,本文從列舉了 36 個 vue 開發(fā)技巧; ...
    阿_軍閱讀 1,566評論 0 1
  • 第一章 Vue概述 what? Vue是實(shí)現(xiàn)UI層的漸進(jìn)式j(luò)s框架,核心庫關(guān)注視圖層,簡單的ui構(gòu)建,復(fù)雜的路由控...
    fastwe閱讀 833評論 0 0
  • 2020/05/28 周四 #[http://fe.zuo11.com/daily/2020-05.html#no...
    抓猹吃瓜閱讀 537評論 0 2
  • 表情是什么,我認(rèn)為表情就是表現(xiàn)出來的情緒。表情可以傳達(dá)很多信息。高興了當(dāng)然就笑了,難過就哭了。兩者是相互影響密不可...
    Persistenc_6aea閱讀 129,553評論 2 7

友情鏈接更多精彩內(nèi)容