react都這麼無情了,vue仍是那麼有義,4種父子組件數據雙向傳遞大法

本來想放張老尤的照片的,燒三根香膜拜一下的,惋惜圖片和不上去,在前端這麼mmp的時代,每天有那麼多B事,在數據驅動的時候,你們都推崇數據的走向都是單向數據流,都是經過父組件去向子組件傳遞數據,仍是那句話,那來這麼多B事,只要注意點就能夠了,合理的運用雙向綁定,不管對業務和組件開發來講,都是一件共贏的事,裝B能夠,可是不能過份!前端

好了,講重點,今天我就給你們講講VUE四種數據雙向傳遞有那些用法vue

一.經過$on , $emit 來進行雙向通訊

使用 $on(eventName) 監聽事件
使用 $emit(eventName) 觸發事件vuex

這種用法,實際上是我接下來三種用法的根基bash

先來講說$on 是用來幹麻的,是用來監聽的事件的,就是監聽$emit裏(eventName)事件的,一量$emit觸發事件,則$on會接收到,則執行函數事件函數

那咱們基本數據單向傳遞咱們都用props來進行傳遞,那一旦子組件想改變props傳過來的數據,咱們是不能直接改變Props裏的數據,咱們仍是要改變父組件的數據,用$on和$emit是如何實現的呢ui

children組件

<template lang="pug">
  .demo
    .demo-example(@click="changePropsValue") {{msg}}
</template>


<script>
export default {
  props: ['msg'],
  methods: {
    changePropsValue () {
      this.$emit('changeMsg', '經過$emit觸發事件了')
    }
  }
}
</script>複製代碼

1.msg是經過父組件傳遞過來的,咱們先前可確定要在props裏聲明好
2.在點擊的時候,咱們觸發了changeMsg事件,第二個參數是,你想要傳到父組件的參數this

parent組件

<template lang="pug">
  div
    demo(:msg="msg" v-on:changeMsg='onChange')
</template>

<script>
import Demo from './demo.vue'
export default {
  data () {
    return {
      msg: '首次數據傳遞'
    }
  },
  components: {
    Demo
  },
  methods: {
    onChange (msg) {
      this.msg = msg
    }
  }
}
</script>複製代碼

咱們隨後把demo引入,傳入子組件的msg咱們事先在data數據裏面定義好,同時在demo組件上進行一個$on的監聽
1.$on :(冒號)後面跟的第一個值是$emit觸發的事件,也是$on所要監聽的事件,一量$emit有觸發,則立刻執行了onChange函數,但本質上vue仍是單向數據流的,雖然props不能改變,可是data裏的數據是能夠進行改變的,一但data的數據和子組件有傳遞關係,一旦父data數據有變更,子組件props所對應的數據則同時跟着變更spa

二.經過 v-model 來進行雙父子通訊

在vue進入到2.0的時候,取消了.sync的功能,致使了一堆組件庫大動腦子,基本都用了v-model去進行雙向綁定,本質上v-model適用場景是用在表單上面的,可是既然能夠自定義了,那就有它的靈活性設計

官方說法:

自定義事件能夠用來建立自定義的表單輸入組件,使用 v-model 來進行數據雙向綁定。看看這個:input v-model="something"雙向綁定

那語法糖則是這樣的

input
v-bind:value="something"
v-on:input="something = $event.target.value"

這說明了

1.v-model裏的something這個變量值在語法糖裏表明的是value值,在表單上咱們能夠看做是input的value值,那在其它標籤能夠當作一個將要傳入的Props數據,那惟一不可變的是這個props的Key必須是value
2.v-on:input="something = $event.target.value"
其實v-model內置也是經過$on和$emit來進行傳遞的,進行了input輸入事件的監聽,而後拿到事件上$event.target.value最新的改變something

如今老版本的組件庫,當2.0取消.sync的時候,自定義組件的時候,如何巧用v-model來進行雙向通訊

children組件

<template lang="pug">
  .demo
    .demo-example(@click="changePropsValue") {{value}}
</template>


<script>
export default {
  props: ['value'],
  methods: {
    changePropsValue () {
      this.$emit('input', '經過$emit觸發input事件了')
    }
  }
}
</script>複製代碼

1.這裏的value前面說過了就是v-model傳過來的value ( v-bind:value="something"),可是隻能用value去接收
2.這裏主要巧用了一點,平時咱們改變input輸入框的時候,input事件是本身主動觸發的,可是,咱們也同時能夠給他手動觸發,咱們用$emit進行了手動觸發(input)事件

parent組件

<template lang="pug">
  div
    demo(v-model ='msg')
</template>

<script>
import Demo from './demo.vue'
export default {
  data () {
    return {
      msg: '首次數據傳遞'
    }
  },
  components: {
    Demo
  }
}
</script>複製代碼

這個咱們直接用v-model像表單那樣綁定就直接能夠進行父子組件雙向綁定了。在v-model的語法糖裏封裝了v-on:input 去進行監聽事件

3.在2.3迴歸的特性.sync

迴歸的.sync與1.0版本的寫法有所改變,改來改去,不離其實中,仍是要經過$emit去顯式地觸發一個更新事件;

可是相比v-model來講語法上更加直觀,更加簡潔,畢鏡v-model是主要給表單進行又向綁定適用的

若是再進一步往底層說,.sync仍是進行了$on進行了監聽封裝,跟v-model同樣也一樣是一種語法糖

children組件

<template lang="pug">
  .demo
    .demo-example(@click="changePropsValue") {{msg}}
</template>


<script>
export default {
  props: ['msg'],
  methods: {
    changePropsValue () {
      this.$emit('update:msg', '經過$emit顯示觸發了更新事件')
    }
  }
}
</script>複製代碼

1.經過props來進行msg的數據接收
2.經過$emit來進行觸發,第一個參數則是顯示觸發,update:msg (msg)則是你須要改變的props裏從父組件裏接收的值,第二個參數,仍是你要更新的值,從語意上設計的也頗有感受,有木有

parent

<template lang="pug">
  div
    demo(:msg.sync="msg")
</template>

<script>
import Demo from './demo.vue'
export default {
  data () {
    return {
      msg: '首次數據傳遞'
    }
  },
  components: {
    Demo
  }
}
</script>複製代碼

主要看demo(:msg.sync="msg") 這裏直接在向子組件傳遞的時候仍是像1.0的時候加一個.sync,本質上仍是它會被擴展爲一個自動更新父組件屬性的 v-on 偵聽器
(推薦用法,通常對一個模態框進行封裝的時候頗有用,有了.sync不建議用v-model)

4.$parent用法

這在一些顯示操做的時候,向外部暴露props和event的時候是不推薦用的,那有人要問了$$parent何時用呢,在一些本身內部邏輯操用的時候能夠用一下,不用很繁瑣的來進行雙向來回導,節省代碼和邏輯,有時候也可讓人一目瞭然

children組件

<template lang="pug">
  .demo
    .demo-example(@click="changePropsValue") 點擊按鈕
</template>


<script>
export default {
  methods: {
    changePropsValue () {
      this.$parent.msg = '經過$parent顯改變了更新事件'
    }
  }
}
</script>複製代碼

1.子組件,經過點擊按鈕,顯示的改變了父組件的parent.msg裏面的數據

parent

<template lang="pug">
  div
    demo
    p {{msg}}
</template>

<script>
import Demo from './demo.vue'
export default {
  data () {
    return {
      msg: '第一次寫入數據'
    }
  },
  components: {
    Demo
  }
}
</script>複製代碼

在這種四種方法裏,我仍是推薦用.sync來進行雙向通訊,一量旦通訊機制深了,組件的嵌到超過3層的話,我仍是建議用vuex來進行數據的共享,否則一層一層傳,再一層一層的向上導,到最後你頁面會把控不住,業務代碼也就不直觀了

相關文章
相關標籤/搜索