cqwcns 发表于 2023-2-17 17:14

JS,EChart+ElementPlus的使用问题

我希望在ElementPlus的drawer组件中渲染EChart图表。


如果图表容器在drawer组件外则没有问题,所以应该是由于drawer组件在文档初始化时并不在dom节点,EChart无法渲染。
我不知道如何解决,请各位大佬指教,感谢。


以下是一个简单的测试demo。

<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>测试</title>

    <!-- style -->
    <link rel="stylesheet" href="https://candyissupersweet.gitee.io/cdn/element-plus/element.plus.index.css" />
    <!-- Vue 3 -->
    <script src="https://candyissupersweet.gitee.io/cdn/vue3/vue.global.prod.js"></script>
    <!-- component library -->
    <script src="https://candyissupersweet.gitee.io/cdn/element-plus/element.plus.full.min.js"></script>
    <!-- echarts -->
    <script type="text/javascript" src="https://candyissupersweet.gitee.io/cdn/echarts/echarts.min.js"></script>
</head>

<body>
    <div id="app" style="width: 100vw;height: 100vh;">

      <el-button type="primary" @click="doOpen">打开</el-button>

      <!-- 如果图表容器在drawer外,则可以正常渲染图表 -->
      <!-- <div id="container" style="width: 100%;height: 100%;"></div> -->

      <el-drawer v-model="drawer" title="图表" direction="btt" size="100%">
            <!-- 如果图表容器在drawer内,则渲染图表失败 -->
            <div id="container" style="width: 100%;height: 100%;"></div>
      </el-drawer>

    </div>

    <script>
      let that = null, App = null, myChart = null;


      App = {
            data() {
                return {
                  drawer: false
                }
            },
            mounted() {
                that = this;

            },
            methods: {
                doOpen() {
                  console.log('开始');

                  // 先显示容器
                  that.drawer = true;

                  // 如果没有初始化,就进行初始化
                  if (!myChart) myChart = echarts.init(document.getElementById('container'));

                  const option = {
                        xAxis: {
                            type: 'category',
                            data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
                        },
                        yAxis: {
                            type: 'value'
                        },
                        series: [
                            {
                              data: ,
                              type: 'line',
                              smooth: true
                            }
                        ]
                  };
                  myChart.setOption(option);
                }
            }
      }

      const app = Vue.createApp(App);
      app.use(ElementPlus);
      app.mount("#app");
    </script>
</body>

</html>

notproblem 发表于 2023-2-17 17:23

<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>测试</title>

    <!-- style -->
    <link rel="stylesheet" href="https://candyissupersweet.gitee.io/cdn/element-plus/element.plus.index.css" />
    <!-- Vue 3 -->
    <script src="https://candyissupersweet.gitee.io/cdn/vue3/vue.global.prod.js"></script>
    <!-- component library -->
    <script src="https://candyissupersweet.gitee.io/cdn/element-plus/element.plus.full.min.js"></script>
    <!-- echarts -->
    <script type="text/javascript" src="https://candyissupersweet.gitee.io/cdn/echarts/echarts.min.js"></script>
</head>

<body>
    <div id="app" style="width: 100vw;height: 100vh;">

      <el-button type="primary" @click="doOpen">打开</el-button>

      <!-- 如果图表容器在drawer外,则可以正常渲染图表 -->
<!--      <div id="container" style="width: 100%;height: 100%;"></div> -->

      <el-drawer v-model="drawer" title="图表" direction="btt" size="100%">
            <!-- 如果图表容器在drawer内,则渲染图表失败 -->
            <div id="container" style="width: 100%;height: 100%;"></div>
      </el-drawer>

    </div>

    <script>
      let that = null, App = null, myChart = null;


      App = {
            data() {
                return {
                  drawer: false
                }
            },
            mounted() {
                that = this;

            },
            methods: {
                doOpen() {
                  console.log('开始');

                  // 先显示容器
                  that.drawer = true;

                  // 如果没有初始化,就进行初始化
                                        this.$nextTick(() => {
                                                if (!myChart) myChart = echarts.init(document.getElementById('container'));
                                               
                                                const option = {
                                                  xAxis: {
                                                        type: 'category',
                                                        data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
                                                  },
                                                  yAxis: {
                                                        type: 'value'
                                                  },
                                                  series: [
                                                        {
                                                            data: ,
                                                            type: 'line',
                                                            smooth: true
                                                        }
                                                  ]
                                                };
                                                myChart.setOption(option);
                                        })
                }
            }
      }

      const app = Vue.createApp(App);
      app.use(ElementPlus);
      app.mount("#app");
    </script>
</body>

</html>

imyxuan 发表于 2023-2-17 19:34

Drawer 的内容是懒渲染的,即在第一次被打开之前,传入的默认 slot 不会被渲染到 DOM 上。 因此,如果需要执行 DOM 操作,或通过 ref 获取相应组件,请在 open 事件回调中进行。
因此,不要在点击按钮的时候进行表格初始化操作,在el-drawer的open事件中执行就好。
<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>测试</title>

    <!-- style -->
    <link rel="stylesheet"/>
    <!-- Vue 3 -->
    <script src="https://candyissupersweet.gitee.io/cdn/vue3/vue.global.prod.js"></script>
    <!-- component library -->
    <script src="https://candyissupersweet.gitee.io/cdn/element-plus/element.plus.full.min.js"></script>
    <!-- echarts -->
    <script type="text/javascript" src="https://candyissupersweet.gitee.io/cdn/echarts/echarts.min.js"></script>
</head>

<body>
    <div id="app" style="width: 100vw;height: 100vh;">

      <el-button type="primary" @click="doOpen">打开</el-button>

      <!-- 如果图表容器在drawer外,则可以正常渲染图表 -->
      <!-- <div id="container" style="width: 100%;height: 100%;"></div> -->

      <el-drawer v-model="drawer" title="图表" direction="btt" size="100%" @open="onOpen">
            <!-- 如果图表容器在drawer内,则渲染图表失败 -->
            <div id="container" style="width: 100%;height: 100%;"></div>
      </el-drawer>

    </div>

    <script>
      let that = null, App = null, myChart = null;


      App = {
            data() {
                return {
                  drawer: false
                }
            },
            mounted() {
                that = this;

            },
            methods: {
                doOpen() {
                  console.log('开始');

                  // 先显示容器
                  that.drawer = true;
                  
                },
                onOpen() {
                  if (!myChart) myChart = echarts.init(document.getElementById('container'));

                  const option = {
                        xAxis: {
                            type: 'category',
                            data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
                        },
                        yAxis: {
                            type: 'value'
                        },
                        series: [
                            {
                              data: ,
                              type: 'line',
                              smooth: true
                            }
                        ]
                  };
                  myChart.setOption(option);
                },
            }
      }

      const app = Vue.createApp(App);
      app.use(ElementPlus);
      app.mount("#app");
    </script>
</body>

</html>
页: [1]
查看完整版本: JS,EChart+ElementPlus的使用问题