VueJS子组件按钮更改父类

Posted

技术标签:

【中文标题】VueJS子组件按钮更改父类【英文标题】:VueJS child component button changes class of parent 【发布时间】:2021-07-19 10:12:31 【问题描述】:

我有一个带有按钮的导航组件,用于切换暗模式/亮模式。当我单击此按钮时,我想更改 App.vue 中的一个类。如何将数据从按钮传递到 App.vue? 我相信我必须从 Top Nav 发出一些东西并在 App.vue 中对类进行 v-bind,但我不太明白如何让它改变类。

当我运行这个时,按钮不会改变 div 上的类。

App.vue

<template>
  <div id="app" :class="[isActive ? 'darkmode' : '']>
    <header>
      <top-nav @change-mode="enableDarkMode"></top-nav>
    </header>
    ...
  </div>
</template>

<script>

export default 
  name: "App",
  components: 
    TopNav,
  ,
  props: ['isActive'],
  data() ,
  methods: 
    enableDarkMode(isActive) 
      console.log(isActive)
    ,
  ,
;
</script>

顶部导航组件

<template>
  ...
  <div>
    <button
      :class="[isActive ? 'dark' : 'light']"
      @click="toggle">
         isActive ? "DarkMode" : "LightMode" 
    </button>
  </div>
</template>

<script>
export default 
  name: "TopNav",
  data() 
    return 
      isActive: false,
    ;
  ,
  components: ,
  methods: 
    toggle() 
      this.isActive = !this.isActive;
      this.$emit('change-mode', this.isActive )
      console.log('emit child')
    ,
  ,
;
</script>

【问题讨论】:

【参考方案1】:

从您提供的 sn-p 看来,App.vue 似乎有 isActive 道具而不是 data 用于管理方法 enableDarkMode。由于how the data flow works in Vue props,Vue 的 props 不会被它们所属的组件更新。 App.vue 是 Top Nav 组件的父级,您可能希望它是这样的:

App.vue

<template>
  <div id="app" :class="[isActive ? 'darkmode' : '']>
    <header>
      <top-nav @change-mode="enableDarkMode"></top-nav>
    </header>
    ...
  </div>
</template>

<script>

export default 
  name: "App",
  components: 
    TopNav,
  ,
  // this is probably not needed because App.vue is the parent component
  // props: ['isActive'],
  data() 
    return 
      isActive: false,
    ;
  ,
  methods: 
    enableDarkMode(isActive) 
      // manages the data
      this.isActive = isActive;
    ,
  ,
;
</script>

顶部导航组件

<template>
  ...
  <div>
    <button
      :class="[isActive ? 'dark' : 'light']"
      @click="toggle">
         isActive ? "DarkMode" : "LightMode" 
    </button>
  </div>
</template>

<script>
export default 
  name: "TopNav",
  data() 
    return 
      isActive: false,
    ;
  ,
  components: ,
  methods: 
    toggle() 
      this.isActive = !this.isActive;
      this.$emit('change-mode', this.isActive )
      console.log('emit child')
    ,
  ,
;
</script>

【讨论】:

我认为您应该将 App.vue 中的 isActive 重命名为 darkModeEnabled 之类的名称。两个组件中的相同名称令人困惑。也不需要将 isActive 保持在 Nav 状态。您可以将 darkModeEnabled 的值作为道具传递给 TopNav,然后在调用 toggle() 时发出与该道具值相反的值。 @fdglefevre 是的,我同意,清晰命名很重要,但 OP 询问为什么 App.vue 中的类没有更新,所以我试图解决这个问题。 @fdglefevre 我对你的解决方案很感兴趣,你能详细说明一下吗? @fdglefevre 谢谢,我会研究一下,希望它能帮助我理解道具并更好地发射。

以上是关于VueJS子组件按钮更改父类的主要内容,如果未能解决你的问题,请参考以下文章

VueJS 导航到子组件

从 VueJS 的父组件中引用子组件的索引

具有父组件操作的角度更改子组件模板

VueJS:在子组件中触发事件时在父组件中运行函数

对挂载中的属性的更改未触发在 VueJS 中计算

尝试在 VueJs 中禁用导航按钮时出错