vue3[setup]父组件传递子组件数据同步更新四种方法以及性能分析

问题与原因

  • 问题: 本文章解决的问题是当父组件传递给子组件的值发生改变后,子组件不能立刻改变的问题。如下图代码所示,子组件的loading变量没有发生改变。
js 复制代码
//父组件
<template>
<div class="page">
    <loadingVue :process="load"/>
</div>
</template>
<script setup>
import { ref } from "vue";
import loadingVue from "../components/loading.vue";
let load = ref(0);
setInterval(() => {
    if(load.value == 100){
        load.value = 0;
    }else{
        load.value +=10;
    }
}, 1000)
</script>
js 复制代码
//子组件
<template>
    <div class="load_component">
        <div class="petal" v-for="index in sum" :style="`transform: rotate(${-60+index*360/sum}deg)`"></div>
        <div class="flowerCore"></div>
        <div class="loading_text">loading<span>...</span></div>
        <div class="process_text"><div class="span">{{ loading }}</div> % </div>
    </div>
</template>
<script setup name="loading">
import { computed, ref, watch } from "vue";
let sum = ref(6);
let props = defineProps(["process"]);
let loading = ref(props["process"]);
</script>
  • 原因: 原因是接收父组件传递的值赋值在props变量里,而loading变量拷贝了props["process"]的值后,不会再关联props的改变。

解决方法

直接使用props

既然父组件传递的值是由props接收,那么直接使用props变量就好了。

缺点:代码会很杂乱,容易堆史山。

  • 修改后代码:
js 复制代码
//子组件
<template>
    <div class="load_component">
        <div class="petal" v-for="index in sum" :style="`transform: rotate(${-60+index*360/sum}deg)`"></div>
        <div class="flowerCore"></div>
        <div class="loading_text">loading<span>...</span></div>
        <div class="process_text"><div class="span">{{ props["process"] }}</div> % </div>
    </div>
</template>
<script setup name="loading">
import { computed, ref, watch } from "vue";
let sum = ref(6);
let props = defineProps(["process"]);

使用key

给子组件加上keykey的值为父组件传入子组件的值。

缺点:1. 若父传子的值不止一个,那使用哪一个作为key呢?2. 每次改变都会重新渲染整个子组件,容易降低性能。

  • 修改后代码:
js 复制代码
//父组件
<template>
<div class="page">
    <loadingVue :process="load" :key="load"/>
</div>
</template>
<script setup>
import { ref } from "vue";
import loadingVue from "../components/loading.vue";
let load = ref(0);
setInterval(() => {
    if(load.value == 100){
        load.value = 0;
    }else{
        load.value +=10;
    }
}, 1000)
</script>

使用computed

loading变量使用computed属性,同步computed["process"]的变化。

  • 修改后代码:
js 复制代码
//子组件
<template>
    <div class="load_component">
        <div class="petal" v-for="index in sum" :style="`transform: rotate(${-60+index*360/sum}deg)`"></div>
        <div class="flowerCore"></div>
        <div class="loading_text">loading<span>...</span></div>
        <div class="process_text"><div class="span">{{ loading }}</div> % </div>
    </div>
</template>
<script setup name="loading">
import { computed, ref, watch } from "vue";
let sum = ref(6);
let props = defineProps(["process"]);
let loading = computed(()=>{
    return props["process"]
})

使用watch

watch监测props["process"]值的改变。

缺点:watch只是监听,监听后还需要更进一步的操作,不便捷、清晰。

  • 修改后代码:
js 复制代码
//子组件
<template>
    <div class="load_component">
        <div class="petal" v-for="index in sum" :style="`transform: rotate(${-60+index*360/sum}deg)`"></div>
        <div class="flowerCore"></div>
        <div class="loading_text">loading<span>...</span></div>
        <div class="process_text"><div class="span">{{ loading }}</div> % </div>
    </div>
</template>
<script setup name="loading">
import { computed, ref, watch } from "vue";
let sum = ref(6);
let props = defineProps(["process"]);
watch(()=>props["process"],(val,pre)=>{
    loading.value = val;
})

性能分析

  • 推荐: computed > watch > key
  • 理由:
  1. key会导致整个组件重新渲染,降低性能。
  2. computedwatch的代码更简洁清晰。
  3. computed内存有缓存机制(复用),效率更高,调试方便。

可使用watch监测值,在值改变时执行更多操作。


那么文章到这里就结束啦,祝大家好运常来

相关推荐
想学后端的前端工程师4 分钟前
【Vue3组合式API实战指南:告别Options API的烦恼】
前端·javascript·vue.js
毕设源码-邱学长2 小时前
【开题答辩全过程】以 基于VUE的藏品管理系统的设计与实现为例,包含答辩的问题和答案
前端·javascript·vue.js
学习CS的小白4 小时前
跨域问题详解
vue.js·后端
周星星日记4 小时前
5.为什么vue中使用query可以保留参数
前端·vue.js
+VX:Fegn08954 小时前
计算机毕业设计|基于springboot + vue作业管理系统(源码+数据库+文档)
数据库·vue.js·spring boot·后端·课程设计
Tzarevich4 小时前
现代前端开发工程化:从 Vite 到 Vue 3 多页面应用实战
vue.js·vite
JIngJaneIL5 小时前
基于java+ vue办公管理系统(源码+数据库+文档)
java·开发语言·前端·数据库·vue.js·spring boot·后端
小北方城市网6 小时前
第4 课:Vue 3 路由与状态管理实战 —— 从单页面到多页面应用
前端·javascript·vue.js
ohyeah6 小时前
用 Vue3 + Coze API 打造冰球运动员 AI 生成器:从图片上传到风格化输出
前端·vue.js·coze
掘金安东尼7 小时前
React 已经改变了,你的 Hooks 也应该改变
前端·vue.js·github