在本教程之后,我将尝试在页面上以编程方式创建组件实例。
主要片段如下:
import Button from 'Button.vue'
import Vue from 'vue'
var ComponentClass = Vue.extend(Button)
var instance = new ComponentClass()
instance.$mount()
this.$refs.container.appendChild(instance.$el)
但是我有两个错误:
我试图实例化的组件包含对存储的引用,但这些引用不起作用:"TypeError:无法读取未定义的属性'state'">。
对于代码段(
this.$refs.container.appendChild(instance.$el)
(的最后一行,我得到了以下错误:"未捕获类型错误:无法读取未定义的属性'container'">
我真的不知道如何解决这个问题,如果Vue.js中的任何人都能给我一些提示,告诉我为什么会出现这些错误,并解决它们,那将是非常棒的。
1(由于您手动实例化该组件,而它不属于主应用程序的组件树,因此存储不会从根组件自动注入。在实例化组件时,您必须手动将存储提供给构造函数。。
import ProjectRow from "./ProjectRow.vue";
import Vue from "vue";
import store from "../store";
let ProjectRowClass = Vue.extend(ProjectRow);
let ProjectRowInstance = new ProjectRowClass({ store });
2( 在Vue单一文件组件(SFC(中,默认导出之外的this
不引用Vue实例,因此您无权访问$refs
或任何其他Vue实例属性/方法。要访问Vue实例,您需要将此行this.$refs.container.appendChild(instance.$el)
移动到默认导出中的某个位置,例如mounted
钩子或methods
中的一个。
请参阅此CodeSandbox,了解如何进行此操作的示例。
这是在Vue.js中实例化组件的另一种方法,您可以使用两个不同的根元素。
// Instantiate you main app
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
})
//
// Then instantiate your component dynamically
//
// Create a component or import it.
const Hello = {
props: ['text'],
template: '<div class="hello">{{ text }}</div>',
};
// Create a componentClass by Vue.
const HelloCtor = Vue.extend(Hello);
// Use componentClass to instantiate your component.
const vm = new HelloCtor({
propsData: {
text: 'HI :)'
}
})
// then mount it to an element.
.$mount('#mount');
它通过分配"这个";财产";"父";。通过设置父级,您还可以访问新实例中的$store。(当然,假设"this"是另一个Vue实例/组件,并且已经可以访问商店(
new (Vue.extend(YourNewComponent))({
parent: this,
propsData: {
whatever: 'some value',
},
}).$mount(el.querySelector('.some-id'))
如果你不需要引用父母,你可以直接离开"家长:这个;出来
重要提示:以这种方式在页面上装载许多(如500+(项目时,您将获得巨大的性能提升。最好只通过道具给新组件提供必要的东西,而不是给它整个"道具";这个";对象
我走上了这条路,遵循了上面的所有例子,甚至是这个例子:https://css-tricks.com/creating-vue-js-component-instances-programmatically/
虽然我走得很远,而且它很有效(我用这种方式制作了很多组件(,但至少在我的案例中,它有的缺点。例如,我同时使用Vuetify,并且动态添加的组件不属于外部表单,这意味着虽然本地(每个组件(验证有效,但表单没有收到整体状态。另一件不起作用的事情是禁用窗体。随着更多的工作,将窗体作为父属性传递,其中一些工作开始起作用,但删除组件呢。这并不顺利。虽然它们是不可见的,但它们并没有被真正删除(内存泄漏(。
所以我改为使用渲染函数。事实上,它要容易得多,有很好的文档记录(Vue 2和Vue 3(,而且一切都很正常。我也从这个项目中得到了很好的帮助:https://koumoul-dev.github.io/vuetify-jsonschema-form/latest/
基本上,要动态添加一个函数,只需实现render()
函数,而不需要使用模板。工作方式有点像React。您可以在这里实现任何逻辑来选择标签、选项和所有内容。只要返回,Vue就会构建影子DOM并保持真实DOM的最新状态。
这里的方法似乎可以直接操作DOM,我很高兴我不再需要这样做了