-
-
Notifications
You must be signed in to change notification settings - Fork 16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: add useStorage #31
Conversation
src/useStorage/index.ts
Outdated
if (listenToStorageChanges) { | ||
tryOnLoad(() => { | ||
// this should be fine since we are in a mounted hook | ||
if (initOnMounted) update(); | ||
}); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it actually listens to storage changes. Can you please explain it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, I removed listenToStorageChanges
I think there's still a serious problem with not listening for storage changes. That's why I didn't introduce the useStorage method before, uni-app doesn't provide an API to handle this kind of listening. Suppose a user uses useStorage to get the data with key What do you guys think? Will be nice to listen to your thoughts! @okxiaoliang4 @edwinhuish |
the stores/userInfo.js export const userStore = useStorage("x-userStore", {
num: 0,
deep:{
a: 1
}
}); pageA import { userStore } from "@/stores/userStore";
const toNext = () => {
uni.navigateTo({
url: "/pages/pageB",
});
};
<button @click="toNext">userStore num is {{ userStore.num }}</button>
<button @click="toNext">userStore deep.a is {{ userStore.deep.a }}</button> pageB import { userStore } from "@/stores/userStore";
const toNext = () => {
uni.navigateTo({
url: "/pages/pageA",
});
};
const change = () => {
userStore.value.num += 1;
userStore.value.deep.a += 1;
}
<button @click="change">userStore num ++ {{ userStore.num }}</button>
<button @click="change">userStore deep.a ++ {{ userStore.deep.a }}</button>
<button @click="toPrev"> to page A</button> I have already tested the code above, and there are no issues. You can give it a try @ModyQyW . Thanks |
我认为应该跟useStorageAsync共用一份核心代码,因为差别就只有是否是异步的,监听逻辑我认为也应该类似于useStorageAsync目前使用的拦截器,因为拦截器可以拦截到开发者直接使用uni storage进行更新的情况,并且在H5的时候可以考虑直接内部改用vueuse/core中的useStorage这样可以做到多个窗口同步数据 |
The code in uni-use |
Listen for the storage changes will cause very impactful on performance. I think the code are fine, but need some impove:
Page A const store = useStorage('store_key', 'foo');
store.value = 'bar';
console.log(store.value); // bar Page B // Call useStorage with key 'store_key', will access directly from local variable in 'useStorage' context
const store = useStorage('store_key', 'foo');
console.log(store.value); // Here should be also 'bar'. |
Also, I'm agree with @okxiaoliang4 , |
The
const { pause: pauseWatch, resume: resumeWatch } = pausableWatch(data, () => write(data.value), {
flush,
deep,
eventFilter,
});
function update(event?: StorageEventLike) {
if (event && event.storageArea !== storage) return;
if (event && event.key == null) {
data.value = rawInit;
return;
}
if (event && event.key !== key) return;
pauseWatch();
try {
if (event?.newValue !== serializer.write(data.value)) data.value = read(event);
} catch (error) {
onError(error);
} finally {
// use nextTick to avoid infinite loop
if (event) nextTick(resumeWatch);
else resumeWatch();
}
} The
I tested again, referring to your code, and there were no issues. The mini-program also passed the test. My code is as follows: // pageA
const store = useStorage('store_key', 'foo');
const changeTest = () => {
store.value = 'bar';
console.info(store.value) // bar
};
const toNext = () => {
uni.navigateTo({
url: "/pages/pageB",
});
};
<button @click="toNext">{{ store }}</button>
<view>{{ store }}</view> // pageB
const store = useStorage('store_key', 'foo');
const changeTest = () => {
store.value = String(new Date().getTime());
console.info(store.value) // bar
};
const toPrev = () => {
uni.navigateBack({
delta: 1,
});
};
<button @click="toPrev">{{ store }}</button>
<view>{{ store }}</view> Moreover, I believe the |
The code I submitted for |
The problem with syncing many pages doesn't always need But this kind of sync update is rarely needed, almost not important, Because users rarely directly update code in already defined localStorage, Update data can be exported from the stores, and always change data.value.xxx. which then triggers changes in data. Still, |
key prefix is something like: const prefix = '__UNI_STORAGE__';
function useStorage( key: string ) {
const keyWithPrefix = prefix + key;
function read() {
const raw = storage.getItem(keyWithPrefix);
return JSON.parse(raw);
}
// Same for write()
return { read }
}
When some on use this function in one page and unfortunately also access storage with same key in another page. Page A const store = useStorage('user');
// Another code.... Page B // Set value to storage with same 'key' (At least it looks the same) will not affect the 'store' variable of page A
const user = storage.setItem('user', 'john'); |
In my understanding, useStorage most important thing is It should be something take and use. Also can be paired with pinia. In your code way, it's better to use pinia, and it's already very reliable. |
I never use After read the doc and code, it's not the one I mean My suggestion: if simple code can work well, don't import third part code. It will make the things complicate. |
The third point "Store all values to a reactive/ref variable", just I'm saying before, useStorage should be something simple and easy to use. And should avoid possible mistake of user. |
Because you access the data with difference page, and reloaded data from storage. You can try it with same page but difference components. |
You should check how to use |
I've already said above, the problem isn't big, it's seldom used this way.
|
I think there are some misunderstandings. In pageB, it should be |
我感觉 H5 直接内部改用 @vueuse/core 中的 useStorage 可能不太好,会带来额外的心理负担。 useStorageAsync 目前使用的拦截器不支持同步 api,所以这应该是目前最大的困难。 |
Good point. PR welcome. |
Description
Add
useStorage
, which is simpler and more direct compared touseStorageAsync
and is used more often in daily scenarios.