vue3父组件传值给子组件,子组件无法实时更新父组件传递值

圆环进度条为例:
在这里插入图片描述
操作父组件修改每个子组件的数据,没能实时更新子组件
1.未解决前的写法
父组件中

<template>
  <div class="process-parent">
    <div class="process-style" v-for="(item, index) in data" :key="index">
      <Process :curent-process="item" />
      <div class="process-button">
        <button @click="processAdd(index)">进度条增加1</button>
        <button @click="processDecrease(index)">进度条递减1</button>
      </div>
    </div>
  </div>
</template>

<script>
import { reactive } from "@vue/reactivity";
import Process from "../components/process.vue";
export default {
  components: {
    Process,
  },
  setup() {
    const data = reactive([
      {
        curentAll: 100,
        curentProcess: 30,
      },
      {
        curentAll: 100,
        curentProcess: 10,
      },
      {
        curentAll: 100,
        curentProcess: 50,
      },
      {
        curentAll: 100,
        curentProcess: 99,
      },
      {
        curentAll: 100,
        curentProcess: 100,
      },
    ]);

    // 方法
    function processAdd(index) {
      data[index].curentProcess++;
      console.log(data);
    }

    function processDecrease(index) {
      data[index].curentProcess--;
      console.log(data);
    }

    return {
      data,
      processAdd,
      processDecrease,
    };
  },
};
</script>
<style lang="scss" scoped>
.process-parent {
  display: flex;
  height: 100vh;
  background: rgb(247, 244, 244);
}
.process-style {
  width: 200px;
  height: 200px;
  // background: #ccc;
  margin-right: 10px;
  margin-top: 100px;
}
.process-button {
  display: flex;
  background: rgb(240, 201, 201);
  margin-right: 5px;
  justify-content: space-between;
}
</style>

子组件中

<template>
  <svg ref="processRef" width="100%" height="100%">
    <!-- 用一个蒙版mask -->
    <mask id="curentProcessMask">
      <circle
        :cx="plan.process_x"
        :cy="plan.process_y"
        :r="plan.process_r"
        :stroke-dasharray="dash(plan.process_r)"
        stroke-width="3"
        stroke="white"
      ></circle>
    </mask>
    <!-- 设置底部最大的圆环 -->
    <circle
      :cx="plan.process_x"
      :cy="plan.process_y"
      :r="plan.process_r"
      stroke-width="3"
      stroke="#444A"
    ></circle>
    <!-- 设置进度条的颜色、长度等,覆盖蒙版 -->
    <circle
      :cx="plan.process_x"
      :cy="plan.process_y"
      :r="plan.process_r"
      :stroke-dasharray="
        planCircle(plan.curentProcess, plan.curentAll, plan.process_r)
      "
      stroke-width="3"
      stroke="#4169E1"
      mask="url(#curentProcessMask)"
    ></circle>
    <!-- 文字 -->
    <text x="50%" y="60%" style="font-size: 30px">
      {
   
   { planPercent(plan.curentProcess, plan.curentAll) }}
      <tspan>%</tspan>
    </text>
  </svg>
</template>
<script>
import { defineComponent, onMounted, reactive, ref, watch } from "vue";
export default defineComponent({
  name: "planProcess",
  props: {
    curentProcess: Object,
  },
  setup(props, context) {
    console.log(props.curentProcess, "传入值");
    //数据初始化
    const plan = reactive({
      curentAll: 0,
      curentProcess: 0,
      process_r: 0,
      process_x: 0,
      process_y: 0,
    });
    const processRef = ref(null);

    // 进度更新
    // const { curentAll, curentProcess } = props.curentProcess;

    // 绑定的方法
    function updateProcess() {
      plan.curentProcess++;
    }

    function planPercent(var1, var2) {
      return ((100 * var1) / var2).toFixed(0);
    }

    function planCircle(var1, var2, r) {
      let girth = 2 * Math.PI * r;
      // 68.17256058289851-当前总进度 219.9114857512855-总的周长
      return (var1 / var2) * girth + " " + girth;
    }

    function dash(r) {
      // 结果:r * 0.3代表每一节周长的长度
      // r * 0.01代表光环上每个周长
      return r * 0.3 + " " + r * 0.01;
    }

    // 初始化更新进度
    updateCurrentProcess(props.curentProcess);
    
    function updateCurrentProcess(newVal) {
	      plan.curentAll = newVal.curentAll;
	      plan.curentProcess = newVal.curentProcess;
    }

    // 生命周期
    onMounted(() => {
      // 设置一下圆的x y 半径
      const setCircle = processRef.value.clientWidth / 2;
      plan.process_r = setCircle - 4;
      plan.process_x = setCircle;
      plan.process_y = setCircle;
      console.log(plan, "获取dom");
    });

    // 绑定的字段和方法
    return {
      plan,
      updateProcess,
      planPercent,
      planCircle,
      dash,
      processRef,
    };
  },
});
</script>
<style scoped lang="scss">
circle {
  transform-origin: center;
  // 旋转后从中上位置开始
  transform: rotate(-90deg);
  fill: #ccc; //内部颜色
  width: 100%;
}
text {
  font-family: "Bahnschrift";
  text-anchor: middle;
  fill: white;
  tspan {
    font-size: 1.2rem;
  }
}
</style>

bug描述
在这里插入图片描述

解决方案:在子组件中添加watch监听父传递过来的对象,获取最新的数据
在子组件中使用watch监听并重新赋值即可

 // 初始化更新进度
    updateCurrentProcess(props.curentProcess);

    // 监听父组件传递子组件数据变化
    watch(props.curentProcess, (newVal, oldValue) => {
      updateCurrentProcess(newVal);
    });

    function updateCurrentProcess(newVal) {
      plan.curentAll = newVal.curentAll;
      plan.curentProcess = newVal.curentProcess;
    }

猜你喜欢

转载自blog.csdn.net/qq_44472790/article/details/121457306