组件双向数据绑定
父组件修改值,子组件同步。子组件修改,父组件更新。
<template>
<input type="text" v-module="name" @update:modelValue="onUpdateName($event)">
</template>
<script>
import { ref } from "vue";
export default {
setup() {
const name = ref("");
const onUpdateName = (event) => {
name.value = event;
};
return { name, onUpdateName };
}
}
</script>
- 向子组件传递单个值,通过
props: ["modelValue"]
接收。
子组件改父组件数据时,使用
emit("update:modelValue", "新值")
进行修改。
- 向子组件传递多个值,通过
props: ["变量名"]
接收。
子组件改父组件数据时,使用
emit("update:变量名", "新值")
进行修改。
customRef
创建一个自定义的 ref 响应式数据,并对其依赖项跟踪和更新触发进行显示控制。
- 实现防抖效果
<template>
<input type="text" v-model="keyword" />
<h1>{{ keyword }}</h1>
</template>
<script>
import { customRef } from "Vue";
export default {
setup() {
// 调用
const keyword = myRef("hello", 500);
return { keyword };
},
};
// 防抖输入框
function myRef (value, delay) {
let timer = null;
return customRef((track, trigger) => {
return {
// 读取数据
get() {
// 通知vue跟踪value的变化
track();
return value;
},
// 更新数据
set(newValue) {
clearTimeout(timer);
timer = setTimeout(() => {
value = newValue;
// 通知vue去重新解析模板
trigger();
}, delay);
}
};
});
};
</script>
setup 语法糖
<script setup></script>
是一种编译时语法糖,用于在单文件组件中使用组合式API。
代码更简洁,性能更强悍,更好的支持 TS。
<!-- 语法格式 -->
<script setup>
// 引入第三方,定义变量、方法等
</script>
defineProps
defineProps 用于接收父组件传递过来的值,可以直接使用无需导入。实质上就是一个 Props 对象。
<!-- 父组件 -->
<template>
<!-- 1.给子组件传参 -->
<Test msg="hello world" />
</template>
<script setup>
import Test from '@/components/Test/Test.vue';
</script>
<!-- 子组件 -->
<template>
<!-- 3.使用传递过来的值 -->
{{ msg }}
</template>
<script setup>
// 2.接收传递过来的 Props
defineProps({
msg: {
type: String, // 类型
required: true, // 是否必传
}
});
// 也可以使用变量接收,使用时要写 props.msg
// const props = defineProps({ msg: String })
</script>
defineEmits
自定义事件。
<!-- 子组件 -->
<template>
<!-- 2.点击触发 -->
<button @click="$emit(delete)">点击事件</button>
</template>
<script setup>
// 1.自定义事件
defineEmits(["delete"])
</script>
<!-- 父组件 -->
<template>
<!-- 3.触发父组件方法 -->
<Test @delete="onDeleteHandler" />
</template>
<script setup>
import Test from '@/components/Test/Test.vue';
// 4.方法逻辑
const onDeleteHandler () => {
console.log("deleted");
}
</script>
defineExpose
向组件外暴露数据。
<!-- 子组件 -->
<template>
<button @click="$emit(delete)">点击事件</button>
</template>
<script setup>
import { ref } from "vue";
const count = ref(0);
// 1. 导出暴露数据
defineExpose({ count });
</script>
<!-- 父组件 -->
<template>
<!-- 3.ref接收数据 -->
<Test ref="instance" />
<button @click="log">获取instance的值</button>
</template>
<script setup>
import Test from '@/components/Test/Test.vue';
import { ref } from "vue";
// 2. 定义变量接收
const instance = ref(null);
const log = () => {
// 4.点击按钮获取暴露的数据
console.log(instance.value.count);
}
</script>