我的需求:
我希望做一个列表组件,其list在组件内部自行管理;
我的SPA上有n个视图(动态生成),每个视图都使用上述组件,在动态组件和vue-router的方式下发现,组件其实并没有生成多个实例。
查阅了资料和写了demo,发现好像只有显式使用组件tag或new出来挂载才会生成新实例。
看了一些别人写的demo,发现是用的其实就是同一个组件,同一个实例,只是每个视图传的data渲染不一样,这样实现或许更符合mvvm的思维。
但是我想知道,Vue是不推荐每一个视图都生成新实例呢?还是我的理解有误?存在动态生成视图并生成对应新实例的方法吗?
(有这个想法的原因可能是因我希望保留每一个页面的dom和data,不想每次切页面的时候重新渲染,对应不同视图用不同组件而言这个很简单,使用keep-alive就可以缓存,但是多个视图同一个组件的时候似乎是不一样的)
新手提问,请各位高手不吝赐教。
1.使用Vue动态组件:
// 动态视图
<component :is="currentView" keep-alive></component>
// 组件定义
var ItemView = Vue.component('ItemView', {
template: '<div><span>{{name}}</span><input v-model="name" /></div>',
data: function(){
return {
name: 'test'
}
},
created: function () {
console.log('created test');
}
})
// 注册视图
components: {
hot: ItemView ,
new: ItemView
}
这种方式下,我在输入框内修改了name
的值,切换视图时发现另一个的name
也修改了。
我认为这说明了切换的是同一个实例,但我预期效果是两个实例,其data是两个孤立作用域。。
2.使用vue-router
// 路由映射
'/hot': {
name: 'hot',
component: require('ItemView.vue')
},
'/new': {
name: 'new'
component: require('ItemView.vue')
}
// ItemView.vue
data() {
return {
name: ''
}
},
route: {
activate({next}){
console.log('activate');
this.pno = this.$route.name;
next();
},
data({next}){
console.log(this.name);
next();
}
}
router方式下,切换路由是发现,activate只执行一次,data钩子输出的name
都是第一次进入的路由名,在设置canReuse以后,activate每次都执行,输出正常。
但给我的感觉就是一个组件在切,每次在钩子里更改了数据。
但我希望是每个视图对应一个新的实例。
碰到了同样的问题,所以告诉你我的解决办法
在路由里配置component的时候使用extends, 或者使用es6的解构
也有尝试使用下面创建实例的方法,但是行不通