亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Vue中的父子組件通訊以及使用sync同步父子組件數(shù)據(jù)

 更新時(shí)間:2021年04月25日 14:30:03   作者:外婆的  
這篇文章主要介紹了Vue中的父子組件通訊以及使用sync同步父子組件數(shù)據(jù),對(duì)vue感興趣的同學(xué),可以參考下

前言

父子組件通訊,可分為兩種情況:

1. 父組件向子組件中傳遞數(shù)據(jù)
2. 子組件向父組件中傳遞數(shù)據(jù)

一般情況下, 1中情況可通過(guò)props解決數(shù)據(jù)傳遞的問(wèn)題, 這里就不多贅述了。

子組件向父組件中傳遞數(shù)據(jù)

主要談?wù)?中情景的實(shí)現(xiàn),有三種方式:

一. 通過(guò)props,父組件向子組件中傳遞數(shù)據(jù)和改變數(shù)據(jù)的函數(shù),通過(guò)在子組件中調(diào)用父組件傳過(guò)來(lái)的函數(shù),達(dá)到更新父組件數(shù)據(jù)(向父組件傳遞數(shù)據(jù))的作用(子組件中需要有相應(yīng)的響應(yīng)事件)

二. 通過(guò)在子組件中觸發(fā)一個(gè) 自定義事件(vm.$emit),將數(shù)據(jù)作為vm.$emit方法的參數(shù),回傳給父組件用v-on:[自定義事件]監(jiān)聽(tīng)的函數(shù)

三.通過(guò)ref對(duì)子組件做標(biāo)記,父組件可以通過(guò)vm.$refs.[子組件的ref].[子組件的屬性/方法]這種方式直接取得子組件的數(shù)據(jù)

下面我將一 一展示

一. 通過(guò)props從父向子組件傳遞函數(shù),調(diào)用函數(shù)改變父組件數(shù)據(jù)

這里就不做代碼展示了

一來(lái)是因?yàn)橄鄬?duì)比較簡(jiǎn)單
二來(lái)是因?yàn)檫@種方式顯然不是Vue中的最佳實(shí)踐(在react中倒比較常見(jiàn))
想要看代碼的話可以看這里:《【Vue】淺談Vue不同場(chǎng)景下組件間的數(shù)據(jù)交流》http://www.cnblogs.com/penghuwan/p/7286912.html (在兄弟組件的數(shù)據(jù)交流那一節(jié))

二. 通過(guò)自定義事件從子組件向父組件中傳遞數(shù)據(jù)

我們可以在子組件中通過(guò)$emit(event, [...參數(shù)])觸發(fā)一個(gè)自定義的事件,這樣,父組件可以在使用子組件的地方直接用 v-on來(lái)監(jiān)聽(tīng)子組件觸發(fā)的事件, 并且可以在監(jiān)聽(tīng)函數(shù)中依次取得所有從子組件傳來(lái)的參數(shù)

例如:
在子組件中某個(gè)部分寫入:

this.emit('eventYouDefined', arg);

然后你就可以在父組件的子組件模板里監(jiān)聽(tīng):
// 這里是父組件的Template:

<Son  v-on: eventYouDefined = "functionYours" />

下面是一個(gè)實(shí)例

父組件

<template>
  <div id="father">
    <div>
       我是父組件,我接受到了:
      {{ text || '暫無(wú)數(shù)據(jù)'  }}
      <son v-on:sendData='getSonText'></son>
    </div>
  </div>
</template>
 
<script>
import son from './son.vue'
export default {
  data: function () {
    return {
      text: ''
    }
  },
  components: {
    son: son
  },
  methods: {
    getSonText (text) {
      this.text = text
    }
  }
}

</script>
 
<style scoped>
#father div {
  padding: 10px;
  margin: 10px;
  border: 1px solid grey;
  overflow: hidden;
}
</style>

子組件:

<template>
  <div>
    <p>我是子組件,我所擁有的數(shù)據(jù): {{ text }}</p>
    <button @click="sendData">
      發(fā)送數(shù)據(jù)
    </button>
  </div>
</template>
 
<script>
export default {
  data () {
    return {
      text: '來(lái)自子組件的數(shù)據(jù)'
    }
  },
  methods: {
    sendData () {
      this.$emit('sendData', this.text)
    }
  }
}
</script>
 
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
   button { float: left }
</style>

在點(diǎn)擊子組件中的“發(fā)送數(shù)據(jù)”按鈕前, 父組件還沒(méi)有接受到數(shù)據(jù)(text為空字符串), 則通過(guò) {{ text || '暫無(wú)數(shù)據(jù)' }}將顯示默認(rèn)文本:‘暫無(wú)數(shù)據(jù)'

點(diǎn)擊“發(fā)送數(shù)據(jù)”按鈕后:

因?yàn)閟endData自定義事件被觸發(fā),通過(guò)

this.$emit('sendData', this.text)   //此處的this指向子組件實(shí)例)

子組件的text數(shù)據(jù)被父組件中:

 <son v-on:sendData='getSonText'></son>

中的getSonText函數(shù)作為參數(shù)接傳參受到, 從而完成了從子組件向父組件中的傳參過(guò)程

三. 通過(guò)ref屬性在父組件中直接取得子組件的數(shù)據(jù)(data)

對(duì)于我們上面講的一和二的處理情景來(lái)說(shuō),有個(gè)局限性就是它們都需要以事件機(jī)制為基礎(chǔ)(無(wú)論是像click那樣的原生事件還是自定義事件),而在事件發(fā)生的時(shí)候才能調(diào)用函數(shù)將數(shù)據(jù)傳遞過(guò)來(lái)

但如果子組件里沒(méi)有類似“按鈕”的東西,因而無(wú)法制造原生事件,同時(shí)也沒(méi)辦法找到一個(gè)觸發(fā)自定義事件的時(shí)機(jī)的時(shí)候,怎么從子組件向父組件傳遞數(shù)據(jù)呢??

這個(gè)時(shí)候, 我們就只能從父組件中“直接取”子組件的數(shù)據(jù)了,借助ref屬性

ref是我們經(jīng)常用到的Vue屬性,利用它可以簡(jiǎn)單方便地從本組件的template中取得DOM實(shí)例,而實(shí)際上,如果你在父組件中為子組件設(shè)置ref的話, 就可以直接通過(guò)vm.$refs.[子組件的ref].[子組件的屬性]去拿到數(shù)據(jù)啦,例如:

父組件:

<template>
  <div id="father">
    <div>
       我是父組件,我接受到了:
      {{ text || '暫無(wú)數(shù)據(jù)'  }}
      <button @click="getSonText()">接受數(shù)據(jù)</button>
      <son ref='son'></son>
    </div>
  </div>
</template>
 
<script>
import son from './son.vue'
export default {
  data: function () {
    return {
      text: ''
    }
  },
  components: {
    son: son
  },
  methods: {
    getSonText () {
      this.text = this.$refs.son.text
    }
  }
}

</script>
 
<style scoped>
#father div {
  padding: 10px;
  margin: 10px;
  border: 1px solid grey;
  overflow: hidden;
}
</style>

子組件:

<template>
  <div>
    <p>我是子組件,我所擁有的數(shù)據(jù): {{ text }}</p>
  </div>
</template>
 
<script>
export default {
  data () {
    return {
      text: '來(lái)自子組件的數(shù)據(jù)'
    }
  }
}
</script>
 
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
   button { float: left }
</style>

demo:

尚未點(diǎn)擊“接受數(shù)據(jù)”按鈕前:

點(diǎn)擊接受數(shù)據(jù)按鈕后:

通過(guò)sync實(shí)現(xiàn)數(shù)據(jù)雙向綁定, 從而同步父子組件數(shù)據(jù)

通過(guò)以上三種方式, 我想你應(yīng)該能解決絕大多數(shù)父子組件通信的場(chǎng)景了,但讓我們?cè)僮屑?xì)考慮一下上面的通信場(chǎng)景,就會(huì)發(fā)現(xiàn)它們還可能存在的問(wèn)題:

從子組件向父組件傳遞數(shù)據(jù)時(shí),父子組件中的數(shù)據(jù)仍不是每時(shí)每刻都同步的

但在某些特殊的需求場(chǎng)景下,我們可能會(huì)希望父子組件中的數(shù)據(jù)時(shí)刻保持同步, 這時(shí)候你可能會(huì)像下面這樣做:

這是父組件中的template:

<son :foo="bar" v-on:update="val => bar = val"></son>

在子組件中, 我們通過(guò)props聲明的方式接收f(shuō)oo并使用

props: {
     foo: [type]
}

同時(shí)每當(dāng)子組件中數(shù)據(jù)改變的時(shí)候,通過(guò)

this.$emit('update', newValue)

把參數(shù)newValue傳遞給父組件template中監(jiān)聽(tīng)函數(shù)中的"val"。然后通過(guò)

val => bar = val

這個(gè)表達(dá)式就實(shí)現(xiàn)了bar = newValue. 這個(gè)時(shí)候,我們發(fā)現(xiàn)父組件中的關(guān)鍵數(shù)據(jù)bar被子組件改變(相等)了!

通過(guò)數(shù)據(jù)的雙向綁定, 父(組件)可以修改子的數(shù)據(jù), 子也可以修改父的數(shù)據(jù)

Vue提供了sync修飾符簡(jiǎn)化上面的代碼,例如:

<comp :foo.sync="bar"></comp>

會(huì)被擴(kuò)展為:

<comp :foo="bar" @update:foo="val => bar = val"></comp>

然后你需要在子組件中改變父組件數(shù)據(jù)的時(shí)候, 需要觸發(fā)以下的自定義事件:

this.$emit("update:foo", newValue)

【注意】你可能覺(jué)得這好像和我上面提到的二中的“通過(guò)自定義事件(emit)從子組件向父組件中傳遞數(shù)據(jù)”的那一節(jié)的內(nèi)容似乎重疊了,。

然而并不是, 兩者有著父子組件關(guān)系上的不同, 下面我通過(guò)一行關(guān)鍵的代碼證明它們的區(qū)別所在

1.在我們講解sync的這一小節(jié)里, 自定義事件發(fā)生時(shí)候運(yùn)行的響應(yīng)表達(dá)式是:
<son :foo="bar" v-on:update="val => bar = val"></son> 中的 "val => bar = val"

2.在二中的“通過(guò)自定義事件從子組件向父組件中傳遞數(shù)據(jù)” 里,自定義事件發(fā)生時(shí)候運(yùn)行的響應(yīng)表達(dá)式是:
<Son v-on: eventYouDefined = "arg => functionYours(arg)" /> 中的 "arg => functionYours(arg)"

對(duì)前者, 表達(dá)式 val => bar = val意味著強(qiáng)制讓父組件的數(shù)據(jù)等于子組件傳遞過(guò)來(lái)的數(shù)據(jù), 這個(gè)時(shí)候,我們發(fā)現(xiàn)父子組件的地位是平等的。 父可以改變子(數(shù)據(jù)), 子也可以改變父(數(shù)據(jù))

對(duì)后者, 你的functionYours是在父組件中定義的, 在這個(gè)函數(shù)里, 你可以對(duì)從子組件接受來(lái)的arg數(shù)據(jù)做任意的操作或處理, 決定權(quán)完全落在父組件中, 也就是: 父可以改變子(數(shù)據(jù)), 但子不能直接改變父(數(shù)據(jù))!, 父中數(shù)據(jù)的變動(dòng)只能由它自己決定

下面是一個(gè)展示demo:

父組件:

<template>
  <div id="father">
    <div>
       我是父組件
      <son
        :wisdom.sync="wisdom"
        :magic.sync="magic"
        :attack.sync="attack"
        :defense.sync="defense">
      </son>
      <p>智力: {{ wisdom }}</p>
      <p>膜法: {{ magic }}</p>
      <p>攻擊: {{ attack }}</p>
      <p>防御: {{ defense }}</p>
    </div>
  </div>
</template>
 
<script>
import son from './son.vue'
export default {
  data: function () {
    return {
      wisdom: 90,
      magic: 160,
      attack: 100,
      defense: 80
    }
  },
  components: {
    son: son
  }
}

</script>
 
<style scoped>
#father div {
  padding: 10px;
  margin: 10px;
  border: 1px solid grey;
  overflow: hidden;
}
</style>

子組件:

<template>
  <div>
    <p>我是子組件</p>
    <p>智力: {{ wisdom }}</p>
    <p>膜法: {{ magic }}</p>
    <p>攻擊: {{ attack }}</p>
    <p>防御: {{ defense }}</p>
    <button @click="increment('wisdom')">增加智力</button>
    <button @click="increment('magic')">增加膜法</button>
    <button @click="increment('attack')">增加攻擊</button>
    <button @click="increment('defense')">增加防御</button>
  </div>
</template>
 
<script>
export default {
  props: {
    wisdom: Number,
    magic: Number,
    attack: Number,
    defense: Number
  },

  methods: {
    increment (dataName) {
      let newValue = this[dataName] + 1
      this.$emit(`update:${dataName}`, newValue)
    }
  }
}
</script>
 
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
   button { float: left }
</style>

點(diǎn)擊前

點(diǎn)擊增加子組件中“增加智力”按鈕的時(shí)候, 父組件和子組件中的智力參數(shù)同時(shí)從90變?yōu)?1

點(diǎn)擊增加子組件中“增加膜法”按鈕的時(shí)候, 父組件和子組件中的智力參數(shù)同時(shí)從160變?yōu)?61

數(shù)據(jù)雙向綁定是把雙刃劍

從好處上看:

1.它實(shí)現(xiàn)了父子組件數(shù)據(jù)的“實(shí)時(shí)”同步, 在某些數(shù)據(jù)場(chǎng)景下可能會(huì)使用到這一點(diǎn)
2.sync提供的語(yǔ)法糖使得雙向綁定的代碼變得很簡(jiǎn)單

從壞處上看:

它破環(huán)了單向數(shù)據(jù)流的簡(jiǎn)潔性, 這增加了分析數(shù)據(jù)時(shí)的難度

當(dāng)sync修飾的prop是個(gè)對(duì)象

我們對(duì)上面的例子修改一下, 把數(shù)據(jù)包裹在一個(gè)對(duì)象中傳遞下來(lái):

父組件

<template>
  <div id="father">
    <div>
       我是父組件
      <son :analysisData.sync="analysisData">
      </son>
      <p>智力: {{ analysisData.wisdom }}</p>
      <p>膜法: {{ analysisData.magic }}</p>
      <p>攻擊: {{ analysisData.attack }}</p>
      <p>防御: {{ analysisData.defense }}</p>
    </div>
  </div>
</template>
 
<script>
import son from './son.vue'
export default {
  data: function () {
    return {
      analysisData: {
        wisdom: 90,
        magic: 160,
        attack: 100,
        defense: 80
      }
    }
  },
  components: {
    son: son
  }
}

</script>
 
<style scoped>
#father div {
  padding: 10px;
  margin: 10px;
  border: 1px solid grey;
  overflow: hidden;
}
</style>

子組件

<template>
  <div>
    <p>我是子組件</p>
    <p>智力: {{ analysisData.wisdom }}</p>
    <p>膜法: {{ analysisData.magic }}</p>
    <p>攻擊: {{ analysisData.attack }}</p>
    <p>防御: {{ analysisData.defense }}</p>
    <button @click="increment('wisdom')">增加智力</button>
    <button @click="increment('magic')">增加膜法</button>
    <button @click="increment('attack')">增加攻擊</button>
    <button @click="increment('defense')">增加防御</button>
  </div>
</template>
 
<script>
export default {
  props: {
    analysisData: Object
  },

  methods: {
    increment (dataName) {
      let newObj = JSON.parse(JSON.stringify(this.analysisData))
      newObj[dataName] += 1
      this.$emit('update:analysisData', newObj)
    }
  }
}
</script>
 
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
   button { float: left }
</style>

demo同上

不要通過(guò)在子組件中修改引用類型props達(dá)到“父子組件數(shù)據(jù)同步”的需求!

父組件的數(shù)據(jù)傳遞給子組件, 一般通過(guò)props實(shí)現(xiàn), 而在實(shí)現(xiàn)“父子組件數(shù)據(jù)同步”這一需求的時(shí)候, 小伙伴們可能會(huì)發(fā)現(xiàn)一點(diǎn): 在子組件中修改引用類型的props(如數(shù)組和對(duì)象)是可行的

1.不僅可以達(dá)到同時(shí)修改父組件中的數(shù)據(jù)(因?yàn)楸緛?lái)引用的就是同一個(gè)數(shù)據(jù))
2.而且還不會(huì)被Vue的檢測(cè)機(jī)制發(fā)現(xiàn)?。ú粫?huì)報(bào)錯(cuò))

但千萬(wàn)不要這樣做, 這樣會(huì)讓數(shù)據(jù)流變得更加難以分析,如果你嘗試這樣做, 上面的做法可能會(huì)更好一些
不要這樣做,糟糕的做法:

父組件:

<template>
  <div id="father">
    <div>
       我是父組件
      <son :analysisData="analysisData">
      </son>
      <p>智力: {{ analysisData.wisdom }}</p>
      <p>膜法: {{ analysisData.magic }}</p>
      <p>攻擊: {{ analysisData.attack }}</p>
      <p>防御: {{ analysisData.defense }}</p>
    </div>
  </div>
</template>
 
<script>
import son from './son.vue'
export default {
  data: function () {
    return {
      analysisData: {
        wisdom: 90,
        magic: 160,
        attack: 100,
        defense: 80
      }
    }
  },
  components: {
    son: son
  }
}

</script>
 
<style scoped>
#father div {
  padding: 10px;
  margin: 10px;
  border: 1px solid grey;
  overflow: hidden;
}
</style>

子組件:

<template>
  <div>
    <p>我是子組件</p>
    <p>智力: {{ analysisData.wisdom }}</p>
    <p>膜法: {{ analysisData.magic }}</p>
    <p>攻擊: {{ analysisData.attack }}</p>
    <p>防御: {{ analysisData.defense }}</p>
    <button @click="increment ('wisdom')">增加智力</button>
    <button @click="increment ('magic')">增加膜法</button>
    <button @click="increment ('attack')">增加攻擊</button>
    <button @click="increment ('defense')">增加防御</button>
  </div>
</template>
 
<script>
export default {
  props: {
    analysisData: Object
  },

  methods: {
    increment (dataName) {
      let obj = this.analysisData
      obj[dataName] += 1
    }
  }
}
</script>
 
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
   button { float: left }
</style>

以上就是Vue中的父子組件通訊以及使用sync同步父子組件數(shù)據(jù)的詳細(xì)內(nèi)容,更多關(guān)于Vue的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 實(shí)例講解v-if和v-show的區(qū)別

    實(shí)例講解v-if和v-show的區(qū)別

    今天小編就為大家分享一篇關(guān)于實(shí)例講解v-if和v-show的區(qū)別,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2019-01-01
  • 新手vue構(gòu)建單頁(yè)面應(yīng)用實(shí)例代碼

    新手vue構(gòu)建單頁(yè)面應(yīng)用實(shí)例代碼

    本篇文章主要介紹了新手vue構(gòu)建單頁(yè)面應(yīng)用實(shí)例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-09-09
  • element-ui?table表格底部合計(jì)自定義配置過(guò)程

    element-ui?table表格底部合計(jì)自定義配置過(guò)程

    這篇文章主要介紹了element-ui?table表格底部合計(jì)自定義配置過(guò)程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-10-10
  • vue3封裝側(cè)導(dǎo)航文字骨架效果組件

    vue3封裝側(cè)導(dǎo)航文字骨架效果組件

    這篇文章主要為大家詳細(xì)介紹了vue3封裝側(cè)導(dǎo)航文字骨架效果組件,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • vue單頁(yè)面實(shí)現(xiàn)當(dāng)前頁(yè)面刷新或跳轉(zhuǎn)時(shí)提示保存

    vue單頁(yè)面實(shí)現(xiàn)當(dāng)前頁(yè)面刷新或跳轉(zhuǎn)時(shí)提示保存

    這篇文章主要介紹了vue單頁(yè)面實(shí)現(xiàn)當(dāng)前頁(yè)面刷新或跳轉(zhuǎn)時(shí)提示保存,在當(dāng)前頁(yè)面刷新或跳轉(zhuǎn)時(shí)提示保存并可取消刷新,以防止填寫的表單內(nèi)容丟失,感興趣的小伙伴們可以參考一下
    2018-11-11
  • Vue.js使用$.ajax和vue-resource實(shí)現(xiàn)OAuth的注冊(cè)、登錄、注銷和API調(diào)用

    Vue.js使用$.ajax和vue-resource實(shí)現(xiàn)OAuth的注冊(cè)、登錄、注銷和API調(diào)用

    這篇文章主要介紹了 Vue.js使用$.ajax和vue-resource實(shí)現(xiàn)OAuth的注冊(cè)、登錄、注銷和API調(diào)用,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-05-05
  • Vue3+Vue Router實(shí)現(xiàn)動(dòng)態(tài)路由導(dǎo)航的示例代碼

    Vue3+Vue Router實(shí)現(xiàn)動(dòng)態(tài)路由導(dǎo)航的示例代碼

    隨著單頁(yè)面應(yīng)用程序(SPA)的日益流行,前端開(kāi)發(fā)逐漸向復(fù)雜且交互性強(qiáng)的方向發(fā)展,在這個(gè)過(guò)程中,Vue.js及其生態(tài)圈的工具(如Vue Router)為我們提供了強(qiáng)大的支持,本文將介紹如何在Vue 3中使用Vue Router實(shí)現(xiàn)動(dòng)態(tài)路由導(dǎo)航,需要的朋友可以參考下
    2024-08-08
  • Vue中如何合并el-table第一列相同數(shù)據(jù)

    Vue中如何合并el-table第一列相同數(shù)據(jù)

    這篇文章主要介紹了Vue中如何合并el-table第一列相同數(shù)據(jù)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • vue柱狀進(jìn)度條圖像的完美實(shí)現(xiàn)方案

    vue柱狀進(jìn)度條圖像的完美實(shí)現(xiàn)方案

    本文是對(duì)bar進(jìn)度條實(shí)現(xiàn)的2種方案進(jìn)行分享,第一種是很簡(jiǎn)單,純css的實(shí)現(xiàn),第二種是echart的實(shí)現(xiàn)。對(duì)vue柱狀進(jìn)度條圖像的實(shí)現(xiàn)方案,感興趣的朋友跟隨小編一起看看吧
    2019-08-08
  • vue父子組件的嵌套的示例代碼

    vue父子組件的嵌套的示例代碼

    本篇文章主要介紹了vue父子組件的嵌套的示例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-09-09

最新評(píng)論