【问题标题】:@Watch decorator not activating@Watch 装饰器未激活
【发布时间】:2017-08-23 04:41:55
【问题描述】:

我有一个简单的测试组件,模板如下所示:

<template>
  <div>
    <input type="text" v-model="name" class="form-control">
    <h5>{{ message }}</h5>
  </div>
</template>
<script src="./test.ts" lang="ts"></script>

TypeScript 组件如下所示:

declare var Vue: typeof Function;
declare var VueClassComponent: any;

import { Component, Inject, Model, Prop, Watch } from "vue-property-decorator";

@VueClassComponent.default({
  template: require("./test.vue"),
  style: require("./test.sass"),
  props: {
    name: String,
    num: Number
  }
})
export default class TestComponent extends Vue {
  name: string;
  num: number;
  message: string = "";

  @Watch("name")
  protected onNameChanged(newName: string, oldName: string): any {
    console.log("setting " + oldName + " to " + newName);
  }

  mounted(this: any): void {
    console.log("mounted called");
    this.message = "Hello " + this.name + " " + this.num;
  }
}

当我在 input 框中键入时,@Watch("name") 处理程序永远不会触发,但是我确实在 console 中收到这些错误:

[Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "name" 

input 框中输入的每个字符一次。我不知道名称是在哪里设置的,因为我没有在任何地方设置它。虽然这是我的目标(更新名称)我一直在阅读你不能直接更改值,你需要设置 @Watch 处理程序,然后在其他地方设置它们(我仍然不完全理解 怎么样,但现在甚至无法获得。

【问题讨论】:

  • 警告是因为您将name 作为属性,并且您在输入中设置了v-model="name",因此试图改变道具。
  • @BertEvans 这也是我的猜测,但这就是示例显示的方式。你有什么建议?
  • 什么例子?我希望你想要做的是像 &lt;test-component v-model="name"&gt;&lt;/test-component&gt; 一样在某处使用它?
  • @BertEvans 这是示例:vuejs.org/v2/guide/computed.html#Watchers
  • @BertEvans 这是组件内的一个属性,我对将其放在整个组件的 html 标记中而不是属性附加到的输入字段的建议感到困惑. (它应该始终代表name,因为它会发生变化)。

标签: typescript vue.js vuejs2 vue-component


【解决方案1】:

根据我们的讨论,问题的根源在于将name 声明为属性。其目的是 name 是一个内部值,仅用于派生 message。在这种情况下,手表是不必要的,计算就可以了。

declare var Vue: typeof Function;
declare var VueClassComponent: any;

import { Component, Inject, Model, Prop, Watch } from "vue-property-decorator";

@VueClassComponent.default({
  template: require("./test.vue"),
  style: require("./test.sass"),
  props: {
    num: Number
  }
})
export default class TestComponent extends Vue {
  name: string;
  num: number;

  get message(){
      return "Hello " + this.name + " " + this.num;
  }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-22
    • 2023-03-28
    相关资源
    最近更新 更多