Vue Router 将道具传递给动态加载 children
Vue Router passing props to dynamically loaded children
我正在学习 Vue atm,我无法通过 Vue 路由在 children 和 parent 组件之间传递道具。我有一个布局组件,它有一个包装器 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 中定义了我的路线,如下所示。所以我对第一次加载的看法是 class "container-animated" 并且世界上一切都很好。
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 是如何工作的:
你得到了你的父组件。 Layout.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 将继承其父级 (Layout) 中定义的 类
希望这有效。
此致,
我想通了,这是否是我的问题的最佳解决方案是任何人的猜测。
在 Vue 路由器上传递时,父级似乎不会自动拾取子道具。因此,一旦组件被动态构建/注入,它们都会调用我的自定义 childinit 事件,该事件会发回父级(布局)中定义的路由器视图。我将父级中的局部变量设置为发出的子级的值,然后将 class 绑定到它。
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 组件也会发出,可能创建的方法不需要复制;可能会尝试看看您是否可以扩展一个基本组件,该组件将始终在两个组件的 init 上发出。
我知道这是旧的,但您不必担心在组件中创建一个方法来发出您的值。这是我的解决方案。
您的布局:
<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 store.
你可以用另一种方法:
路由器:
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 atm,我无法通过 Vue 路由在 children 和 parent 组件之间传递道具。我有一个布局组件,它有一个包装器 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 中定义了我的路线,如下所示。所以我对第一次加载的看法是 class "container-animated" 并且世界上一切都很好。
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 是如何工作的:
你得到了你的父组件。 Layout.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 将继承其父级 (Layout) 中定义的 类
希望这有效。
此致,
我想通了,这是否是我的问题的最佳解决方案是任何人的猜测。
在 Vue 路由器上传递时,父级似乎不会自动拾取子道具。因此,一旦组件被动态构建/注入,它们都会调用我的自定义 childinit 事件,该事件会发回父级(布局)中定义的路由器视图。我将父级中的局部变量设置为发出的子级的值,然后将 class 绑定到它。
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 组件也会发出,可能创建的方法不需要复制;可能会尝试看看您是否可以扩展一个基本组件,该组件将始终在两个组件的 init 上发出。
我知道这是旧的,但您不必担心在组件中创建一个方法来发出您的值。这是我的解决方案。
您的布局:
<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 store.
你可以用另一种方法:
路由器:
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,更好更简洁。