經過v-model‘實現’組件雙向數據綁定

單向數據流

  • 單向數據流是Vue組件一個很是明顯的特徵,不該該在子組件中直接修改props的值
  • 若是傳遞的prop僅僅用做展現,不涉及修改,則在模板中直接使用便可
  • 若是須要對prop的值進行轉化而後展現,則應該使用computed計算屬性
  • 若是prop的值用做初始化,應該定義一個子組件的data屬性並將prop做爲其初始值

組件之間的通訊

  • 父子組件的關係能夠總結爲 prop 向下傳遞,事件event向上傳遞
  • 祖先組件和後代組件(跨多代)的數據傳遞,可使用provideinject來實現
  • 跨組件或者兄弟組件之間的通訊,能夠經過eventBus或者vuex等方式來實現

封裝的組件如何實現v-model的數據雙綁的效果

如下兩種一般是咱們的實現方式, 看着就很麻煩

  1. 經過emit將事件派發到父組件,prop將數據傳到子組件

    每一個父組件都要實現changeValue方法來接收數據並更新數據vue

// 子組件
    <template>
    <div>
    <van-button @click="add" type="default">加一</van-button>
    <div>
        {{countsVal}}
    </div>
    <van-button @click="reduce" type="default">減一</van-button>
    </div>
    </template>

    <script>
        export default {
            props: {
                value: Number
            },
			  model: {
			  prop: 'value',
			  event: 'input'
			},
            data () {
                return {
                // props的初始化比data的初始化要靠前
                countsVal: this.value
                }
            },
            methods: {
                add () {
                    this.countsVal++
                    this.$emit('add', this.countsVal)
                },
                reduce() {
                    this.countsVal--
                    this.$emit('reduce', this.countsVal)
                }
            }
        };
    </script>

    // 父組件
    <template>
        <div>
                <counter :value='value' @add='changeValue' @reduce='changeValue'/>
        </div>
    </template>

    <script>
        export default {
            data () {
                return {
                value: 10
                }
            },
            methods: {
                changeValue (data) {
                    this.value = data
                }
            }
        };
    </script>
  1. 將加減執行的回到函數經過父組件傳到子組件中實現改變數據

    每一個父組件都要實現addreduce兩個方法vuex

// 子組件
    <template>
    <div>
    <van-button @click="add" type="default">加一</van-button>
    <div>
        {{countsVal}}
    </div>
    <van-button @click="reduce" type="default">減一</van-button>
    </div>
    </template>

    <script>
    export default {
        props: {
            value: Number,
            add: Function,
            reduce: Function
        }
    };
    </script>
    
    // 父組件
    <template>
    <div>
    <counter :value='value' :add='add' :reduce='reduce'/>
    </div>
    </template>

    <script>
        export default {
            data () {
                return {
                value: 10
                }
            },
            methods: {
                add (data) {
                    this.value++
                },
                reduce (data) {
                    this.value--
                }
            }
        };
    </script>

經過v-model語法糖實現,父子組價的數據雙綁

Vue內置了v-model指令,v-model 是一個語法糖,能夠拆解爲 props: value 和 events: input。就是說組件只要提供一個名爲 value 的 prop,以及名爲 input 的自定義事件,知足這兩個條件,使用者就能在自定義組件上使用 v-model,戳這裏看model配置api

// 子組件
  <template>
      <div>
          <van-button @click="changeVal(1)" type="default">加一</van-button>
          <div>
              {{countsVal}}
          </div>
          <van-button @click="changeVal(-1)" type="default">減一</van-button>
      </div>
  </template>

  <script>
  export default {
      props: {
          value: Number
      },
      data () {
          return {
          // props的初始化比data的初始化要靠前
          countsVal: this.value
          }
      },
      methods: {
          changeVal (data) {
          this.countsVal += parseInt(data)
          this.$emit('input', this.countsVal)
          }
      }
  }
  </script>
  // 父組件只須要經過v-model將數據傳進去就行了
  <template>
      <div>
          <counter v-model='counts'/>
      </div>
  </template>

  <script>
      import counter from './base/counter'
      export default {
          components: {
              counter
          },
          data () {
              return {
              counts: 10
              }
          }
      }
  </script>
相關文章
相關標籤/搜索