常见问题

91 阅读2分钟

1VUE父子组件优先级\color{green}{1、VUE 父子组件优先级}

父组件的 beforeCreate
父组件的 created
父组件的 beforeMount
子组件的 beforeCreate
子组件的 created
子组件的 beforeMount
子组件的 mounted
父组件的 mounted
父组件的 beforeUpdate
子组件的 beforeUpdate
子组件的 updated
父组件的 updated
父组件的 beforeDestroy
子组件的 beforeDestroy
子组件的 destroyed
父组件的 destroyed

关键点分析

  1. 父组件的异步请求

    • 如果父组件在 created 钩子中发起的是同步操作(例如直接设置一个变量),那么子组件在 mounted 钩子中可以正常拿到值。
    • 如果父组件在 created 钩子中发起的是异步操作(例如通过 axios 或 fetch 请求数据),那么子组件在 mounted 钩子中可能拿不到值,因为异步请求尚未完成。
  2. Vue 的响应式机制

    • Vue 的响应式系统会自动更新子组件接收到的 props 数据。如果父组件的数据在异步请求完成后更新,子组件会重新渲染并接收到最新的值。
  3. 生命周期顺序

    • 父组件的 created 钩子会在子组件的 mounted 钩子之前执行。
    • 但是,由于异步请求的延迟,父组件的数据更新可能会晚于子组件的 mounted 钩子。

解决方案

方案 1:使用 watch 监听 props

在子组件中监听从父组件传递的 props,当数据更新时再执行相关逻辑。

javascript
深色版本
// 子组件
export default {
  props: ["message"],
  watch: {
    message(newVal) {
      console.log("子组件监听到的新值:", newVal);
      // 在这里处理新值
    }
  },
  mounted() {
    console.log("子组件初始值:", this.message);
  }
};

优点

  • 能够及时响应父组件传递的数据变化。

方案 2:使用 v-if 控制子组件渲染

确保父组件的数据加载完成后再渲染子组件。

html
深色版本
<!-- 父组件模板 -->
<template>
  <div>
    <ChildComponent v-if="message" :message="message" />
  </div>
</template>
javascript
深色版本
// 父组件
export default {
  data() {
    return {
      message: null
    };
  },
  async created() {
    const response = await new Promise((resolve) =>
      setTimeout(() => resolve("Async Data"), 1000)
    );
    this.message = response;
  }
};

优点

  • 子组件只会在数据准备好后渲染,避免了空值问题。

2Echart渲染宽度问题\color{green}{2、Echart渲染宽度问题}

当在Vue应用中使用Echarts时,如果在DOM未渲染完成时初始化图表,可能导致宽度溢出。一种简单的修复方式是在调用setOption前先调用resize()方法。

1. 安装并引入

npm install echarts --save
//main.js// 
import echarts from 'echarts';
import * as echarts from 'echarts'; // 如果安装的是echarts 5以上版本,则需此种方式引入Vue.prototype.$echarts = echarts

2. 定义防抖函数

传送门:Vue中 实现函数的防抖、节流及应用场景

// utils/common.js // 防抖
function _debounce(fn, delay = 300) {  
    var timer = null;  
    return function () {    
        var _this = this;    
        var args = arguments;    
        if (timer) clearTimeout(timer);    
        timer = setTimeout(function () {     
            fn.apply(_this, args);    
            }, delay);  };
   } 
   
export{  
    _debounce
}

3.  绘制图表代码

<template>
  <div class="charts">
    <div id="lineChart" :style="{ width: '100%', height: '400px' }"></div>
  </div>
</template>
 
<script>
import { _debounce } from '@/utils/common.js'
export default {
  data() {
    return {};
  },
  methods: {
    drawLine() {
      // 基于准备好的dom,初始化echarts实例
      let lineChart = this.$echarts.init(document.getElementById("lineChart"));
      lineChart.setOption({
        title: {
          text: "雨量流量关系图",
          x: "center",
        },
        xAxis: {
          type: "category",
          data: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
        },
        yAxis: {
          type: "value",
        },
        series: [
          {
            data: [820, 932, 901, 934, 1290, 1330, 1320],
            type: "line",
          },
        ],
      });
    },
    resizeCharts:_debounce(function(){
      this.$echarts.init(document.getElementById('lineChart')).resize()
    },500)
  },
  mounted() {
    this.drawLine();
    //刚进页面估计要this.resizeCharts();调一下
    window.addEventListener('resize',this.resizeCharts);
  },
  beforeDestroy () {
    window.removeEventListener('resize',this.resizeCharts);
  },
};
</script>