vue3中的v-model

159 阅读1分钟

vue3中的v-model

vue3中移除了.sync修饰符和组件的model选项,不过都可以用v-model来代替。

vue2中的v-model本质是:value和update:value的结合,vue3中对v-model做了扩展,使其可以自定义属性。

Parent.vue

<template>
  <Child v-model:title="title" />
</template>

<script>
  import { ref, watch } from 'vue'
  export default {
    setup() {
      const title = ref('test v-model')
      
      watch(title, newV => console.log(`title值被子组件改变为:${newV}`))
      
      return { title }
    }
  }
</script>

Child.vue

<template>
  <input v-model="props.title" @change="handleChange"></input>
</template>

// 第一种方式,通过ctx.emit('update:title', value)来更新title,需要注意:需要添加emits属性,值为['update:title']
<script>
  export default {
    props: {
      title: { type: String }
    },
    emits: ['update:title'],
    setup(props, ctx) {
      const handleChange = e => {
        const value = e.target.value
        ctx.emit('update:title', value) // update:xxx是固定写法
      }
    }
  }
</script>

// 第二种,在props中添加'update:title',可以省略添加emits属性
<script>
  export default {
    props: {
      title: { type: String },
      'update:title': { type: Function }
    },
    setup(props, ctx) {
      const handleChange = e => {
        const value = e.target.value
        ctx.emit('update:title', value) // update:xxx是固定写法
      }
    }
  }
</script>

// 第三种,vue3会把父组件传给子组件的所有属性(排除props中接收的属性),都放在ctx.attrs中,包括属性、事件、样式等。
因此可以在ctx.attrs中拿到onUpdate:title事件,直接调用
<script>
  export default {
    props: {
      title: { type: String }
    },
    setup(props, ctx) {
      const handleChange = e => {
        const value = e.target.value
        ctx.attrs['onUpdate:title'](value)
      }
    }
  }
</script>