【问题标题】:Content from async XML source doesn't get updated correctly in vue component来自异步 XML 源的内容未在 vue 组件中正确更新
【发布时间】:2017-06-20 10:02:25
【问题描述】:

我正在努力应对 vue 的反应性问题,需要一些帮助。

我的组件应该显示来自 XML 文档的内容。在不同的 XML 文档之间切换时,某些组件会保留其旧值并且不反映新内容。这似乎发生在具有相同 id 的 XML 元素上。但是我在 v-for 循环中使用了一个唯一的 :key 属性,该属性由 XML 文档 id 和 XML 元素 id 组成。

只有在我使用数据属性设置内容时才会发生这种情况。

<span v-html="value"></span>
...
data() {
  return {
    value: this.xmlNode.firstChild.nodeValue
  };
}

当我直接设置内容时,它按预期工作。

<span v-html="xmlNode.firstChild.nodeValue"></span>

HTML

<div id="course">
  <button @click="toggle">Change content</button>
  <edit-element
    v-for="node in courseElementContent"
    :xml-node="node"
    :key="id + '#' + node.getAttribute('idref')"></edit-element>
</div>

JavaScript:

Vue.component('edit-element', {
  template: '<div><span v-html="value"></span></div>',
  props: ["xmlNode"],
  data() {
    return {
      value: this.xmlNode.firstChild.nodeValue
    };
  }
});

new Vue({
  el: "#course",
  name: "CourseElement",
  data: {
      id: 1,
      courseElementContent: null
  },
  created() {
    this.load();
  },

  methods: {
    toggle() {
      if (this.id == 1) this.id = 2;
      else this.id = 1;
      this.load();
    },
    load() {
      var me = this;
      axios.get("content/" + this.id + ".xml").then(
        response => {
          var doc = new DOMParser().parseFromString(response.data, "text/xml"));
          // get all <content> elements
          me.courseElementContent = doc.querySelectorAll("content");
      });
    }
  }
});

我错过了什么?应该更改什么以始终反映正确的值? (注意:我想使用引用数据属性,只需通过设置即可轻松更改“值”。)

感谢赐教。

我的互动小提琴 https://jsfiddle.net/tvjquwmn/

【问题讨论】:

    标签: vue.js


    【解决方案1】:

    您的 data 属性不是响应式的,因为它引用原始类型。在创建步骤之后它确实不会更新。 如果您希望它具有反应性,请改为计算:

    Vue.component('edit-element', {
      template: `
      <div>
        <span v-html="direct ? xmlNode.firstChild.nodeValue : value"></span>
        <span style="font-size: 60%; color:grey">({{ keyVal }})</span>
      </div>`,
      props: ["xmlNode", "keyVal", "direct"],
      computed: {
        value() {
            return this.xmlNode.firstChild.nodeValue;
        }
      }
    });
    

    查看工作小提琴:https://jsfiddle.net/56c7utvc/

    【讨论】:

    • 感谢您的快速回答和工作示例。我还是不完全明白。我希望能够在以后的步骤中更改该值。该怎么做?
    • 您的 data() 函数仅在创建组件时运行一次。它不会在下一个渲染步骤中重新运行,因此它们将保持静态,除非它们被显式更新。另一方面,计算属性是响应式的,并且会监视其依赖项的变化。
    • 这是有道理的。但是我没有得到它,因为我使用了一个唯一的 :key 属性,恕我直言,该属性会导致显式更新。我希望能够在以后的步骤中更改该值?你有什么建议?
    • 它与 :key 没有任何关系。问题是this.xmlNode.firstChild.nodeValue 是一个原始值。因此,当您在数据函数中将其分配给value(仅运行一次)时,它不会作为参考传递,而是被复制(不再是同一个实体)。然后,复制的值被 vue 代理以被观看。但原来的属性不是。所以,那么,data.value,虽然本身是反应性的,但不会对 firstChild.nodeValue 上的变化做出反应,因为你的 data.value 没有以任何方式链接到 firstChild.nodeValue,它们是完全独立的。
    • 我明白了!非常感谢您的解释。我认为将根据 :key 属性创建一个新组件。然后我真的不明白 :key 是干什么用的。
    猜你喜欢
    • 1970-01-01
    • 2017-10-24
    • 1970-01-01
    • 2022-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-27
    • 2020-12-11
    相关资源
    最近更新 更多