vue自定义组件上使用v-model

一、表单绑定

1.1、v-model基本使用

Vue中使用v-model指令来实现表单元素和数据的双向绑定

<template>
  <section>
    <input type="text" v-model="message">
    {{message}}
  </section>
</template>

<script>
export default {
  data() {
    return {
      message: '你好啊'
    }
  }
}
</script>

解析:当在输入框输入内容时,因为input中的v-model绑定了message,所以会实时将输入的内容传递给message。当message发生改变时,也会将message的值插入到DOM中,所以DOM会发生响应的改变。

1.2、v-model原理

v-model其实是一个语法糖,它的背后本质上是包含两个操作:

  • 1.v-bind绑定一个value属性
  • 2.v-on指令给当前元素绑定input事件

也就是说上面的代码 等同于下面的代码:

<template>
  <section>
    <!-- <input type="text" v-model="message"> -->
    <!-- 等同于 -->
    <input type="text" :value="message" @input="message = $event.target.value">
    <h2>{{message}}</h2>
  </section>
</template>

<script>
export default {
  data() {
    return {
      message: '你好啊'
    }
  }
}
</script>

二、组件上使用v-model

2.1 官网解释:

允许一个自定义组件在使用 v-model 时定制 prop 和 event。默认情况下,一个组件上的 v-model 会把 value 用作 prop 且把 input 用作 event,但是一些输入类型比如单选框和复选框按钮可能想使用 value prop 来达到不同的目的。使用 model 选项可以回避这些情况产生的冲突。

自定义model使用示例:

model: {
    prop: 'myValue',  // 默认是value
    event: 'myInput', // 默认是input
}

当我们使用model的默认值的时候value作prop,input作event时,可以省略不写model。

2.2 v-model的使用

2.2.1 自定义组件代码示例

<template>
  <section>
    <!-- 自定义组件中使用v-mode指令 -->
    <input @input="changeInput">
  </section>
</template>

<script>
export default {
  name: 'CustomModel',
  // 当我们使用model的默认值的时候value用作prop,input用作event时,可以省略不写model。
  model: {
    prop: 'myValue',  // 默认是value
    event: 'myInput', // 默认是input
  },
  props: {
    // 接收string和number类型的值,
    // 注意不能是写成字符串["String","Number"],因为此时它们是构造器,是全局变量
    myValue: [String, Number],
  },
  methods: {
    changeInput(e) {
      // 向上派发myInput事件,这样model监听myInput才有意义:当输入字符时触发input事件,进而派发触发自定义的myInput事件,然后model监听myInput,就实现了数据绑定。
      // 必须注意,这里的派发事件名“myInput”必须和model中的event的值相同。
      // PS: 通过watch监听 input标签的值,然后$emit派发事件,和通过@input派发事件具有一样的效果。只要能达到通信的效果即可,手段是多样的。
      this.$emit('myInput', e.target.value);
    }
  }
}
</script>

2.2.2 在父组件中使用自定义组件

<template>
  <div class="home">
    <h3>输入的实时内容:{{ myValue }}</h3>
    <custom-model v-model="myValue"></custom-model>
  </div>
</template>
<script>
import CustomModel from './CustomModel';
export default {
  components: {
    CustomModel,
  },
  data() {
    return {
      myValue: ''
    }
  }
}
</script>

2.3 自定义checkbox组件

2.3.1 子组件

<template>
  <section>
    <input type="checkbox" :checked="checked" @change="handleChange"> 点赞哈默视频?
  </section>
</template>

<script>
export default {
  model: {
    prop: 'checked',  // 默认是value,注意是prop,不带s。
    event: 'change',  // 默认是input
  },
  props: ['checked'],
  methods: {
    handleChange(e) {
      this.$emit('change', e.target.checked);
    }
  }
}
</script>

2.3.2 父组件

<template>
  <div class="app">
    <BaseCheckbox v-model="checked" />
    <!-- <BaseCheckbox :checked="checked" @change="checked = $event" /> -->
    <p>已经赞了:{{checked}}</p>
  </div>
</template>
<script>
import BaseCheckbox from './BaseCheckbox';
export default {
  components: {
    BaseCheckbox,
  },
  data() {
    return {
      checked: true
    }
  }
}
</script>

 

posted @ 2022-08-08 16:38  小阿飞ZJF  阅读(831)  评论(0编辑  收藏  举报