长沙的网站建设公司哪家好,wordpress 做企业站,关于酒店网站建设的摘要,WordPress一键开启全站SSL前言
随着 Vue3.4 版本的发布#xff0c;defineModel 也正式转正了。它可以简化父子组件之间的双向绑定#xff0c;是目前官方推荐的双向绑定实现方式。
defineModel 使用
在开发的过程中#xff0c;如果有需要通过子组件进行状态更新的话#xff0c;v-model是一个绕不开…前言
随着 Vue3.4 版本的发布defineModel 也正式转正了。它可以简化父子组件之间的双向绑定是目前官方推荐的双向绑定实现方式。
defineModel 使用
在开发的过程中如果有需要通过子组件进行状态更新的话v-model是一个绕不开的点。以前的v-model是这样用的
Vue3中得 v-model 默认解析成 :modelValue 与 update:modelValue
!-- Father.vue --
templatespannum:{{ num }}/spanhr /Child v-modelnum /
/templatescript langts setup
import { ref } from vue
import Child from ./Child.vue
const num refnumber(0)
/script
!-- Child.vue --
templatenum: {{ modelValue }}button clickonClickcount/button
/templatescript langts setup
const $props defineProps{ modelValue: number }()
const $emits defineEmits{(e: update:modelValue, newCount: number): void// 注册update:modelValue事件作为状态更新的回调
}()
function onClick() {$emits(update:modelValue, $props.modelValue 1)// 状态更新时发布事件
}
/script
在有了defineModel之后我们就可以在Child.vue中这样实现
!-- Child.vue --
templatenum: {{ num }}button clickonClickcount/button
/templatescript langts setup
// 一步到位完成事件注册和监听状态变化并发布事件
const num defineModel({ type: Number, default: 0 })
// 单个v-model绑定等价于如下
// const num defineModel(modelValue, { type: Number, default: 0 })
function onClick() {num.value 1
}
/script
defineModel如何实现多个 v-model 绑定
!-- Father.vue --
templatespannum1: {{ num1 }}/spanspannum2: {{ num2 }}/spanhr /Child v-model:num1num1 v-model:num2num2 /
/templatescript langts setup
import { ref } from vue
import Child from ./Child.vue
const num1 refnumber(0)
const num2 refnumber(0)
/script
!-- Child.vue --
templatenum1: {{ num1 }} num2: {{ num2 }}button clickonClick1/button
/templatescript langts setup
const num1 defineModel(num1, { type: Number, default: 20 })
const num2 defineModel(num2, { type: Number, default: 20 })
// 一步到位完成事件注册和监听状态变化并发布事件
function onClick() {num1.value 1num2.value 1
}
/script
实现原理
!-- Father.vue --
templatespannum:{{ num }}/spanhr /Child v-modelnum /
/templatescript langts setup
import { ref } from vue
import Child from ./Child.vue
const num refnumber(0)
/script
!-- Child.vue --
templatenum: {{ num }}button clickonClickcount/button
/templatescript langts setup
import { ref, watch } from vue
const $props defineProps{ modelValue: number }()
const $emits defineEmits{(e: update:modelValue, newCount: number): void
}()const num ref()watch(() $props.modelValue,() {num.value $props.modelValue},{// 回调函数会在watch创建时立即执行一次immediate: true}
)
watch(num, () {$emits(update:modelValue, num.value)
})function onClick() {num.value 1
}
/script等同于如下
!-- Child.vue --
templatenum: {{ num }}button clickonClickcount/button
/templatescript langts setup
const num defineModel({ type: Number, default: 0 })function onClick() {num.value 1
}
/script defineModel其实就是在子组件内定义了一个ref变量num和modelValue的props。 watch了props中的modelValue,watch创建时立即执行一次将props中的modelValue赋值给num。当props中的modelValue的值改变后会同步更新num变量的值。 watch了ref变量num当在子组件内改变num变量的值后会抛出update:modelValue事件 父组件收到这个事件后就会更新父组件中对应的变量值。
其实defineModel的源码中是使用 customRef 和 watchSyncEffect 去实现的我这里是为了让大家能够更容易的明白defineModel的实现原理才举的ref和watch的例子。