灏天阁

Vue3 中常用 API(v-model、v-memo、useAttrs、defineExpose、computed、watch)

· Yin灏

v-model(支持多个v-model

语法:v-model:自定义事件名 = “数据或方法”

  1. v-model 没有事件名,默认为 modelValue,如:v-model="data" 等于 v-model:modelValue="data"

!注意:一个标签只能有一个 v-model 没有事件名,使用多个 v-model 时,要加不同的名字来区分

  1. 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的方式。

结果:

image.png

新增指令 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,其他的数据和方法被他接收

image.png

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>

结果:

image.png

computed 计算属性

watch 和 WatchEffect 监听

之前的文章,单独详细描述过这两个属性,感兴趣的同学可点击下方链接前往 d

点击此处,前往查看详细介绍

- Book Lists -