如何在手动安装的Vue组件上更新道具?

时间:2018-12-14 20:50:02

标签: vue.js vis.js

问题: 有什么方法可以更新这样创建的手动安装的Vue组件/实例的道具吗?我传入一个名为item的对象作为组件的data道具。

let ComponentClass = Vue.extend(MyComponent);

let instance = new ComponentClass({
    propsData: { data: item }
});

// mount it
instance.$mount();

为什么

我有一个非Vue第三方库,可在时间轴上显示内容(vis.js)。因为我的应用程序的其余部分都是用vue编写的,所以我试图将vue组件用于时间轴本身上的内容。

我已经设法通过在vis.js的模板函数中手动创建和安装组件来在时间轴上渲染组件。

template: function(item, element, data) {

    // create a class from the component that was passed in with the item
    let ComponentClass = Vue.extend(item.component);

    // create a new vue instance from that component and pass the item in as a prop
    let instance = new ComponentClass({
        propsData: { data: item },
        parent: vm
    });

    // mount it
    instance.$mount();

    return instance.$el;
}

item.component是Vue组件,它接受数据道具。

我能够以这种方式创建和安装vue组件,但是当item更改时,我需要更新组件上的data道具。

3 个答案:

答案 0 :(得分:1)

如果您在Vue之外定义对象,然后在data中将其用于Vue实例,则会使该对象成为反应性的。在下面的示例中,我以这种方式使用dataObj。尽管我遵循使用data函数的约定,但它会返回一个预定义的对象(如果我使用data: dataObj,它将以完全相同的方式工作)。

安装实例后,我更新了dataObj.data,您可以看到该组件进行了更新以反映新的值。

const ComponentClass = Vue.extend({
  template: '<div>Hi {{data}}</div>'
});

const dataObj = {
  data: 'something'
}

let instance = new ComponentClass({
  data() {
    return dataObj;
  }
});

// mount it
instance.$mount();
document.getElementById('target').appendChild(instance.$el);

setTimeout(() => {
  dataObj.data = 'another thing';
}, 1500);
<script src="https://unpkg.com/vue@latest/dist/vue.js"></script>
<div id="target">
</div>

答案 1 :(得分:0)

这是我能够以编程方式传递和更新道具的方式:

const ComponentClass = Vue.extend({
  template: '<div>Hi {{data}}</div>',
  props: {
    data: String
  }
});

const propsObj = {
  data: 'something'
}

const instance = new ComponentClass()

const props = Vue.observable({
      ...instance._props,
      ...propsObj
})

instance._props = props

// mount it
instance.$mount();
document.getElementById('target').appendChild(instance.$el);

setTimeout(() => {
  props.data = 'another thing';  // or instance.data = ...
}, 1500);
<script src="https://unpkg.com/vue@latest/dist/vue.js"></script>
<div id="target">
</div>

答案 2 :(得分:0)

在 Vue 2.2+ 中,您可以使用 $props。 事实上,我和你的用例完全一样,有一个 Vue 项目、vis-timeline 和带有手动安装组件的项目。

就我而言,将某些内容分配给 $props.data 会触发观察者和整个反应性机器。

编辑:而且,正如我之前应该注意到的,这不是您应该做的。控制台中有一个错误日志,告诉 prop 不应该像这样直接变异。所以,我会尝试寻找其他解决方案。