【问题标题】:Vue.js strange reactivity issueVue.js 奇怪的反应性问题
【发布时间】:2020-09-16 00:38:34
【问题描述】:

我已经不知所措了,我真的可以使用一些故障排除帮助。

在将代码从我的主/根App.vue 移动到Home.vue“视图”文件后,我突然遇到了一些反应性问题。

采用以下App.vue模板语法:

  <div id="app">
    <Header15 />
    <router-view />
    <UtilsBar />
    <Footer15 />
  </div>
</template>

我的Home.vue文件中定义的有问题的模板语法sn-p:

<ul class="filter-list">
  <li class="filter-list__litem" v-for="theme in themeFilterButtons" :key="theme.id">
    <a class="filter-list__link" :class="{ 'on': theme.isActive }" :href="'#'+theme.id" @click.prevent="onFilterSelect('theme', theme.id)">
      {{ theme.isActive }}<br />
      {{ theme.text }}
    </a>
  </li>

themeFilterButtons,是一个对象的计算数组。

computed: {
  themeFilterButtons() {
    return this.filters.themes.map((theme) => {
      return { ...theme, isActive: false };
    });
  }
}

新数组,从我的过滤器对象中引用一个数组(主题);它在我的数据中是这样定义的:

data() {
  return {
    filters: {
      themes: [
        { id: 113, text: 'First World War' },
        { id: 214, text: 'Second World War' }
      ]
    }
  }
}

绑定到点击事件的onFilterSelect方法最终会调用另一个方法filterBtnSelToggle。该方法通过切换对象上的 isActive 属性来切换选定的类 (.on)。

为了排除故障,我简化了函数以尝试执行将第一个数组索引上的 isActive 属性设置为 true 的琐碎任务。由于它最初设置为 false,因此单击任何按钮都应将属性更改为 true。无论我如何设置该值,模板视图 (v-for) 都不会更新。我尝试了所有这些,但没有更新标记。

onFilterSelect(cat, id) {
  // Say I wanted to set isActive: true on the first array item.
  this.themeFilterButtons[0].isActive = true; // < Doesn't work.
  this.$set(this.themeFilterButtons[0], 'isActive', true); // < Nope, also doesn't work.
  console.log('this.themeFilterButtons[0].isActive'); // Returns true.
}

我登录到控制台的任何内容都会返回我所期望的内容,它只是没有更新的模板(标记)内容。

就像我说的那样,奇怪的是,如果我将该逻辑移回主 App.vue 文件中,它还能继续工作......

非常感谢任何帮助!

【问题讨论】:

    标签: javascript vue.js vue-reactivity


    【解决方案1】:

    在这种情况下,计算属性依赖于this.filters.themes,并且您始终将 isActiv 设置为 false。因此您可以将 themeFilterButtons 设置为数据属性 它可以工作

      // delete computed Code block set themeFilterButtons property in data 
      mounted() {
        this.themeFilterButtons = this.filters.themes.map((theme) => {
          return { ...theme, isActive: false };
        });
      },
    

    【讨论】:

    • 不错!这行得通。我承认,我需要在何时使用不同的生命周期挂钩等方面提高技能。我认为这是某种方式解释了为什么代码在我的 App.js 而不是 Home.js“视图”中工作。尽管这可行,但在安装的生命周期挂钩中做我正在做的事情是不好的做法还是可能会出现问题?
    • 这种情况下created生命周期中的代码也是可以的,对于data属性或者property,create和mounted差别不大。如果要使用ref,只使用mounted跨度>
    【解决方案2】:

    您可以尝试使用 getter setter 计算属性。

    computed: {
      themeFilterButtons: {
        get () {
          return this.filters.themes.map((theme) => {
            return { ...theme, isActive: false };
          });
        }
        set (val) {
          this.filters = val
        }
      }
    }
    

    但是,更好的方法是首先在 data 中定义 isActive

    【讨论】:

    • OP 没有使用v-model 或其他任何需要setter的东西
    猜你喜欢
    • 1970-01-01
    • 2020-10-12
    • 1970-01-01
    • 1970-01-01
    • 2022-06-15
    • 1970-01-01
    • 1970-01-01
    • 2021-09-09
    相关资源
    最近更新 更多