组件v-model
父组件内
<NavSearch v-model="searchForm" @onSearch="onSearch" />
const selectParams = ref({
name: null,
address: null,
desc: null
})
我们在子组件上定义v-model
用于双向绑值,父组件内需要定义一个绑定的变量searchForm
子组件
然后在子组件内通过defineProps
接收父组件绑定的值
const props = defineProps({
modelValue: {
type: Function,
default: () => ({
name: null,
address: null,
desc: null
}),
},
});
const { modelValue } = toRefs(props);
通过toRefs
解构defineProps
内的modelValue
,这样子组件的表单就可以直接使用modelValue
了
子组件内点击搜索按钮,此时通过update:modelValue
事件回传改值
const emit = defineEmits(["update:modelValue", "onSearch"]);
const onSearch = () => {
// 子组件直接修改modelValue的值,update:modelValue表示修改modelValue,修改为第二个参数的值
emit("update:modelValue", modelValue.value);
// 搜索时返回一个事件,父组件内执行查询列表
emit("onSearch");
};
父组件
<NavSearch v-model="searchForm" @onSearch="onSearch" />
const onSearch = () => {
console.log("查询列表", searchForm.value);
};
通过给组件绑定v-model
让父子组件的数据双向互通,父组件可以拿到最新的值。
分页组件的封装
这里举例一个分页组件的封装,通过v-model
双向绑定,数据修改后通知父组件更新
// 父组件
<pagination v-model="pageInfo" @change="onPageChange" />
const pageInfo = ref({
num: 1,
size: 12,
total: 50
});
const onPageChange = () => {
console.log('分页变化', pageInfo.value);
};
// 子组件
<template>
<a-pagination
:current="modelValue.num"
:page-size="modelValue.size"
:total="modelValue.total"
:page-size-options="[12, 24, 36, 48, 60]"
size="medium"
show-total
show-jumper
show-page-size
@change="onPageChange"
@page-size-change="onPageSizeChange"
/>
</template>
<script setup lang="ts">
// 子传父事件
const emit = defineEmits(['update:modelValue', 'change']);
// 接收父组件v-model
const props = defineProps({
modelValue: {
type: Object,
default: () => ({
num: 1,
size: 12,
total: 0
})
}
});
// 用toRefs变为可修改响应式,用于组件绑值,但无法直接影响父组件
const { modelValue } = toRefs(props);
// 当前页发生变化
const onPageChange = (current: number) => {
// 先修改modelValue
modelValue.value.num = current;
// 通过update:modelValue事件修改父组件绑定的modelValue
emit('update:modelValue', modelValue);
// 子组件返回事件,通知父组件更新
emit('change');
};
// 当前分页大小发生变化
const onPageSizeChange = (size: number) => {
// 先修改modelValue
modelValue.value.size = size;
// 通过update:modelValue事件修改父组件绑定的modelValue
emit('update:modelValue', modelValue);
// 子组件返回事件,通知父组件更新
emit('change');
};
</script>
另外,你也可以通过withDefaults
为defineProps
标注数据类型,结果是一样的
interface IProps {
modelValue: {
num: number;
size: number;
total: number;
};
}
const props = withDefaults(defineProps<IProps>(), {
modelValue: () => ({
num: 1,
size: 12,
total: 0
})
});
const { modelValue } = toRefs(props);
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。