Javascript 更改属性';将一个组件中的值从另一个组件中删除

Javascript 更改属性';将一个组件中的值从另一个组件中删除,javascript,typescript,vue.js,vue-component,Javascript,Typescript,Vue.js,Vue Component,我正在努力学习hoe Vue.js的作品,阅读大量文档和教程,并参加一些pluralsight课程。我有一个非常基本的网站界面和运行。这是App.vue(我把它当作母版页) (为了使阅读更容易、更快,请查看以下注释:这是您应该注意的部分) 到目前为止还不错!但这是踢球的人。有些页面没有左侧栏,在这些页面上,我想将showleeftcontent从true更改为false。这是我无法理解的部分 假设我们有一个“Notes”组件,看起来像这样 <template> <div

我正在努力学习hoe Vue.js的作品,阅读大量文档和教程,并参加一些pluralsight课程。我有一个非常基本的网站界面和运行。这是App.vue(我把它当作母版页)

(为了使阅读更容易、更快,请查看以下注释:
这是您应该注意的部分

到目前为止还不错!但这是踢球的人。有些页面没有左侧栏,在这些页面上,我想将
showleeftcontent
true
更改为
false
。这是我无法理解的部分

假设我们有一个“Notes”组件,看起来像这样

<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>
致:

在我单击导航栏中的“备注”之前,警报不会弹出。但是,该值是“未定义的”

编辑3:

这里的语法很难理解(请记住这是TypeScript,我不太清楚!!)

编辑4:

慢慢地走

export default class App extends Vue {
    data() {
        return {
            showLeftContent: true
        }
    }

    leftContent(value: boolean) {
        alert('clicked');
        this.$root.$emit('left-content', value);
    }
}

这不会导致任何错误,但也不起作用。事件永远不会被触发。我将尝试将其放入导航组件中,看看是否有效。

父子组件关系中的基本方法是从子组件发出事件,然后在父组件中侦听并处理该事件

然而,我不确定这种方法在使用router视图时是否有效。此人通过观察$route属性的变化来解决这个问题


您可能还想研究使用vue实例或vuex创建简单事件总线。

如果您想访问根实例的数据属性(或道具、选项等),可以使用
this.$root.$data
。(支票)

对于您的代码,您可以在其他组件的hook=
mounted
中将
this.$root.$data.showLeftContent
更改为true/false,然后当Vue为这些组件创建实例时,它将相应地显示/隐藏左侧面板

下面是一个演示:

Vue.config.productionTip=false
Vue.component('子'{
模板:`
到达根:点击我!

`, 道具:[“颜色”], 方法:{ changeRootData(){ 这是。$root。$data.testValue+=':)' } } }) 新Vue({ el:“#应用程序”, 数据(){ 返回{ testValue:“穿靴子的猫” } } })

{{testValue}}

正如@lukebarden answer上所述,您可以使用emit事件将true/false传递给
路由器链接上的主
应用程序
组件

假设您的
导航组件如下所示,您可以这样做:

#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>

或者
this.$root.$emit/$on
将是一个选项。在root应用程序组件中,我应该使用道具而不是数据吗?也就是说,showLeftContent应该是道具而不是data()对象的一部分吗?@CaseyCrokston,Vue在单向数据流下工作。一个组件不应更改其道具的值。所以我不认为用一个道具代替数据属性是个好主意。好的,谢谢。这是有道理的。所以我仍在努力了解如何更改数据属性'showleeftcontent',如果执行如下警报:警报(this.$root.$data.showleeftcontent);它返回“未定义”您确定Notes组件已安装吗?可能添加一个
console.log
以进行双重检查。@Sphinx,请参阅编辑2如果值为“未定义”,可能是由于App不是根实例引起的。通过
console.log(this.$root.$el)
.lol仔细检查,我也不知道typescript(对于edit3)。添加了typescript标记。
this.$root.$emit('left-content',value)。你没有定义
这个。$on
@CaseyCrookston我不太了解ts,但我认为你不需要这个块
方法:{…}
来初始化一个方法。@CaseyCrookston关于你的编辑4,它不是
应用程序
发出
'left-content'
事件,而是
导航
(而且你不需要
$root
)。
应用程序
收听导航组件上的事件。@sovalina,你能告诉我那会是什么样子吗?伙计,我解决了一个问题,又出现了一个问题!!我真的很感谢你的帮助!!@CaseyCrookston我做了一个测试路由器链接(但不是在typescript中)@caseycrokston如果
/notes
是一条路线,您也可以从路线组件中排除
LeftSideBar
<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>
<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>
export default class Notes extends Vue {
    mounted() {
        alert(this.$root.$data.showLeftContent);
        //this.$root.$data.showLeftContent = false;
    }
}
export default class App extends Vue {
    data() {
        return {
            showLeftContent: true
        }
    }

    leftContent(value: boolean) {
        alert('clicked');
        this.$root.$emit('left-content', value);
    }
}
#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>
<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>