首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >即使使用this.nextTick,Vuejs也无法在mounted()之后访问dom元素。使用chartjs

即使使用this.nextTick,Vuejs也无法在mounted()之后访问dom元素。使用chartjs
EN

Stack Overflow用户
提问于 2019-10-29 18:12:36
回答 1查看 490关注 0票数 2

这是我的子元素

代码语言:javascript
复制
<template lang="html">
  <div class="row">
    <div class="col-lg-8 col-md-8 col-sm-12 col-xs-12">
      <bar-chart :v-if="this.barChartReadyToBeRendered" :chart-data='null' :height="340"></bar-chart>
    </div>
    <div class="flex-col-docs col-lg-3">
      <div class="column" style="height: 150px">
        <div class="col">
            <q-select dark stack-label="Show Targets" class="select-notification"
              v-model="selectTargetNotification"
              :options="this.getTargetChangeOptions"
            />
        </div>
        <div class="col">
            <q-select dark stack-label="Agency" class="select-notification"
              v-model="selectOrgNotification"
              :options="this.getOrganisationOptions"
            />
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import BarChart from '../../components/BarChart'

export default {
  components: {
    BarChart
  },

.
.
/* Other code */

mounted () {
    console.log('OUTSIDE MOUNTED')
    this.$nextTick(() => {
      console.log(this.$el)
      let ctx = document.getElementById('bar-chart')
      console.log('WWWWWWWWWWWWWWWWWW')
      console.log(ctx)
      console.log(this.$el)
      this.createChart('bar-chart')
    })
  }

</script>

条形图is是

代码语言:javascript
复制
<script>
import { Bar, mixins } from 'vue-chartjs'
const { reactiveProp } = mixins

export default {
  extends: Bar,
  mixins: [reactiveProp],
  props: ['options'],
  mounted () {
    this.renderChart(this.chartData, this.options)
  }
}
</script>

<style>
</style>

在我的父元素中,模板是

代码语言:javascript
复制
<template>
  <q-page padding class="row justify-center">
    <div style="width: 80vw; max-width: 100vw;">
      <div class="flex-row-docs">
        <div class="doc-container">
          <q-list no-border>
            <div class="row justify-start">
              <div class="col-6">
                <target-changes-agency></target-changes-agency>
              </div>
            </div>
            <div class="q-mb-md q-mt-md q-headline">Full coverage</div>
            <span v-if="!isNewsByIdLoaded" class="row justify-center">
              <q-spinner-mat :size="36" style="color: #027be3ff; text-align: justify; margin: 2rem;" />
            </span>
            <div class="row">
              <article-cluster :isNewsByIdLoaded="isNewsByIdLoaded"></article-cluster>
            </div>
          </q-list>
        </div>
      </div>
    </div>
  </q-page>
</template>

我期望console.log(ctx)和console.log(this.$el),但是这两个命令的输出分别是null<!-- -->

我认为是挂载的,这个.$nextTick()将允许我访问DOM。这里我漏掉了什么?请帮帮忙谢谢

EN

回答 1

Stack Overflow用户

发布于 2019-11-02 02:45:29

为什么要假设document.getElementById('bar-chart')会返回任何元素?没有正在创建的具有该ID的元素。您正在寻找的是document.getElementsByTagName('bar-chart'),但这也不会产生任何结果,因为Vue不会在内部创建Web Components,而是在适当的位置插入组件的根元素。因此,您可以做的是为bar-chart组件提供一个id属性,该属性将自动传递给根元素。

下一个问题是,只有当v-if中的条件为真时,您的bar-chart组件才可见。这可能不是第一次加载组件时的情况。在这个可运行的最小示例中,我简单地设置了v-if="false"

代码语言:javascript
复制
const { Bar, mixins } = VueChartJs
const { reactiveProp } = mixins

const BarChart = Vue.component('bar-chart', {
  extends: Bar,
  mixins: [reactiveProp],
  props: ['options'],
  mounted () {
    //this.renderChart(this.chartData, this.options) 
    this.$nextTick(() => {
        console.log('mounted bar-chart component:');
        console.log(this.$el)
    });
  }
});

Vue.component('example-component', {
  template: `<div><bar-chart v-if="false" id="barchart" chart-data="null" height="340"></bar-chart></div>`,
  components: [BarChart],
  mounted () {
      this.$nextTick(() => {
        console.log('mounted child component:');
        let ctx = document.getElementById('barchart')
        console.log(ctx)
        console.log(this.$el)
      })
    }
});

// create a new Vue instance and mount it to our div element above with the id of app
var vm = new Vue({
  el: '#app'
});
代码语言:javascript
复制
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.min.js"></script>
<script src="https://unpkg.com/vue-chartjs@3.5.0/dist/vue-chartjs.min.js"></script>
<div id="app">
  <example-component></example-component>
</div>

(堆栈代码片段控制台实际上隐藏了<!-- -->,但您可以在此codepen中看到它。Vue自动插入这个空的HTML注释,作为当前未显示的组件的占位符。)

输出实际上是预期的,因为没有呈现bar-chart组件,因此this.$el (指子组件,而不是bar-chart组件)为空。

下面是与bar-chart组件上的v-if="true"相同的代码片段:

代码语言:javascript
复制
const { Bar, mixins } = VueChartJs
const { reactiveProp } = mixins

const BarChart = Vue.component('bar-chart', {
  extends: Bar,
  mixins: [reactiveProp],
  props: ['options'],
  mounted () {
    //this.renderChart(this.chartData, this.options) 
    this.$nextTick(() => {
        console.log('mounted bar-chart component:');
        console.log(this.$el)
    });
  }
});

Vue.component('example-component', {
  template: `<div><bar-chart v-if="true" id="barchart" chart-data="null" height="340"></bar-chart></div>`,
  components: [BarChart],
  mounted () {
      this.$nextTick(() => {
        console.log('mounted child component:');
        let ctx = document.getElementById('barchart')
        console.log(ctx)
        console.log(this.$el)
      })
    }
});

// create a new Vue instance and mount it to our div element above with the id of app
var vm = new Vue({
  el: '#app'
});
代码语言:javascript
复制
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.min.js"></script>
<script src="https://unpkg.com/vue-chartjs@3.5.0/dist/vue-chartjs.min.js"></script>
<div id="app">
  <example-component></example-component>
</div>

如您所见,日志现在也在bar-chart组件的mounted()钩子中返回了正确的元素。

当然,如果您计划拥有该组件的多个实例,则不应该在组件中使用id属性,因为这将导致多个元素具有相同的ID,这是无效的HTML,并且可能导致意外的干扰。因此,在这个最小的示例中,这只是为了演示目的。在实际代码中,您可以使用Vue's ref attribute,然后可以通过父组件中的this.$refs引用它。

在你的代码中还有另外两个问题:

  1. 您不需要在v-if前面使用冒号,因为它会自动绑定到作为其值给定的表达式。
  2. 您不需要在表达式中使用this.,您将自动处于组件上下文中,并且只需直接使用属性的名称。
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58605315

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档