programing

Vue-Router를 구현하는 VueJS SPA에서 중첩된 $ref 구현

prostudy 2022. 3. 30. 00:09
반응형

Vue-Router를 구현하는 VueJS SPA에서 중첩된 $ref 구현

나는 현재 Laravel/VueJS SPA를 활용하고 있다.Vue/Vue-RouterVue 구성 요소가 할당되어 있으며$ref (구성 요소 C/내포된 하위 구성 요소 내부) 레이아웃에 주입되는 기본 Vue-Router 구성 요소(구성 요소 B) 내에 캡슐화된(구성 요소 A - 레이아웃 구성 요소)

여기에 해당하는 이 요소에 액세스해야 함$ref( 컴포넌트 C 내부) 그러나, 컴포넌트 A 내의 컴포넌트 계층은 컴포넌트 B에 선언된 정보로부터 구성되었기 때문에 나는 컴포넌트 C에 접근할 수 없다.

(Layout-Component / $root) - Vue Layout Component: --(Vue-Router-Component) -
Primary component injected into layout via Vue-Router - Child Component of
Component A --(dynamic-form-field) - Child Component of Vue-Router-Component

<Layout-Component ref="componentA">
  <Vue-Router-Component ref="componentB">
    <dynamic-form-field ref="componentC"></dynamic-form-field>
  </Vue-Router-Component>
</Layout-Component>

나는 에 접속해 보았다.$ref표준 중첩된 $ref 구문 사용:

this.$root.$refs['componentB'].$refs['componentC'].attribute

그러나 액세스할 수 없음$refs안에 선언된.Components B or C로부터Component A.


구성 요소 B에 선언된 데이터를 사용하지 않고 주 레이아웃 내에서 직접 중첩된 구성 요소 계층(구성 요소 A - C)을 재생성하면 중첩된 구성 요소에 액세스할 수 있기 때문에 Vue 라이프사이클 문제로 결정했다.$refs위 구문을 통해 문제없이.


문제는 구성요소 B에 명시된 데이터로부터 구성요소 A(레이아웃 구성요소)에 구성요소를 작성하는 데서 비롯된다.

레이아웃 구성 요소(구성 요소 A) 코드 조각:

<template v-for="(input, field) in formDialog.inputs">
  <template v-if="Array.isArray(input)">
    <!-- for every record in the input array -->
    <template v-for="(inputArrRecord, arrIndex) in input">
      <v-col cols="12" class="p-0">
        <v-btn
          icon
          x-small
          v-if="arrIndex"
          class="float-right"
          color="error"
          :title="
            inputArrRecord.typeTitle
              ? `Remove ${inputArrRecord.typeTitle}`
              : 'Remove'
          "
          @click="inputArrRecord.removeAction"
        >
          <v-icon>mdi-close-box-multiple-outline</v-icon>
        </v-btn>
      </v-col>

      <template v-for="(inputArrRecordInput, field2) in inputArrRecord.inputs">
        <!-- for every field in the array record -->
        <dynamic-form-field
          :ref="`dynamicFormField${field2}`"
          :input="inputArrRecordInput"
          :field="field2"
          :mode="formMode"
          :error="formDialog.errors[`${field}.${arrIndex}.${field2}`]"
        ></dynamic-form-field>
      </template>
    </template>
  </template>

  <dynamic-form-field
    v-else
    :ref="`dynamicFormField${field}`"
    :input="input"
    :field="field"
    :mode="formMode"
    :error="formDialog.errors[field]"
  ></dynamic-form-field>
</template>

데이터 선언(구성 요소 B) 코드 조각:

export default {
  data() {
    return {
      formDialog: {
        errors: [],
        show: false,
        inputs: {
          id: {
            val: '',
            save: true,
            type: 'hidden',
          },

          word_data: [],
          definitions: [],

          tags: {
            val: [],
            save: true,
            add: true,
            type: 'autocomplete',
            items: this.$root.cache.tags,
            ref: 'vocabTagsAutocomplete',
            label: 'Search For a Tag',
            actionChange: this.addExistingTag,
            actionKeydown: this.addNewTag,
          },

          synonym: {
            val: '',
            save: true,
            add: true,
            placeholder: 'Synonyms',
          },
        },
        titleActions: [
          {
            icon: 'mdi-book-plus',
            btnType: 'text',
            text: 'Add Word Type',
            event: this.cloneWordDataTemplate,
          },
          {
            icon: 'mdi-book-plus-outline',
            btnType: 'text',
            text: 'Add Definition',
            event: this.cloneDefinitionTemplate,
          },
        ],
      },
    }
  },
}

동적 형식 필드.vue(구성 요소 C) 내용:

<template>
  <v-col
    v-if="(mode == 'add' && input.add) || (mode == 'edit' && input.save)"
    :cols="input.gridSize || 12"
  >
    <form-field-selection
      :input="input"
      :field="field"
      :error="error"
      :ref="`formFieldSelection${field}`"
    ></form-field-selection>
  </v-col>
</template>

<script>
  export default {
    name: 'dynamic-form-field',
    props: ['input', 'field', 'mode', 'error'],
  }
</script>

에 액세스하려면$ref구성 요소 A에서 구성 요소 C에 선언되었는가?

구성 요소 C가 이벤트를 방출하여 데이터로 전송:

// Component C
<script>
/*..component code..*/
mounted(){
  this.$root.$emit('child_ready',this)
}
</script>

그러면 다른 구성 요소에서 해당 이벤트를 들을 수 있다.

// Your layout
<script>
/*...layout code...*/
created(){
    // Using created to make sure we add our listeners before any child mount
    this.$root.$on('child_ready',onChild)
},
beforeDestroy(){
    // cleaning the listener
    this.$root.$off('child_ready',onChild)
},
methods:{
    onChild(childRef){
        // Now you can access properties and methods
        // childRef.property()
        // childRef.method()
    }
}
<script>

참조URL: https://stackoverflow.com/questions/67542490/implementing-nested-refs-in-a-vuejs-spa-implementing-vue-router

반응형