Vue3.4之defineModel的用法

👀 defineModel是vue3.4中正式加入的API的,可以简化组件之间双向绑定的流程。

1.首先回顾一下基于v-modal实现的双向绑定

v-model是vue.js提供的一个语法糖,用于在表单元素和组件之间创建双向数据绑定,即当数据变属性化时,相应的表单元素也会自动更新。

1.1 v-model的写法

v-model的原理:v-bind绑定一个value属性,v-on指令给当前元素绑定事件

父组件:

<template>
  <Children v-model:count="countNumber"></Children>
</template>

<script setup lang="ts">
import Children from './children.vue'
import {ref} from 'vue'

const countNumber = ref(1) 
</script>

子组件:children

<template>
  <div>
    {{ props.count }}
    <button @click="updateCount">child</button>
  </div>
</template>

<script setup lang="ts">
const props = defineProps(["count"]);
const emits = defineEmits(['update:count'])

const updateCount = () =>{
  emits('update:count', props.count+1)
}
</script>
1.2 自定义事件写法

父组件:

<template>
  <Children :count="countNumber" @change="updateVal"></Children>
</template>

<script setup lang="ts">
import Children from './components/HelloWorld.vue'
import {ref} from 'vue'

const countNumber = ref(1) 
const updateVal = (item:number) => {
countNumber.value  = item
}
</script>

子组件:children

<template>
  <div>
    {{ count }}
    <button @click="updateCount">child</button>
  </div>
</template>

<script setup lang="ts">
const props = defineProps<{
  count: number 
}>()

const emits = defineEmits(['change'])

const updateCount = () =>{
  emits('change', props.count+1)
}
</script>
从vue2开始,vue就是单向数据流,在子组件中是不能直接修改props中的值,由子组件抛出一个事件,由父组件去监听这个事件,再去修改父组件中传递给props的变量。自定义事件的写法更显式,适合复杂逻辑的场景。- v-model写法更简洁,减少了样板代码。

2.defineModel实现数据双向绑定

这个宏可以用来声明一个双向绑定 prop,通过父组件的 v-model 来使用。在底层,这个宏声明了一个 model prop 和一个相应的值更新事件。如果第一个参数是一个字符串字面量,它将被用作 prop 名称;否则,prop 名称将默认为 "modelValue"。在这两种情况下,你都可以再传递一个额外的对象,它可以包含 prop 的选项和 model ref 的值转换选项。

父组件:

<template>
  <Children v-model:count="countNumber"></Children>
</template>

<script setup lang="ts">
import Children from './children.vue'
import {ref} from 'vue'

const countNumber = ref(1) 
</script>

子组件:

<template>
  <div>
    {{ count }}
    <button @click="updateCount">child</button>
  </div>
</template>

<script setup lang="ts">
const count = defineModel("count", {
  type: Number,
  default: 0
}) 

const updateCount = () =>{
  count.value++
}
</script>
2.1修饰符和转换器

为了获取 v-model 指令使用的修饰符,我们可以像这样解构 defineModel() 的返回值:

父组件:

<Children v-model:message.capitalize="word"/>

<script setup lang="ts">
import Children from './children.vue'
import {ref} from 'vue'

const word = ref('test')
</script>

子组件:

<div>Message: {{ message }}</div>
<input :value="message" @input="handleInput">
<script setup lang="ts">
const [message, modifiers] = defineModel('message', {
    type: String,
    default: 'test',
    set(value){
    if(modifiers.capitalize){
      return value.charAt(0).toUpperCase() + value.slice(1)
    }
    return value
    }
})
const handleInput = (e) => {
  message.value = e.target.value
}

注意事项:

  1. 版本要求:vue的版本是3.4+,因为defineModel是在vue3.4之后增加的
  2. 双向绑定:确保父组件和子组件之间的数据流式清晰一致的
### Vue 3.4 版本中的组件使用方法与示例 #### 新特性的概述 Vue 3.4 增加了一些新的功能,其中包括 `v-bind` 同名简写的语法糖以及 `defineModel` 宏的支持[^3]。这些新特性使得开发者能够更高效地编写代码并简化模板结构。 #### 使用 `defineModel` 的例子 下面是一个简单的例子展示如何利用 `defineModel` 来创建双向绑定模型: ```javascript <script setup> import { defineModel } from &#39;vue&#39; const model = defineModel() </script> <template> <input :value="model" @input="$event => model = $event.target.value"> </template> ``` 上述代码片段展示了如何通过 `defineModel` 创建一个可以被父级组件控制的响应式变量,并实现自动更新的功能[^2]。 #### 利用 `v-bind` 简化属性传递的例子 另一个值得注意的新特性就是 `v-bind` 的同名简写形式。这允许我们更加简洁地将对象内的键值对映射至子组件的 prop 上面去: ```html <!-- ParentComponent.vue --> <ChildComponent v-bind="parentObject"/> <!-- ChildComponent.vue --> <script setup> defineProps({ keyA: String, keyB: Number }) </script> ``` 在这个场景下, 如果 `parentObject` 是 `{keyA:&#39;value&#39;, keyB:1}` ,那么它会自动匹配到子组件定义好的 Props 中。 #### 关于多 `v-model` 支持的应用实例 对于需要多个数据同步的情况,我们可以借助 Vue 提供的多 `v-model` 功能来达成目标。如下所示: ```html <CustomForm v-model:name="form.name" v-model:email="form.email"/> <script setup> let form = reactive({name:&#39;&#39;, email:&#39;&#39;}); </script> ``` 这里体现了 Vue 对复杂表单管理的强大能力——即允许多字段的同时绑定[^1]。 #### 结合懒加载和去除空白字符修饰符的实际应用 最后值得一提的是,在实际开发过程中经常需要用到一些内置修饰符如 `.lazy`,`.trim` 等等。比如希望只有当失去焦点的时候才触发事件或者清除掉不必要的前后空格时就可以这样操作[^4]: ```html <input v-model.lazy.trim="searchQuery"> ``` 以上便是关于 Vue 3.4 组件的一些基本介绍及其具体使用的几个典型范例。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值