如何解决通过vue js中的router-view更新组件中的props
我想将一个布尔值从路由器视图中的一个视图传递到根 App.vue,然后传递到 App.vue 中的一个组件。我能够做到,但我遇到了错误:
避免直接改变 prop,因为每当父组件重新渲染时,该值将被覆盖。相反,根据道具的值使用数据或计算属性。道具被变异:“抽屉”
下面是我的代码:
Home.vue:
<template>
<div class="home" v-on:click="updateDrawer">
<img src="...">
</div>
</template>
<script>
export default {
name: "Home",methods:{
updateDrawer:function(){
this.$emit('updateDrawer',true)
}
};
</script>
上面的视图在路由器视图中,我在下面的 App.vue 中获取值:
<template>
<v-app class="">
<Navbar v-bind:drawer="drawer" />
<v-main class=" main-bg">
<main class="">
<router-view v-on:updateDrawer="changeDrawer($event)"></router-view>
</main>
</v-main>
</v-app>
</template>
<script>
import Navbar from '@/components/Navbar'
export default {
name: 'App',components: {Navbar},data() {
return {
drawer: false
}
},methods:{
changeDrawer:function(drawz){
this.drawer = drawz;
}
},};
</script>
我通过在导航栏组件中绑定它来发送抽屉的值。
Navbar.vue:
<template>
<nav>
<v-app-bar app fixed class="white">
<v-app-bar-nav-icon
class="black--text"
@click="drawer = !drawer"
></v-app-bar-nav-icon>
</v-app-bar>
<v-navigation-drawer
temporary
v-model="drawer"
>
...
</v-navigation-drawer>
</nav>
</template>
<script>
export default {
props:{
drawer:{
type: Boolean
}
},};
</script>
这将工作一次,然后它会给我上述错误。如果有人可以解释我应该做什么以及如何解决此问题,我将不胜感激。
解决方法
在 Navbar.vue 中,您正在获取属性“抽屉”,每当有人点击“v-app-bar-nav-icon”时,您将抽屉更改为 !drawer。
这里的问题是您正在从子端(Navbar.vue 是子项)改变(更改值)属性。 这不是 Vue 的工作方式,props 仅用于将数据从父级传递到子级(App.vue 是父级,Navbar.vue 是子级),而不是相反。
这里的正确方法是:每次在 Navbar.vue 中,您想要更改“抽屉”的值时,您都应该像在 Home.vue 中一样发出一个事件。
然后您可以在 App.vue 中侦听该事件并相应地更改抽屉变量。
示例:
导航栏.vue
<v-app-bar-nav-icon
class="black--text"
@click="$emit('changedrawer',!drawer)"
></v-app-bar-nav-icon>
App.vue
<Navbar v-bind:drawer="drawer" @changedrawer="changeDrawer"/>
我最初错过了您还在 Navbar.vue 中使用 v-model="drawer" 的事实。 v-model 也改变了 drawer 的值,这也是我们不想要的。 我们可以通过将 v-model 拆分为 v-on:input 和 :value 来解决这个问题:
<v-navigation-drawer
temporary
:value="drawer"
@input="val => $emit('changedrawer',val)"
>
某种中央状态管理(例如 Vuex)在这种情况下也很棒;)
,你可以做的是观察 Navbar.vue 中 drawer prop 的变化,如下所示:
<template>
<nav>
<v-app-bar app fixed class="white">
<v-app-bar-nav-icon
class="black--text"
@click="switchDrawer"
/>
</v-app-bar>
<v-navigation-drawer
temporary
v-model="navbarDrawer"
>
...
</v-navigation-drawer>
</nav>
</template>
<script>
export default {
data () {
return {
navbarDrawer: false
}
},props: {
drawer: {
type: Boolean
}
},watch: {
drawer (val) {
this.navbarDrawer = val
}
},methods: {
switchDrawer () {
this.navbarDrawer = !this.navbarDrawer
}
}
}
</script>
Home.vue
<template>
<div class="home">
<v-btn @click="updateDrawer">Updrate drawer</v-btn>
</div>
</template>
<script>
export default {
name: 'Home',data () {
return {
homeDrawer: false
}
},methods: {
updateDrawer: function () {
this.homeDrawer = !this.homeDrawer
this.$emit('updateDrawer',this.homeDrawer)
}
}
}
</script>
App.vue
<template>
<v-app class="">
<Navbar :drawer="drawer" />
<v-main class="main-bg">
<main class="">
<router-view @updateDrawer="changeDrawer"></router-view>
</main>
</v-main>
</v-app>
</template>
<script>
import Navbar from '@/components/Navbar'
export default {
name: 'App',components: { Navbar },data () {
return {
drawer: false
}
},methods: {
changeDrawer (newDrawer) {
this.drawer = newDrawer
}
}
}
</script>
这不会改变 drawer prop,但会响应变化。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。