记录下组件上v-model的用法

348 阅读1分钟

vue3组件上使用v-model

1、默认绑定

感觉跟匿名插槽一样,算匿名绑定吧

  • 父组件传递
<ChildCom v-model="searchValue"></ChildCom>
  • 子组件

1、接收参数,默认命名为modelValue
2、改变父组件绑定的值searchValue

// html
<input :value="modelValue" type="text" @input="handleInputChange" />
//js 
// 1、接收参数
const props = defineProps({
  modelValue: {
    type: String as PropType<string>,
    required: true,
    default: ''
  }
})
// 2、注册事件,改变绑定的值
const emit = defineEmits(['update:modelValue'])
const handleInputChange = (e: Event) => {
    emit('update:modelValue', (e.target as HTMLInputElement).value)
}

2、带参数绑定

<ChildCom v-model:age="age"></PropChild>

用法跟上面一样 只是把modelValue改为age

3、修饰符

trim, lazy, number

  • 自定义修饰符
// 父组件
<ChildCom
  v-model:name.custProp1="name"
  v-model:name2.custProp2="name2"
></ChildCom>

nameModifiers 中nameModifiers值为true 说实话有点没搞明白什么场景下使用

//子组件
// template
<input type="text" :value="name" @input="handleInputChange3" />
// script
import { PropType, ref } from 'vue'
const props = defineProps({
  name: {
    type: String as PropType<string>,
    default: ''
  },
  nameModifiers: {
    type: Object as PropType<any>,
    default: () => ({})
  },
  name2: {
    type: String as PropType<string>,
    default: ''
  },
  name2Modifiers: {
    type: Object as PropType<any>,
    default: () => ({})
  }
})
const handleInputChange3 = (e: Event) => {
  let value = (e.target as HTMLInputElement).value
  if (props!.nameModifiers!.custProp1) {
    value += '1'
  }
  if (props!.nameModifiers!.custProp2) {
    value += '2'
  }
  emit('update:name', value)
}

参考

vue2组件上使用

  • 父组件
<ChildCom :searchValue.sync='searchValue'></ChildCom>
  • 子组件一样

配合computed使用

场景,我们父组件定义了子组件变量,需要再子组件内操作,实现双向绑定

const props = defineProps(['filters'])

const emit = defineEmits(['update:filters'])

const searchForm = computed({
  get() {
    return props.filters
  },
  set(val) {
    emit('update:filters', val)
  }
})

进阶。defineModel

注意: 这个需要vue3.3+

  • 子组件这样写就行: 现在简单的离谱
<template>
  <div class="child-com">
    <el-input v-model="searchForm" placeholder="name"></el-input>
  </div>
</template>
const searchForm = defineModel<SearchTypes>('searchForm', {
  required: true,
})
  • 父组件
<child-com v-model:searchForm="searchForm"></child-com>
  • 如果识别不了, 在vite.config.ts内配置下
plugins: [
  vue({ script: { defineModel: true } }),

defineModel 对象带函数

  • 父组件
// js
const overviewForm = reactive({
  statScope: '', // 统计范围
  date: '',
  ieMark: 'I', // 进出口
  handleSearch: () => {
    console.log(9, overviewForm)
  }
})
<!--html-->
<OverviewSearch v-model:overviewForm="overviewForm"></OverviewSearch>
  • 子组件
interface OverviewFormType {
  statScope: string // 统计范围
  date: string // 统计周期
  ieMark: 'I' | 'E' // 进出口类型
  handleSearch: () => void // 查询方法
}

const overviewForm = defineModel<OverviewFormType>('overviewForm')