Closed jingxin2015 closed 5 months ago
@errorrik 能给点建议思路吗?
没必要。你要解决的是状态保存的问题。
看起来这个状态和 parent 和 owner 都无关,看起来这个粒度是 by 组件的,是自己组件内聚的。以及,我不确定你是依赖某个父环境存在,还是出现在任何地方都需要保持之前的状态。这是你需要考虑的问题,这些问题框架并不帮你解决,KeepAlive 是一个无脑封装
我还是建议自己封装解决。下面是我的一个思路,场景是,在某个爹一直存活的生命周期内,状态能被保存。但这不一定适应你的状态保存场景,仅供参考。
function keepAlive(Component) {
let key = (new Date).getTime() + Math.random();
let initData = Component.prototype.initData;
let attached = Component.prototype.attached;
let proto = {
initData() {
if (this.owner && this.owner.__keepAlive && this.owner.__keepAlive[key]) {
return this.owner.__keepAlive[key];
}
return initData.call(this);
},
attached() {
this.data.listen(change => {
if (this.owner) {
if (!this.owner.__keepAlive) {
this.owner.__keepAlive = {};
}
this.owner.__keepAlive[key] = this.data.get();
}
});
attached && attached.call(this);
}
}
return san.defineComponent(proto, Component);
}
const ManualCounter = san.defineComponent({
template: '<div>{{count}}<button on-click="add">+</button></div>',
add() {
this.d.count++;
},
initData() {
return {
count: 0
};
}
});
const AutoCounter = san.defineComponent({
template: '<div>{{count}}</div>',
attached() {
this.interval = setInterval(() => {
this.d.count++;
}, 1000)
},
detached() {
clearInterval(this.interval);
},
initData() {
return {
count: 0
};
}
});
const Entry = san.defineComponent({
components: {
'c-manual': keepAlive(ManualCounter),
'c-auto': keepAlive(AutoCounter)
},
template: `
<div>
<input type="radio" value="c-manual" checked="{= counter =}" name="counter">manual
<input type="radio" value="c-auto" checked="{= counter =}" name="counter">auto
<c s-is="counter" />
</div>
`,
initData() {
return {
counter: 'c-manual'
};
}
});
(new Entry).attach(document.body)
我的需求就是想在打开多个选项卡时,在已经打开的选项卡之间切换时需要保持状态,这些选项卡是通过 san-router 来打开的,上面的代码能够实现初始化数据的状态保持,但是在切换的时候还是会执行 attached 方法,这样就会调用后台方法获取数据,能否实现不去重新调用后端方法加载数据呢?
主要是用于实现同时打开多个选项卡页面的功能的,选项卡想通过 s-is 实现,如何保持状态?