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监测值,在值改变时执行更多操作。


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

相关推荐
qq_12498707531 小时前
基于springboot的会议室预订系统设计与实现(源码+论文+部署+安装)
java·vue.js·spring boot·后端·信息可视化·毕业设计·计算机毕业设计
ttod_qzstudio3 小时前
Vue 3 中 toRaw 的取舍之道:以 Babylon.js 3D 开发为例
vue.js·babylonjs
Mr Xu_3 小时前
Vue3 + Element Plus 实战:App 版本管理后台——动态生成下载二维码与封装文件上传
前端·javascript·vue.js
比特森林探险记3 小时前
Vue基础语法与响应式系统详解
前端·javascript·vue.js
zihan03214 小时前
element-plus, el-table 表头按照指定字段升降序的功能实现
前端·vue.js·状态模式
三翼鸟数字化技术团队4 小时前
watchEffect的两种错误用法
前端·javascript·vue.js
娟宝宝萌萌哒5 小时前
智能体设计模式重点
人工智能·设计模式
我是伪码农6 小时前
Vue 1.28
前端·javascript·vue.js
Andy&lin6 小时前
【医疗】智慧病房APP原型模板
设计模式·产品运营·人机交互·交互·健康医疗
Engineer邓祥浩6 小时前
设计模式学习(22) 23-20 解释器模式
学习·设计模式·解释器模式