[ vue ] 自定义组件的 v-model 理解

需求场景描述:

 

1. 在父组件 myself.vue 里面定义数据 button_val 

2. 在父组件 myself.vue.里面定义按钮,它的功能是吧 button_val  的值 -1

----

3. 子组件 test.vue 是一个按钮,它显示的数据是 父组件button_val 的值,功能是把 button_val 的值 +1

接下来看如何一步一步实现这个效果

官方文档解读:

查看官方文档:https://cn.vuejs.org/v2/guide/components-custom-events.html#%E8%87%AA%E5%AE%9A%E4%B9%89%E7%BB%84%E4%BB%B6%E7%9A%84-v-model

 

1. 注意这里组件的默认规则

prop: value
event: input

 2. v-mode是vue提供的语法糖,它本质是这样的:

  [ 效果 ]

     

[ 父组件 ]

<
template> <div class="q-ma-lg"> <div class="q-mb-lg"> <span>(父组件)监控lovingVue的值:</span> {{lovingVue}} </div> <base-checkbox :value="lovingVue" @input="lovingVue = $event"/> </div> </template> <script> import test_child from 'components/test_child.vue' export default { data(){ return { lovingVue:'' } }, components:{ 'base-checkbox':test_child } } </script>

  [ 子组件 ]

<template>
<div>
  <span>(子组件)</span>
  <input type="text" @input="$emit('input',$event.target.value)" />
</div>
</template>
<script>

1. 子组件本质是一个input框,通过监听用户input输入来抛出一个值,这个值就是用户输入的内容。

2. 父组件的行为就可以参照官方文档的那句话了: 一个组件上的 v-model 默认会利用名为 value 的 prop 和名为 input 的事件 

    这里父组件监听input事件来获取子组件抛出的值,并更新 lovingVue 。

3. 就此达到数据的双向绑定

3. 自定义prop和自定义事件:

默认v-model的props是:value

默认v-model的event是:input

这里我们来实现自定义prop和事件:

<!-- 父组件 -->
<template>
  <div class="q-ma-lg">
    <div class="q-mb-lg">
      <span>(父组件)监控lovingVue的值:</span>
      {{lovingVue}}
    </div>

    <base-checkbox :customValue="lovingVue" @customEvent="lovingVue = $event"/>

  </div>
</template>
<script>
import test_child from 'components/test_child.vue'
export default {
  data(){
    return {lovingVue:''}
  },
  components:{'base-checkbox':test_child}
}
</script>

<!-- ------------------------------------------------------------------------------- -->

<!-- 子组件 -->
<template>
<div>
  <span>(子组件)</span>
  <input type="text" @input="$emit('customEvent',$event.target.value)" />
</div>
</template>

<script>
export default {
  model:{
    prop:'customValue',
    event:'customEvent'
  },
  props:{
    customValue:String
  }
}
</script>

需求的实现:

<!-- 父组件 -->
<template>
  <div class="q-mt-lg">
    <div style="width:200px;height:100px;border:1px solid" class="bg-primary">
      <span>parent</span>
      <q-btn 
        :label="button_val + ' (-1)'" 
        @click="button_val = button_val - 1"
        color="grey" 
        class="q-ma-md" 
      />
    </div>

    <!-- 子组件 -->
    <div style="width:200px;height:100px;border:1px solid" class="bg-info">
      <span>child</span>
      <test 
        v-model="button_val" 
        class="q-ma-md"
      />
    </div>
  </div>
</template>
<script>
import test from 'components/test.vue'
export default {
  data(){
    return {button_val:1}
  },
  components:{test}
}
</script>


----------------------------------------------

<!-- 子组件 -->
<template>
  <div>
    <q-btn color="primary" :label="buttonVal+'  (+1)'" @click="handleTest"/>
  </div>
</template>

<script>
export default {
  model:{
    prop:'buttonVal',
    event:'haha'
  },
  props:{
    buttonVal:{
      type:Number,
      default:0
    }
    
  },
  data(){
    return {}
  },
  methods:{
    handleTest(){
      this.$emit('haha',Number(this.buttonVal)+1)
    }

  }
}
</script>

猜你喜欢

转载自www.cnblogs.com/remly/p/12977442.html