admin管理员组文章数量:1308182
I'm having trouble getting props passed between children and parent ponents through Vue Routes. I've got a Layout ponent, that has a wrapper DIV and looks like this:
<template>
<div class="container" v-bind:class="cssClass">
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'Layout',
props: ['cssClass']
}
</script>
and I've got my routes defined in my base App JS, and looks like the below. So my view on first load has the class "container-animated" and all is good with the world.
const router = new VueRouter({
routes: [
{ path: '/', ponent: Layout, props: { cssClass: 'container-animated' },
children: [
{ path: '', ponent: Homepage },
{ path: '/hello-world', ponent: HelloWorldPage, props: { cssClass: '' } }
]
},
]
});
However, once I hit the /hello-world route, I want to pass an empty cssClass props to down to Layout, (which HelloWorldPage is currently nested inside) - how would I go about that? Are props even the mechanism to achieve that?
I'm having trouble getting props passed between children and parent ponents through Vue Routes. I've got a Layout ponent, that has a wrapper DIV and looks like this:
<template>
<div class="container" v-bind:class="cssClass">
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'Layout',
props: ['cssClass']
}
</script>
and I've got my routes defined in my base App JS, and looks like the below. So my view on first load has the class "container-animated" and all is good with the world.
const router = new VueRouter({
routes: [
{ path: '/', ponent: Layout, props: { cssClass: 'container-animated' },
children: [
{ path: '', ponent: Homepage },
{ path: '/hello-world', ponent: HelloWorldPage, props: { cssClass: '' } }
]
},
]
});
However, once I hit the /hello-world route, I want to pass an empty cssClass props to down to Layout, (which HelloWorldPage is currently nested inside) - how would I go about that? Are props even the mechanism to achieve that?
Share Improve this question edited Oct 26, 2023 at 18:48 IP002 5471 gold badge6 silver badges23 bronze badges asked Jul 2, 2018 at 17:19 Squiggs.Squiggs. 4,4747 gold badges56 silver badges94 bronze badges 3-
Why do you want to pass down an empty prop? Should this prop be changed in the future? What is the child supposed to do with the
cssClass
? Should the parent notice, which ponent is active and changecssClass
of the respective child ponent? – Bennett Dams Commented Jul 2, 2018 at 18:26 - Well in this instance I want to remove the css modifer in the parent.. in another route I may want to add a different modifier depending on the route to something else. Yes to your last statement on the parent being aware of the child ponent prop. – Squiggs. Commented Jul 2, 2018 at 19:11
- these answers 1 2 may be helpful regarding to vue router <router-link :to="...">, how to pass props to a ponent – tinystone Commented Feb 14, 2023 at 1:52
4 Answers
Reset to default 4I figured it out, whether this is the optimum solution for my problem is anyone's guess.
It appears child props aren't picked up automatically by the parent when passed on the Vue Router. So once the ponents are built / injected dynamically, they each call my custom childinit event, which emits back to the router view defined in the parent (Layout). I set a local variable in the parent to the value of the emitted child, and then bind the class to it.
const router = new VueRouter({
routes: [
{
path: '/',
ponent: Layout,
children: [
{
path: '',
ponent: Homepage,
props: { cssClass: 'home' },
},
{
path: '/helloworld',
ponent: HelloWorldPage,
props: { cssClass: 'helloworld' }
}
]
}
]
});
My layout ponent:
<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>
My Homepage ponent:
export default {
name: 'Homepage',
props: ['cssClass'],
created() {
this.$emit('childinit', this.cssClass);
}
}
The HelloWorld ponent emits as well, it's possible that the created method doesn't need to be replicated; might have a go at seeing if you can extend a base ponent that will always emit on init for both ponents.
I know that this is old, but you don't have to worry about creating a method in ponent which emits your value. this is my solution.
Your layout:
<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>
This way, everything stays on the Layout ponent. It's not ideal solution either. I can imagine using router.afterEach()
and set the value to Vuex store.
You can do it with another method:
router:
const router = new VueRouter({
routes: [
{
path: '/',
ponent: Layout,
children: [
{
path: '',
ponent: Homepage,
meta: { cssClass: 'home' },
},
{
path: '/helloworld',
ponent: HelloWorldPage,
meta: { cssClass: 'helloworld' }
}
]
}
]
});
layout ponent:
<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>
and another one with setup and reactivity
layout ponent with setup + router:
<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>
This last method is for Vue 3, and is much better and cleaner.
Let me explain you how vue works:
You got your parent ponent. 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>
Now, your vue router will have to look like this:
{
path: '/',
name: 'Layout',
ponent: Layout,
children: [
{ path: '', ponent: Create, name: 'Create' },
]
}
Since you have defined that inside the Layout.vue will inherit everything inside .container-fluid, the ponent Create will inherit the classes defined in its parent (Layout)
Hope this works.
Regards,
本文标签: javascriptpassing props to dynamically loaded childrenStack Overflow
版权声明:本文标题:javascript - passing props to dynamically loaded children - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741839810a2400430.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论