在页面上使用多个重的相同 VueJS 组件的正确方法是什么?
What is the proper way to use multiple heavy same VueJS components on a page?
我正在尝试将自定义输入创建为 VueJS 组件。它将有 <input type="text">
字段和按钮。该组件必须实现这样的行为:您可以键入具有自动完成功能的文本,或按下按钮打开带有数据库记录的模式对话框,然后按下 select 一个。像这样:
<div class="input-group">
<input type="text" class="form-control" placeholder="Search for...">
<span class="input-group-btn">
<button class="btn btn-default" type="button" @click="openModal">Choose</button>
</span>
</div>
模态对话框将包含复杂的逻辑和大量 HTML 代码。我想我会把模态对话框放在其他组件中。
毕竟我的自定义输入组件将在 table 行的页面上使用,例如:
<tr v-for="item in items">
<td><input-component :item="item"><input-component></td>
</tr>
table 可能包含 10-30 行,这是一个问题 - 我应该从我的自定义输入组件中排除繁重的模式对话框代码,还是在 VueJS 中有这么多重复 DOM?
我应该选择什么变体:
1) 排除模态对话框,将其放在页面顶部一次并从自定义输入组件中调用它
<body>
<modal-component></modal-component>
<table><tbody>
<tr v-for="item in items">
<td><input-component :item="item"><input-component></td>
</tr>
</tbody></table>
</body>
2) 包含模态对话框并在 DOM
中有数十个重复代码
<body>
<table><tbody>
<tr v-for="item in items">
<td><input-component :item="item"><input-component></td><!--now contains <modal-component></modal-component>-->
</tr>
</tbody></table>
</body>
整个页面只使用一个模态对话框。
使用数组中的相关数据填写对话框,如下所示
var dialogs = [
{ name: 'john', surname: 'snow' },
{ name: undefined, surname: undefined },
...
]
var currentDialog = 4
var dialogData = dialogs[currentDialog]
使用 dynamic component 并将组件类型绑定到响应式 属性。
Vue.component('customer-dialog', {
template: '<p>Customer Dialog</p>'
})
Vue.component('supplier-dialog', {
template: '<p>Supplier Dialog</p>'
})
var app = new Vue({
el: '#app',
data: {
dialog: null // initial dialog to use
},
methods: {
showDialog: function(d) {
this.dialog = d
// additional dialog initialization code
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.10/vue.js"></script>
<div id="app">
<component :is="dialog"></component>
<button @click="showDialog('customer-dialog')">Customers</button>
<button @click="showDialog('supplier-dialog')">Suppliers</button>
</div>
如果您想将 switched-out 对话框保留在内存中以便您可以保留它们的状态或避免 re-rendering,您可以将动态组件包装在一个元素中。
<keep-alive><component :is="dialog"></component></keep-alive>
我正在尝试将自定义输入创建为 VueJS 组件。它将有 <input type="text">
字段和按钮。该组件必须实现这样的行为:您可以键入具有自动完成功能的文本,或按下按钮打开带有数据库记录的模式对话框,然后按下 select 一个。像这样:
<div class="input-group">
<input type="text" class="form-control" placeholder="Search for...">
<span class="input-group-btn">
<button class="btn btn-default" type="button" @click="openModal">Choose</button>
</span>
</div>
模态对话框将包含复杂的逻辑和大量 HTML 代码。我想我会把模态对话框放在其他组件中。
毕竟我的自定义输入组件将在 table 行的页面上使用,例如:
<tr v-for="item in items">
<td><input-component :item="item"><input-component></td>
</tr>
table 可能包含 10-30 行,这是一个问题 - 我应该从我的自定义输入组件中排除繁重的模式对话框代码,还是在 VueJS 中有这么多重复 DOM?
我应该选择什么变体:
1) 排除模态对话框,将其放在页面顶部一次并从自定义输入组件中调用它
<body>
<modal-component></modal-component>
<table><tbody>
<tr v-for="item in items">
<td><input-component :item="item"><input-component></td>
</tr>
</tbody></table>
</body>
2) 包含模态对话框并在 DOM
中有数十个重复代码<body>
<table><tbody>
<tr v-for="item in items">
<td><input-component :item="item"><input-component></td><!--now contains <modal-component></modal-component>-->
</tr>
</tbody></table>
</body>
整个页面只使用一个模态对话框。
使用数组中的相关数据填写对话框,如下所示
var dialogs = [
{ name: 'john', surname: 'snow' },
{ name: undefined, surname: undefined },
...
]
var currentDialog = 4
var dialogData = dialogs[currentDialog]
使用 dynamic component 并将组件类型绑定到响应式 属性。
Vue.component('customer-dialog', {
template: '<p>Customer Dialog</p>'
})
Vue.component('supplier-dialog', {
template: '<p>Supplier Dialog</p>'
})
var app = new Vue({
el: '#app',
data: {
dialog: null // initial dialog to use
},
methods: {
showDialog: function(d) {
this.dialog = d
// additional dialog initialization code
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.10/vue.js"></script>
<div id="app">
<component :is="dialog"></component>
<button @click="showDialog('customer-dialog')">Customers</button>
<button @click="showDialog('supplier-dialog')">Suppliers</button>
</div>
如果您想将 switched-out 对话框保留在内存中以便您可以保留它们的状态或避免 re-rendering,您可以将动态组件包装在一个元素中。
<keep-alive><component :is="dialog"></component></keep-alive>