这是我的子元素
<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是
<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>在我的父元素中,模板是
<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。这里我漏掉了什么?请帮帮忙谢谢
发布于 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"。
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'
});<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"相同的代码片段:
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'
});<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引用它。
在你的代码中还有另外两个问题:
v-if前面使用冒号,因为它会自动绑定到作为其值给定的表达式。this.,您将自动处于组件上下文中,并且只需直接使用属性的名称。https://stackoverflow.com/questions/58605315
复制相似问题