programing

vuejs는 이 . nextTick을 사용해도 mounted() 후 dom 요소에 액세스할 수 없습니다.chartjs 사용

goodcopy 2022. 7. 26. 22:50
반응형

vuejs는 이 . nextTick을 사용해도 mounted() 후 dom 요소에 액세스할 수 없습니다.chartjs 사용

이것은 내 자식 요소입니다.

<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>

막대 차트 js는

<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(이것)가 필요합니다.$el) 단, 이들 2개의 출력은null그리고.<!-- -->각각 다음과 같다.

나는 말 탄 줄 알았는데.$nextTick()을 사용하면 DOM에 액세스할 수 있습니다.내가 여기서 뭘 놓쳤지? 제발 도와줘서 고마워

왜 그렇게 생각하시죠?document.getElementById('bar-chart')어떤 요소라도 반환할까요?해당 ID를 가진 요소가 생성되지 않았습니다.당신이 찾고 있는 것은document.getElementsByTagName('bar-chart')그러나 Vue는 내부적으로 웹 컴포넌트를 작성하지 않고 대신 컴포넌트의 루트 요소를 삽입하기 때문에 결과도 얻을 수 없습니다.그래서 네가 할 수 있는 건 네가 할 수 있는 건bar-chart구성 요소idroot 요소에 자동으로 전달됩니다.

다음 이슈는 바로 당신의bar-chart컴포넌트는 다음 조건에서만 표시됩니다.v-if진부하다.컴포넌트를 처음 로드할 때는 그렇지 않을 수 있습니다.이 최소한의 작업 예에서는 단순히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>

(스택 스니펫콘솔은 실제로 이 명령어를 숨깁니다.<!-- -->코드펜에서 확인할 수 있습니다.Vue는 이 빈 HTML 주석을 현재 표시되지 않는 컴포넌트의 플레이스 홀더로 자동으로 삽입합니다.

출력은 실제로 예측됩니다.bar-chart컴포넌트가 렌더링되지 않았습니다.this.$el(자 컴포넌트에는 적용되지 않습니다.bar-chartcomponent)가 비어 있습니다.

여기 같은 토막이 있습니다.v-if="true"에서bar-chart컴포넌트:

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>

보시다시피 로그는 올바른 요소를 반환합니다.mounted()훅 오브 더 훅bar-chart요소.

물론, 이 기능을 사용하면 안 됩니다.id이 컴포넌트의 인스턴스를 여러 개 가질 계획인 경우 여러 요소가 동일한 ID를 가지기 때문에 HTML이 비활성화되고 예기치 않은 간섭이 발생할 수 있습니다.이 최소한의 예에서는 데모용으로만 사용되었습니다.실제 코드에서는 Vue의 속성을 대신 사용할 수 있습니다.이 속성은 부모 컴포넌트 내부에서 참조할 수 있습니다.

코드에는 다음 두 가지 문제가 있습니다.

  1. v-if값으로서 지정된 식에 자동으로 바인드되기 때문입니다.
  2. 없다this.식에서는 자동으로 구성요소 컨텍스트에 들어가 속성 이름을 직접 사용할 수 있습니다.

언급URL : https://stackoverflow.com/questions/58605315/vuejs-unable-to-access-dom-element-after-mounted-even-with-this-nexttick-usin

반응형