Vue3 中常用 API(v-model、v-memo、useAttrs、defineExpose、computed、watch)
·
Yin灏
v-model(支持多个v-model
)
语法:v-model:自定义事件名 = “数据或方法”
- v-model 没有事件名,默认为 modelValue,如:
v-model="data" 等于 v-model:modelValue="data"
!注意:一个标签只能有一个 v-model 没有事件名,使用多个 v-model 时,要加不同的名字来区分
- v-model 有事件名,如:v-model:name=“data”
<!-- 父组件 -->
<template>
<div>
<div>姓名:{{ data.name }}</div>
<div>年龄:{{ data.age }}</div>
<Child v-model="data.name" v-model:age="data.age"></Child>
</div>
</template>
<script setup lang="ts">
import Child from "./Child.vue";
import { reactive } from "vue";
const data = reactive({
name: "大哥",
age: 55,
});
// 方便观察数据的变换
watchEffect(() => {
console.log(data.name, data.age);
});
</script>
<!-- 子组件 -->
<template>
<div>
<button @click="updataMsg">更新数据</button>
</div>
</template>
<script lang="ts" setup>
import { ref } from "vue";
const emits = defineEmits<{
(e: "update:modelValue", value: string): void;
(e: "update:age", value: Number): void;
}>();
const updataMsg = () => {
emits("update:modelValue", "二弟");
emits("update:age", 22);
};
</script>
代码中用到了defineEmits 函数的泛型参数
用于声明事件的名称和参数类型。
注意:不再是像 Vue2 那样使用$emit('input')
了,而是统一使用update:xxx
的方式。
结果:
新增指令 v-memo
v-memo
主要功能是提高性能,避免不必要的重新渲染
Vue 组件状态改变引起组件重新渲染,在大量元素的情况下,可能会导致性能问题,为了解决这些问题,v-memo
允许开发者明确告诉 Vue,当依赖的内容没有变化时,不需要重新渲染该部分的内容。
<template>
// 只有 valueA, valueB 发生变化重新渲染
<div v-memo="[valueA, valueB]">...</div>
</template>
$attrs
Vue3 中,
$attrs
包含父组件中除 props 和自定义事件外的所有属性集合。(父组件传递的参数,defineProps()
没接收的参数,都由useAttrs()
接收)
<!-- 父组件 -->
<template>
<div>
<Child :name="data.name" :age="data.age"></Child>
</div>
</template>
<script setup lang="ts">
import Child from "./Child.vue";
import { reactive } from "vue";
const data = reactive({
name: "大哥",
age: 55,
});
</script>
<!-- 子组件 -->
<template>
<div>
<div>{{ props.name }}</div>
</div>
</template>
<script lang="ts" setup>
import { ref, useAttrs } from "vue";
// 接收父组件传递数据
const props = defineProps(["name"]);
// 用VueUse方法获得,除props之外的参数
const attrs = useAttrs();
console.log(attrs);
</script>
结果:
在代码中,父组件传递了两个参数,子组件只接收了 data.name,打印 attrs,其他的数据和方法被他接收
defineExpose()
在
Vue2
中,经常使用ref
来拿到子组件里的任意数据及方法,但在Vue3
中则必须使用defineExpose
暴露子组件内的方法或属性才能被父组件所调用。
<!-- 父组件 -->
<template>
<div>
<Child ref="childRef"></Child>
</div>
</template>
<script setup lang="ts">
import Child from "./Child.vue";
import { ref, onMounted } from "vue";
const childRef = ref();
// 在挂载后获取,在setup中执行的话,获取不到
onMounted(() => {
childRef.value.getData();
childRef.value.data;
console.log(childRef.value.data);
});
</script>
<!-- 子组件 -->
<script lang="ts" setup>
import { ref } from "vue";
const getData = () => {
console.log("子组件方法");
};
const data = ref("子组件数据");
defineExpose({
getData,
data,
});
</script>
结果:
computed 计算属性
watch 和 WatchEffect 监听
之前的文章,单独详细描述过这两个属性,感兴趣的同学可点击下方链接前往 d