我想把头放在V Vue.js的作品上,阅读大量文档和教程,并学习一些复数课程。我有一个非常基本的网站用户界面,并且正在运行。这是App.vue(我正在使用kind。作为母版页)。
(要使阅读起来更轻松,更快捷,请查找以下评论:This is the part you should pay attention to
)...
<template>
<div id="app">
<div>
<div>
<CommandBar />
</div>
<div>
<Navigation />
</div>
</div>
<div id="lowerContent">
<!-- This is the part you should pay attention to -->
<template v-if="showLeftContent">
<div id="leftPane">
<div id="leftContent">
<router-view name="LeftSideBar"></router-view>
</div>
</div>
</template>
<!-- // This is the part you should pay attention to -->
<div id="mainPane">
<div id="mainContent">
<router-view name="MainContent"></router-view>
</div>
</div>
</div>
</div>
</template>
然后在同一App.vue文件中,这是脚本部分
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import CommandBar from './components/CommandBar.vue';
import Navigation from './components/Navigation.vue';
@Component({
components: {
CommandBar,
Navigation,
}
})
export default class App extends Vue {
data() {
return {
showLeftContent: true // <--- This is the part you should pay attention to
}
}
}
</script>
好的,所以想法是,有些页面我想显示左侧边栏,而其他页面我不需要。这就是将div包裹在<template v-if="showLeftContent">
中的原因。
然后使用名为<router-view>'s
的文件,我可以控制将哪些组件加载到“ router \ index.ts \”文件中。路线如下所示:
{
path: '/home',
name: 'Home',
components: {
default: Home,
MainContent: Home, // load the Home compliment the main content
LeftSideBar: UserSearch // load the UserSearch component in the left side bar area
}
},
到目前为止一切顺利!但是,这是踢脚线。某些页面没有左侧栏,在这些页面上,我想将showLeftContent
从true
更改为false
。那是我不知道的部分。
假设我们有一个类似这样的“注释”组件。
<template>
<div class="notes">
Notes
</div>
</template>
<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator';
@Component
export default class Notes extends Vue {
data() {
return {
showLeftContent: false // DOES NOT WORK
}
}
}
</script>
很显然,我在这里没有正确处理showLeftContent
。据我了解,似乎data
中的属性仅作用于该组件。我只是找不到关于如何在App组件中设置数据属性,然后在通过router-view
加载子组件时在子组件中进行更改的任何方法。
谢谢!
编辑:
我从以下位置更改了Notes组件的脚本部分:
<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator';
@Component
export default class Notes extends Vue {
data() {
return {
showLeftContent: false // DOES NOT WORK
}
}
}
</script>
收件人:
<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator';
@Component
export default class Notes extends Vue {
mounted() {
this.$root.$data.showLeftContent = false;
}
}
</script>
尽管这没有引起任何编译或运行时错误,但也没有达到预期的效果。在Notes
上,左侧栏仍然显示。
编辑2:
如果我在Notes组件的脚本部分中放置了警报:
export default class Notes extends Vue {
mounted() {
alert(this.$root.$data.showLeftContent);
//this.$root.$data.showLeftContent = false;
}
}
直到我单击导航中的“注释”,警报才会弹出。但是,该值为“未定义”。
编辑3:
在这里使用语法(请记住这是TypeScript,我不太清楚!)
编辑4:
寸步难行!
export default class App extends Vue {
data() {
return {
showLeftContent: true
}
}
leftContent(value: boolean) {
alert('clicked');
this.$root.$emit('left-content', value);
}
}
这不会导致任何错误,但也不起作用。该事件永远不会被解雇。我将尝试将其放在“导航”组件中,看看是否可行。
答案 0 :(得分:3)
如@lukebearden回答中所述,您可以使用发出事件在单击App
时将true / false传递给主router-link
组件。
假设您的Navigation
组件如下所示,您可以执行以下操作:
#Navigation.vue
<template>
<div>
<router-link to="/home" @click.native="leftContent(true)">Home</router-link> -
<router-link to="/notes" @click.native="leftContent(false)">Notes</router-link>
</div>
</template>
<script>
export default {
methods: {
leftContent(value) {
this.$emit('left-content', value)
}
}
}
</script>
在主App
中,您收听Navigation
上的发射:
<template>
<div id="app">
<div>
<Navigation @left-content="leftContent" />
</div>
<div id="lowerContent">
<template v-if="showLeftContent">
//...
</template>
<div id="mainPane">
//...
</div>
</div>
</div>
</template>
<script>
//...
data() {
return {
showLeftContent: true
}
},
methods: {
leftContent(value) {
this.showLeftContent = value
}
}
};
</script>
答案 1 :(得分:2)
父子组件关系中的一种基本方法是从子组件发出事件,然后在父组件中侦听和处理该事件。
但是,我不确定在使用路由器视图时该方法是否有效。这个人通过观察$ route属性的更改来解决它。 https://forum.vuejs.org/t/emitting-events-from-vue-router/10136/6
您可能还想研究使用vue实例或vuex创建简单的事件总线。
答案 2 :(得分:1)
如果您想访问根实例的数据属性(或道具,选项等),则可以使用this.$root.$data
。 (选中Vue Guide: Handling Edge)
对于您的代码,您可以在其他组件的hook = this.$root.$data.showLeftContent
中将mounted
更改为true / false,然后在Vue为这些组件创建实例时,它将相关显示/隐藏左侧面板。
以下是一个演示:
Vue.config.productionTip = false
Vue.component('child', {
template: `<div :style="{'background-color':color}" style="padding: 10px">
Reach to root: <button @click="changeRootData()">Click me!</button>
<hr>
<slot></slot>
</div>`,
props: ['color'],
methods: {
changeRootData() {
this.$root.$data.testValue += ' :) '
}
}
})
new Vue({
el: '#app',
data() {
return {
testValue: 'Puss In Boots'
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<div id="app">
<h2>{{testValue}}</h2>
<child color="red"><child color="gray"><child color="green"></child></child></child>
</div>