source

Vue Router는 동적으로 부하가 높은 아이에게 소품을 전달합니다.

factcode 2022. 8. 12. 23:17
반응형

Vue Router는 동적으로 부하가 높은 아이에게 소품을 전달합니다.

저는 Vue ATM을 배우고 있는데, Vue Routes를 통해 아이들과 부모 컴포넌트 사이에 소품을 전달하는 데 어려움을 겪고 있습니다.Layout 컴포넌트는 래퍼 DIV를 가지며 다음과 같습니다.

<template>
    <div class="container" v-bind:class="cssClass">
      <router-view></router-view>
    </div>
</template>

<script>
export default {
  name: 'Layout',
  props: ['cssClass']
}
</script>

기본 App JS에서 루트를 정의했습니다.다음과 같습니다.그래서 첫 번째 적재물에 대한 나의 견해는 "컨테이너 애니메이션" 클래스로 모든 것이 세계와 잘 어울린다.

const router = new VueRouter({
    routes: [
      { path: '/', component: Layout, props: { cssClass: 'container-animated' },
        children: [
          { path: '', component: Homepage },
          { path: '/hello-world', component: HelloWorldPage, props: { cssClass: '' } }
        ]
     },
    ]
});

그러나 /hello-world 루트를 실행하면 빈 cssClass 소품을 Layout(현재 HelloWorldPage가 네스트되어 있는 레이아웃)에 전달하고 싶습니다.어떻게 하면 좋을까요?소품들은 그것을 달성하기 위한 메커니즘인가?

이게 내 문제에 대한 최적의 해결책인지 아닌지는 아무도 짐작할 수긍할 수 없다.

Vue Router를 통해 전달될 때 부모에 의해 자녀 소품이 자동으로 픽업되지 않는 것으로 보입니다.따라서 컴포넌트가 동적으로 구축/삽입되면 각각 커스텀 childinit 이벤트를 호출하여 부모(레이아웃)에서 정의된 라우터 뷰로 돌아갑니다.부모에서 로컬 변수를 내보낸 자식 값으로 설정한 다음 클래스를 바인딩합니다.

const router = new VueRouter({
    routes: [
      {
        path: '/',
        component: Layout,
        children: [
          {
            path: '',
            component: Homepage,
            props: { cssClass: 'home' },
          },
          {
              path: '/helloworld',
              component: HelloWorldPage,
              props: { cssClass: 'helloworld' }
          }
        ]
      }
    ]
});

내 레이아웃 구성요소:

<template>
    <div class="container" v-bind:class="className">
      <router-view v-on:childinit="onChildInit"></router-view>
    </div>
</template>

<script>
export default {
  name: 'Layout',
  props: ['cssClass'],
  data() {
    return {
      className : ''
    }
  },
  methods: {
    onChildInit( value ){
      this.className = value;
    }
  }
}
</script>

내 홈페이지 컴포넌트:

export default {
  name: 'Homepage',
  props: ['cssClass'],
  created() {
    this.$emit('childinit', this.cssClass);
  }
}

HelloWorld 컴포넌트에서도 레플리케이션이 필요 없습니다.두 컴포넌트 모두 초기화 시 항상 레플리케이션되는 기본 컴포넌트를 확장할 수 있는지 여부를 확인할 수 있습니다.

오래된 것은 알지만, 자신의 가치를 발산하는 컴포넌트에 메서드를 작성할 필요는 없습니다.이게 내 해결책이야

레이아웃:

<template>
<div class="container" v-bind:class="className">
    <router-view></router-view>
</div>
</template>
<script>
export default {
  name: 'Layout',
  props: ['cssClass'],
  data() {
    return {
      className : ''
    }
  },
  // set class initially
  created () {
    this.setClassName(this.$route)
  },
  // and when route changes
  watch: {
    $route: function (val) {
        this.setClassName(val)
    }
  },
  methods: {
    setClassName( Route ){
      // each matched route is checked for cssClass from top to bottom, so you can override
      Route.matched.forEach((route) => {
        if (route.props.default && route.props.default instanceof Object && 'cssClass' in route.props.default) {
          this.className = route.props.default.cssClass
        }
      })
    }

  }
}
</script>

이렇게 하면 모든 것이 Layout 컴포넌트에 남습니다.이상적인 해결책도 아닙니다.사용하는 것이 상상이 됩니다.router.afterEach()값을 Vuex 스토어로 설정합니다.

다른 방법으로 실행할 수 있습니다.

라우터:

const router = new VueRouter({
    routes: [
      {
        path: '/',
        component: Layout,
        children: [
          {
            path: '',
            component: Homepage,
            meta: { cssClass: 'home' },
          },
          {
            path: '/helloworld',
            component: HelloWorldPage,
            meta: { cssClass: 'helloworld' }
          }
        ]
      }
    ]
});

레이아웃 구성요소:

<template>
    <div class="container" :class="className">
       <router-view ></router-view>
    </div>
</template>

<script>
export default {
  name: 'Layout',
  data() {
    return {
      className : ''
    }
  },
  created() {
    this.className = this.$route.meta.cssClass;
  }
}
</script>

셋업과 반응성을 갖춘 또 다른 하나는

레이아웃 컴포넌트(설정+라우터):

<template>
    <div class="container" :class="cssClass">
       <router-view ></router-view>
    </div>
</template>

<script setup>
   import { useRoute } from 'vue-router'
   const route = useRoute();
   const { cssClass } = route.meta;
</script>

<script>
export default {
  name: 'Layout',
}
</script>

이 마지막 방법은 Vue 3용이며 훨씬 더 좋고 깨끗합니다.

vue의 구조를 설명하겠습니다.

부모 컴포넌트가 있습니다.레이아웃표시하다

<template>
  <div id="app" class="container-fluid">
    <router-view/>
  </div>
</template>
<style>
 .container-fluid {
background-color:blue; //as defined in the parent, everything inside #app will inherit this class
}
</style>

vue 라우터는 다음과 같이 되어 있어야 합니다.

{
    path: '/',
    name: 'Layout',
    component: Layout,
    children: [
        { path: '', component: Create, name: 'Create' },
    ]
}

Layout(레이아웃) 내에서 정의했기 때문에.vue는 .container-fluid 내의 모든 것을 상속하고 Create 구성 요소는 상위 구성 요소(레이아웃)에 정의된 클래스를 상속합니다.

이게 먹히길 바라.

안부 전해요,

언급URL : https://stackoverflow.com/questions/51140952/vue-router-passing-props-to-dynamically-loaded-children

반응형