Vuetify 和 require.js:如何显示动态组件?
Vuetify and require.js: How do I show a dynamic component?
我正在创建一个选项卡组件,它动态加载其 v-tab-item
组件,给定一个由 tabName
、id
和 tabContent
组成的配置对象数组是组件的资源位置。我成功加载了组件。但是,在我切换选项卡之前,它们实际上并没有初始化(或 运行 它们的 created()
方法)。我只是得到带有正确标签的空标签。使用 DOM 检查器最初仅显示 <componentId></componentId>
,然后当我切换选项卡时,这些标签将替换为组件的所有内容。
如何让动态组件在加载后立即初始化?
编辑:我在这里创建了一个 CodePen:
https://codepen.io/sgarfio/project/editor/DKgQON
但由于这是我的第一个 CodePen,我还没有想出如何引用项目中的其他文件(即如何设置 tabContent 以便 require.js 可以加载它们)。我在控制台中看到 "Access is denied",这听起来像是找到了文件但不允许访问它们,这很奇怪,因为所有文件都属于同一个项目。所以我的 CodePen 甚至不如我的实际项目。但也许它会帮助别人理解我正在尝试做的事情。
此外,在仔细研究之后,我发现了这个:
http://michaelnthiessen.com/force-re-render/
也就是说我应该更改组件上的密钥,这将强制组件重新呈现。我还发现了这个:
https://vuejs.org/v2/guide/components-dynamic-async.html
其中有一个很好的例子说明了我正在尝试做的事情,但它并没有强制异步组件首先 initialize。这就是我需要异步组件执行的操作——在我切换选项卡之前它们不会初始化。事实上,它们甚至不会出现在网络呼叫中。 Vue 只是为它们生成一个占位符。
我成功了!我最终做的是从加载异步组件的代码中发出一个事件,以指示该组件已加载。该事件的侦听器会计算已加载的组件数量(它已经知道应该有多少),一旦收到正确数量的这些事件,它就会更改 this.active
的值( v-tabs
组件的 v-model
值(指示哪个选项卡当前处于活动状态)设置为“0”。我试过这个,因为正如我之前提到的,每当我切换标签时,异步组件都是 loading/rendering 。我还有 prev/next 按钮来设置 this.active
,今天我注意到如果我使用 "next" 按钮而不是单击选项卡,它会加载异步组件但不会推进选项卡.我已经弄清楚了如何从加载代码中发出事件,所以此时我所要做的就是捕获已加载组件的数量,然后操作 this.active
.
我可能会尝试更新我的 CodePen 以反映这一点,如果我这样做了,我会回来并做出相应的评论。现在,这是我最终得到的示例。我仍在添加一些东西以使其更健壮(例如,以防配置对象包含不存在的组件URL),但这是它的基本要点。
created: function() {
this.$on("componentLoaded", () => {
this.numTabsInitialized++;
if(this.numTabsInitialized == this.numTabs) {
// All tabs loaded; update active to force them to load
this.active = "0";
}
})
},
methods: {
loadComponent: function(config) {
var id = config.id;
var compPath = config.tabContent;
var self = this;
require([compPath], function(comp) {
Vue.component(id, comp);
self.$emit("componentLoaded");
});
}
}
我正在创建一个选项卡组件,它动态加载其 v-tab-item
组件,给定一个由 tabName
、id
和 tabContent
组成的配置对象数组是组件的资源位置。我成功加载了组件。但是,在我切换选项卡之前,它们实际上并没有初始化(或 运行 它们的 created()
方法)。我只是得到带有正确标签的空标签。使用 DOM 检查器最初仅显示 <componentId></componentId>
,然后当我切换选项卡时,这些标签将替换为组件的所有内容。
如何让动态组件在加载后立即初始化?
编辑:我在这里创建了一个 CodePen:
https://codepen.io/sgarfio/project/editor/DKgQON
但由于这是我的第一个 CodePen,我还没有想出如何引用项目中的其他文件(即如何设置 tabContent 以便 require.js 可以加载它们)。我在控制台中看到 "Access is denied",这听起来像是找到了文件但不允许访问它们,这很奇怪,因为所有文件都属于同一个项目。所以我的 CodePen 甚至不如我的实际项目。但也许它会帮助别人理解我正在尝试做的事情。
此外,在仔细研究之后,我发现了这个:
http://michaelnthiessen.com/force-re-render/
也就是说我应该更改组件上的密钥,这将强制组件重新呈现。我还发现了这个:
https://vuejs.org/v2/guide/components-dynamic-async.html
其中有一个很好的例子说明了我正在尝试做的事情,但它并没有强制异步组件首先 initialize。这就是我需要异步组件执行的操作——在我切换选项卡之前它们不会初始化。事实上,它们甚至不会出现在网络呼叫中。 Vue 只是为它们生成一个占位符。
我成功了!我最终做的是从加载异步组件的代码中发出一个事件,以指示该组件已加载。该事件的侦听器会计算已加载的组件数量(它已经知道应该有多少),一旦收到正确数量的这些事件,它就会更改 this.active
的值( v-tabs
组件的 v-model
值(指示哪个选项卡当前处于活动状态)设置为“0”。我试过这个,因为正如我之前提到的,每当我切换标签时,异步组件都是 loading/rendering 。我还有 prev/next 按钮来设置 this.active
,今天我注意到如果我使用 "next" 按钮而不是单击选项卡,它会加载异步组件但不会推进选项卡.我已经弄清楚了如何从加载代码中发出事件,所以此时我所要做的就是捕获已加载组件的数量,然后操作 this.active
.
我可能会尝试更新我的 CodePen 以反映这一点,如果我这样做了,我会回来并做出相应的评论。现在,这是我最终得到的示例。我仍在添加一些东西以使其更健壮(例如,以防配置对象包含不存在的组件URL),但这是它的基本要点。
created: function() {
this.$on("componentLoaded", () => {
this.numTabsInitialized++;
if(this.numTabsInitialized == this.numTabs) {
// All tabs loaded; update active to force them to load
this.active = "0";
}
})
},
methods: {
loadComponent: function(config) {
var id = config.id;
var compPath = config.tabContent;
var self = this;
require([compPath], function(comp) {
Vue.component(id, comp);
self.$emit("componentLoaded");
});
}
}