solid-alive 0.3.3 → 0.3.51

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,267 @@
1
+ # solid-alive
2
+
3
+ #### 安装(install)
4
+
5
+ - pnpm add solid-alive / npm i solid-alive / yarn add solid-alive
6
+
7
+ #### 参数(describe)
8
+
9
+ - **AliveProvider**
10
+ - children :JSXElement 必须
11
+ - include : [] 缓存的id 数组, 默认都不缓存, 如 ["home",'abc'], 当你 删除一个缓存时, 父id与子id要一起删除
12
+ - scrollContainerName : string 保存的滚动条的 left 与 top位置, 如: html, body, .abxasdfe, #asdf
13
+ - transitionEnterName : string 进入页面的动画名称, 要 css keyframes
14
+
15
+ ```css
16
+ <!-- @/assets/css/index.css -- >
17
+ .appear {
18
+ animation: showkeyframes 0.45s ease;
19
+ }
20
+ @keyframes showkeyframes {
21
+ 0% {
22
+ opacity: 0;
23
+ }
24
+ 100% {
25
+ opacity: 1;
26
+ }
27
+ }
28
+ ```
29
+
30
+ - **aliveTransfer**
31
+ - component : JSXElement, 必须
32
+ - id : string 保存的唯一值, 如 home, 在AliveProvider 的 include 要包括这些id 才会缓存, 必须
33
+ - params : Object
34
+ - isolated : 单独组件, 当不是Route组件 时使用, 默认false, !!!不要在已缓存的组件中使用,不要在已缓存的组件中使用,不要在已缓存的组件中使用
35
+ - disableAnimation : 当前页面不用动画, 默认 false
36
+ - stopSaveScroll : 当面组件不用去管滚动条 , 默认 false
37
+ - transitionEnterName : 当面页面的单独动画, 要 css keyframes
38
+
39
+ - **onActivated** : Function 激活缓存页面时会触发的函数
40
+ - **onDeactivated** : Function 离开缓存页面时会触发的函数
41
+ - **useAliveContext** : Function 父子缓存路由会有 Context 时, 可能会用到的hooks
42
+ - **useAlive** hook
43
+ - aliveScrollDelete : 删除 保存了的 dom
44
+ - aliveSaveScrollDtv: 指令 保存 dom 滚动条数据
45
+ <!-- - aliveFrozen: 在你重新生成 Route 时 , 要执行这个函数 1iuxs -->
46
+
47
+ #### 使用(use)
48
+
49
+ 1. AliveProvider
50
+
51
+ ```tsx
52
+ // src/index.tsx
53
+ import { render } from "solid-js/web"
54
+
55
+ import { AliveProvider, aliveTransfer } from "solid-alive"
56
+ // import { userInfo } from "./store/userInfo.ts"
57
+
58
+ import "@/assets/css/index.css"
59
+ // import Container from "./layout/Container/index.tsx"
60
+
61
+ import { lazy, type Component, For } from "solid-js"
62
+ import { Route, Router } from "@solidjs/router"
63
+
64
+ // 使用 import.meta.glob 动态导入所有组件
65
+ // const modules = import.meta.glob<{ default: Component<any> }>([
66
+ // "./view/**/**.tsx",
67
+ // "./view/**.tsx",
68
+ // ])
69
+ // const transferRouter = (data: MenuData[]) => (
70
+ // <For each={data}>
71
+ // {(item) => {
72
+ // let module = modules[`./view${item.realPath}`]
73
+ // if (!module) return null
74
+ // return (
75
+ // <Route
76
+ // component={aliveTransfer(lazy(module), item.id)}
77
+ // path={item.path}
78
+ // >
79
+ // {item.children ? transferRouter(item.children) : null}
80
+ // </Route>
81
+ // )
82
+ // }}
83
+ // </For>
84
+ // )
85
+
86
+ // 导入 Home 组件
87
+ // import Home from "@/view/Home/index.tsx"
88
+ // const Home1 = aliveTransfer(Home, "home")
89
+
90
+ render(
91
+ () => (
92
+ <AliveProvider
93
+ include={["home", "about"]}
94
+ transitionEnterName="appear"
95
+ scrollContainerName=".container"
96
+ >
97
+ {/* 1 */}
98
+ {/* <App /> */}
99
+ {/* 2 */}
100
+ {/* <Router root={Container} children={routes} /> */}
101
+ {/* 3 */}
102
+ <Router children={routes} />
103
+ {/* 4 */}
104
+ {/* <Router root={Container}>
105
+ {transferRouter([])}
106
+ </Router> */}
107
+ {/* 5 */}
108
+ {/* <Router root={Container}>
109
+ <Route path={"/cart"} component={Hom1}>
110
+ <Route path={""} component={G1}></Route>
111
+ <Route path={"h"} component={H1}></Route>
112
+ </Route>
113
+ </Router> */}
114
+ </AliveProvider>
115
+ ),
116
+ document.getElementById("root")!,
117
+ )
118
+ ```
119
+
120
+ ```tsx
121
+ // src/router/index.ts
122
+ import { lazy } from "solid-js"
123
+ import { aliveTransfer } from "solid-alive"
124
+ const routes = [
125
+ {
126
+ path: "/",
127
+ component: aliveTransfer(
128
+ lazy(() => import("@/view/Home/index")),
129
+ "home",
130
+ ),
131
+ children: [
132
+ {
133
+ path: "",
134
+ component: aliveTransfer(
135
+ lazy(() => import("@/view/Home/C")),
136
+ "c",
137
+ // {
138
+ // "disableAnimation":true,
139
+ // "isolated":true,
140
+ // "stopSaveScroll":true,
141
+ // "transitionEnterName":'appear'
142
+ // }
143
+ ),
144
+ },
145
+ ],
146
+ },
147
+ {
148
+ path: "/about",
149
+ component: aliveTransfer(
150
+ lazy(() => import("@/view/About/index")),
151
+ "about",
152
+ ),
153
+ },
154
+ ]
155
+
156
+ export default routes
157
+ ```
158
+
159
+ 2. Home 组件
160
+
161
+ ```tsx
162
+ // src/view/Home/index.tsx
163
+ import { createContext, useContext } from "solid-js"
164
+ import { onActivated, onDeactivated, useAlive } from "solid-alive"
165
+
166
+ export const DataContext = createContext<{ value: string }>()
167
+
168
+ export default function Home(props: any) {
169
+ //@ts-ignore
170
+ const { aliveSaveScrollDtv, aliveScrollDelete } = useAlive()
171
+ const divRef: HTMLDivElement | null = null
172
+ onActivated(() => {
173
+ console.log("home - onActivated")
174
+ })
175
+
176
+ onDeactivated(() => {
177
+ console.log("home - onDeactivated")
178
+ })
179
+
180
+ const delDom = () => {
181
+ // 删除 aliveSaveScrollDtv 保存的 dom元素
182
+ divRef && aliveScrollDelete(divRef)
183
+ }
184
+
185
+ return (
186
+ <ThemeContext.Provider value={{ value: "123" }}>
187
+ <div>
188
+ home <button> 清除路由 </button>
189
+ {props.children}
190
+ <div
191
+ ref={(cn) => (divRef = cn)}
192
+ use:aliveSaveScrollDtv
193
+ // use:aliveSaveScrollDtv={(v) => (divRef = v)}
194
+
195
+ style="height:300px;overflow:scroll"
196
+ >
197
+ <div style="height:500px">
198
+ Lorem ipsum dolor sit amet consectetur adipisicing elit. Ut
199
+ praesentium debitis dolorum sed dolorem doloremque aliquam beatae,
200
+ architecto corrupti in qui, harum expedita voluptatum fugit
201
+ necessitatibus suscipit! Animi, nemo quas! Lorem ipsum dolor sit
202
+ amet consectetur adipisicing elit. Reiciendis, quaerat asperiores
203
+ libero, quasi vitae hic officiis repellendus sint tempore totam
204
+ saepe dolores dolorem magni ab suscipit magnam distinctio
205
+ exercitationem omnis.
206
+ </div>
207
+ </div>
208
+ </div>
209
+ </ThemeContext.Provider>
210
+ )
211
+ }
212
+ ```
213
+
214
+ 3. Home 下的 子路由 c.tsx
215
+
216
+ ```tsx
217
+ import { getOwner, useContext } from "solid-js"
218
+ import { onActivated, useAliveContext } from "solid-alive"
219
+ import { DataContext } from "."
220
+
221
+ export default function C() {
222
+ // no value
223
+ const data = useContext(DataContext)
224
+ // have value
225
+ const data1 = useAliveContext(DataContext)
226
+ console.log(data, "data")
227
+ console.log(data1, "data1")
228
+ onActivated(() => {
229
+ console.log(getOwner())
230
+ console.log("C - onActivated")
231
+ // console.log(getOwner())
232
+ })
233
+
234
+ return (
235
+ <div>
236
+ ccccccccc <input type="text" /> {data?.value?.()}cccccc
237
+ </div>
238
+ )
239
+ }
240
+ ```
241
+
242
+ 4. isolated
243
+
244
+ ```tsx
245
+ import Aside from "xxxx"
246
+
247
+ const Aside1 = aliveTransfer(Aside, "aside", {
248
+ isolated: true,
249
+ disableAnimation: true,
250
+ })
251
+
252
+ /** 最外的容器 */
253
+ export function Container(props: any) {
254
+ return (
255
+ <div class="container">
256
+ {props.children}
257
+ <Aside1 />
258
+ </div>
259
+ )
260
+ }
261
+ ```
262
+
263
+ #### 已知问题(issue)
264
+
265
+ - 父子路由的 context 问题
266
+ - 多个已缓存的路由有子路由时, 未缓存的子路由 会共享子组件
267
+ - 如果父路由缓存, 子路由不缓存时会有 路由组件共享问题
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import{createComponent as e}from"solid-js/web";import{createContext as n,useContext as t,createRoot as r,createEffect as i,onCleanup as o,untrack as l}from"solid-js";import{produce as s,createStore as a}from"solid-js/store";const d=Symbol("currentId"),v=Symbol("setActiveCb"),u=Symbol("parentId");var c=n({elements:{},setElements:()=>{},setActiveCb:()=>{},aliveIds:()=>{},info:{frozen:!1},transitionEnterName:()=>{}});const f=n({[d]:void 0,[v]:()=>{}});var m=(n,t,r,i)=>e(f.Provider,{value:{[d]:i,[v]:r,[u]:t},get children(){return n()}}),p=e=>{for(;"function"==typeof e;)e=e();return e},h=!1;function y(e,n,l){return function(a){var v,u,y,A,b=t(c),E=t(f)[d],I=b.transitionEnterName();if(!(null===(v=b.aliveIds())||void 0===v?void 0:v.includes(n)))return m((()=>e(a)));if(E&&(null===(u=b.elements[n])||void 0===u?void 0:u.parentId)&&b.elements[n].parentId!==E)return null;b.elements[n]?b.info.frozen?(null===(y=b.elements[n].subsets)||void 0===y?void 0:y.some((e=>b.elements[e])))||(b.info.frozen=!1):null===(A=b.elements[n].onActivated)||void 0===A||A.forEach((e=>e())):(b.setElements({[n]:{id:n,subsets:Array.isArray(l)?l:null}}),r((t=>{b.setElements(s((r=>{var i;r[n].dispose=t,r[n].parentId=null===(i=Object.values(b.elements).find((e=>{var t;return null===(t=e.subsets)||void 0===t?void 0:t.includes(n)})))||void 0===i?void 0:i.id,r[n].element=m((()=>e(a)),r[n].parentId,b.setActiveCb,n)})))})));var g=e=>{if(e instanceof HTMLElement&&!h){h=!0,e.classList.add(I);var n=()=>{e.removeEventListener("animationend",n),e.classList.remove(I),h=!1};e.addEventListener("animationend",n)}};return I&&!b.info.frozen&&i((()=>{if(!h){var e=n;do{b.elements[e].parentId||g(p(b.elements[e].element)),e=b.elements[e].parentId}while(e)}})),o((()=>{var e,t;b.info.frozen||null===(t=null===(e=b.elements[n])||void 0===e?void 0:e.onDeactivated)||void 0===t||t.forEach((e=>e()))})),b.elements[n].element}}function A(n){const[t,r]=a();return i((e=>{var i=Array.isArray(n.include)?n.include:[];if(e.length>i.length){var o=new Set(i);(e=>{var n,i;if(Array.isArray(e))for(var o of e)null===(i=null===(n=t[o])||void 0===n?void 0:n.dispose)||void 0===i||i.call(n),r({[o]:void 0})})(e.filter((e=>!o.has(e))))}return i}),Array.isArray(n.include)?n.include:[]),e(c.Provider,{value:{info:{frozen:!1},elements:t,setElements:r,setActiveCb:(e,n,t,i)=>{r(s((r=>{r[e][n]?r[e][n][i](t):"add"===i&&(r[e][n]=new Set([t]))})))},aliveIds:()=>n.include,transitionEnterName:()=>n.transitionEnterName},get children(){return n.children}})}const b=(()=>{let e=[],n=!1,t=()=>{},r=/iPad|iPhone|iPod/.test(navigator.userAgent)&&!window.MSStream,i=()=>{n=!1;var t=e.slice(0);e.length=0;for(let e=0;e<t.length;e++)t[e]()};if("undefined"!=typeof Promise&&"function"==typeof Promise.prototype.then){const e=Promise.resolve();t=()=>{e.then(i),r&&setTimeout((()=>{}))}}else if("undefined"!=typeof MutationObserver){let e=1;const n=new MutationObserver(i),r=document.createTextNode(String(e));n.observe(r,{characterData:!0}),t=()=>{e=(e+1)%2,r.data=String(e)}}else t=()=>{setTimeout(i,0)};return r=>{e.push(r),n||(n=!0,t())}})();function E(e,n){l((()=>{var r,i=t(f),l=i[d];l&&(null===(r=i[v])||void 0===r||r.call(i,l,e,n,"add"),"onActivated"===e&&b(n),o((()=>{var t;null===(t=i[v])||void 0===t||t.call(i,l,e,n,"delete"),n=null})))}))}function I(e){E("onActivated",e)}function g(e){E("onDeactivated",e)}function S(){var e=t(c).info;return()=>e.frozen=!0}export{A as AliveProvider,y as aliveTransfer,b as nextTick,I as onActivated,g as onDeactivated,S as useAliveFrozen};
1
+ import{createComponent as e}from"solid-js/web";import{createStore as l,produce as t}from"solid-js/store";import{createContext as n,createMemo as o,useContext as s,createRoot as i,getOwner as c,createComponent as r,createEffect as d,untrack as a,onCleanup as v,runWithOwner as u}from"solid-js";const f=n(),h=n();function m(n){const[s,i]=l({}),c=(e,l,n,o)=>i(t(t=>t[e][l]?t[e][l][o](n):"add"===o&&(t[e][l]=new Set([n])))),r=(e,l,n)=>i(t(t=>{const o=t[e].scrollDtvs;"set"===n?(!o&&(t[e].scrollDtvs=new Map),t[e].scrollDtvs.set(l,{left:0,top:0})):(null==o?void 0:o.has(l))&&(o.delete(l),!o.size&&delete t[e].scrollDtvs)})),d=o(e=>{if(!Array.isArray(n.include))return new Set([]);if(null==e?void 0:e.size){for(const l of n.include)e.delete(l);e.size&&(l=e,i(t(e=>{(l=>{var t,n;for(const o of l)e[o]&&(e[o].dispose(),e[o].parentId&&(null===(n=null===(t=e[e[o].parentId])||void 0===t?void 0:t.childIds)||void 0===n||n.delete(o)),e[o].component=null,e[o].owner=null,delete e[o])})(l)})))}var l;const o=new Set(n.include);return o.size&&o.size!==n.include.length&&console.warn("[solid-alive]:include中有值重复"),o});return e(f.Provider,{get value(){return{caches:s,include:d,currentIds:new Set,setCaches:i,setActive:c,aniName:()=>n.transitionEnterName,scrollName:n.scrollContainerName,setDirective:r}},get children(){return n.children}})}let p=!1;const I=(l,n,o)=>((null==o?void 0:o.isolated)||(p=!0),function(m){if(!n)return console.error(`[solid-alive]: id:'${n}' 不正确`),null;const I=s(f);if(!I||!I.include().has(n))return l(m);const S=(null==o?void 0:o.transitionEnterName)||I.aniName(),w=s(h),C=()=>{var e;return!(null==w?void 0:w.id)||(null===(e=I.caches[n])||void 0===e?void 0:e.parentId)===w.id},D=e=>(null==o?void 0:o.isolated)||I.currentIds.add(e);if(I.caches[n])D(n);else{const s=(null==o?void 0:o.isolated)?null:[...I.currentIds].at(-1);s&&I.caches[s]&&I.setCaches(t(e=>{const l=e[s];l.childIds?l.childIds.add(n):l.childIds=new Set([n])})),D(n),I.setCaches({[n]:{id:n,parentId:s,init:null}}),i(o=>I.setCaches(t(t=>{t[n].dispose=o,t[n].owner=c(),t[n].component=e(h.Provider,{value:{id:n},get children(){return r(l,m)}})})))}const z=e=>{var l;const s=I.scrollName;if(!s||(null===(l=I.caches[n].childIds)||void 0===l?void 0:l.size)||(null==o?void 0:o.stopSaveScroll))return;const i=document.querySelector(s);if(!i)return console.warn(`[solid-alive]:未找到为scrollContainerName=${s} 的HTML元素`);"set"===e?requestAnimationFrame(()=>i.scrollTo(I.caches[n].scrollContainer||{left:0,top:0})):I.setCaches(t(e=>{const{scrollLeft:l,scrollTop:t}=i;e[n].scrollContainer={left:l,top:t}}))};let A=null;return d(()=>{var e;const l=I.caches[n];l?C()&&(p&&!(null==o?void 0:o.isolated)&&(null===(e=l.childIds)||void 0===e?void 0:e.size)&&(p=!1),l.init||!l.hasEl&&!(()=>{var e,l;if(null===(l=null===(e=I.caches[n])||void 0===e?void 0:e.component)||void 0===l?void 0:l.call(e))return I.setCaches(t(e=>{e[n].init=!0,e[n].hasEl=!0;for(const l of e[n].aOnceSet||[])l();delete e[n].aOnceSet})),!0})()||a(()=>{(()=>{var e,l,t,s;if(S&&!(null==o?void 0:o.disableAnimation)){let o=n;for(;o;){const l=null===(e=I.caches[o])||void 0===e?void 0:e.parentId;if(!l)break;o=l}(s=null===(t=null===(l=I.caches[o])||void 0===l?void 0:l.component)||void 0===t?void 0:t.call(l))instanceof HTMLElement&&(s.classList.add(S),A=()=>{A&&(s.removeEventListener("animationend",A),s.classList.remove(S))},s.addEventListener("animationend",A))}})(),z("set");const{scrollDtvs:e,aSet:t}=l;for(const l of e||[])l[0].scrollTo(l[1]);for(const e of t||[])e()})):console.warn(`[solid-alive]: include中 id = ${n} 的值不存在`)}),v(()=>{var e;if(!(null==o?void 0:o.isolated)&&(p||!I.caches[n]))return;null==A||A(),A=null;const l=I.caches[n];if(I.currentIds.has(n))if(l.parentId){I.currentIds.delete(n);const t=e=>{var l;for(const n of e){I.currentIds.delete(n);const e=null===(l=I.caches[n])||void 0===l?void 0:l.childIds;(null==e?void 0:e.size)&&t(e)}};(null===(e=l.childIds)||void 0===e?void 0:e.size)&&t(l.childIds)}else I.currentIds.clear();if(C()){z("save"),I.setCaches(t(e=>{for(const l of e[n].scrollDtvs||[]){const{scrollLeft:e,scrollTop:t}=l[0];l[1].left=e,l[1].top=t}e[n].init=!1}));for(const e of l.dSet||[])e()}}),C()&&u(I.caches[n].owner,()=>I.caches[n].component)}),S=(e,l)=>{if("function"!=typeof l)return;const{id:t}=s(h)||{},n=s(f);t&&n&&(n.setActive(t,e,l,"add"),v(()=>{n.setActive(t,e,l,"delete")}))},w=e=>{S("aSet",e)},C=e=>{S("dSet",e)},D=()=>{const{id:e}=s(h)||{},l=s(f);return{aliveId:e,aliveScrollDelete:t=>e&&(null==l?void 0:l.setDirective(e,t,"delete")),aliveSaveScrollDtv:(t,n)=>{e&&!1!==(null==n?void 0:n()(t))&&(null==l||l.setDirective(e,t,"set"))}}},z=e=>{const t=s(f),{id:n}=s(h)||{},[o,i]=l();return n&&(null==t||t.setActive(n,"aOnceSet",()=>{u(c(),()=>{i(s(e))})},"add")),o};export{m as AliveProvider,I as aliveTransfer,w as onActivated,C as onDeactivated,D as useAlive,z as useAliveContext};
@@ -1,8 +1,19 @@
1
- import { ProveiderProps } from "./types";
1
+ import type { AliveProviderProps } from "./types";
2
2
  /**
3
- * @description Alive
4
- * @param children jsx.element
5
- * @param {Arrya<string> | null} [include] 哪些路由要缓存, 默认不缓存, ['/','/about',...]
6
- * @param {string} [transitionEnterName] 动画名称 transitionEnterName="appear"
7
- */
8
- export default function AliveProvider(props: ProveiderProps): import("solid-js").JSX.Element;
3
+ * @description 容器
4
+ * @param {JSXElement} children
5
+ * @param {Array<string>} [include] ['home','about']
6
+ * @param {string} [transitionEnterName] 动画名称, 要 css keyframes 动画
7
+ * @param {string} [scrollContainerName] 滚动容器, 如 html, body, .contain, #xxy, ...
8
+ * @example
9
+ * ```jsx
10
+ * <AliveProvider
11
+ include={['home','about']}
12
+ transitionEnterName="ease-show"
13
+ scrollContainerName=".contain"
14
+ >
15
+ <Router root={Contain} children={routes} />
16
+ </AliveProvider>
17
+ * ```
18
+ * */
19
+ export default function (props: AliveProviderProps): import("solid-js").JSX.Element;
@@ -1,3 +1,17 @@
1
- export declare function onActivated(cb: () => void): void;
2
- export declare function onDeactivated(cb: () => void): void;
3
- export declare function useAliveFrozen(): () => boolean;
1
+ /**
2
+ * @description 进入缓存
3
+ * ```tsx
4
+ * import { onActivated } from 'solid-alive'
5
+ * //use
6
+ * onActivated(()=> console.log(234))
7
+ * ```
8
+ */
9
+ export declare const onActivated: (cb: () => void) => void;
10
+ /**
11
+ * @description 离开缓存
12
+ * ```tsx
13
+ * import { onDeactivated } from 'solid-alive'
14
+ * onDeactivated(()=> console.log(234))
15
+ * ```
16
+ */
17
+ export declare const onDeactivated: (cb: () => void) => void;
@@ -1,8 +1,23 @@
1
- import { JSX } from "solid-js";
1
+ import { type JSXElement } from "solid-js";
2
2
  /**
3
- * @description Alive 组件用的 转换函数; aliveTransfer(Comp, ‘/home’)
4
- * @param { ()=> JSX.Element } Component () => JSX.Element
5
- * @param { string } id string,自己的id 值,一定要唯一
6
- * @param { Array<string> } [subsets] [string,...], 子组件的 id值 可不传
7
- */
8
- export default function aliveTransfer(Component: <T>(props: T) => JSX.Element, id: string, subsets?: Array<string> | null): <T>(props: T) => JSX.Element;
3
+ * @description 转换
4
+ * @param {()=> JSXElement} Component 组件
5
+ * @param {string} id 唯一id
6
+ * @param {{isolated?:boolean, disableAnimation?:boolean, transitionEnterName?:string}} [params] 其它参数
7
+ * @example
8
+ * ```tsx
9
+ * import Home from 'xxx'
10
+ * const Home1 = aliveTransfer(Home, 'home')
11
+ * ```
12
+ * */
13
+ declare const aliveTransfer: (Component: <T>(props: T) => JSXElement, id: string, params?: {
14
+ /** 成一个独立缓存组件 */
15
+ isolated?: boolean;
16
+ /** 禁用动画 */
17
+ disableAnimation?: boolean;
18
+ /** 动画名称, 要 css keyframes */
19
+ transitionEnterName?: string;
20
+ /** 当前组件不去管制 滚动条 */
21
+ stopSaveScroll?: boolean;
22
+ }) => <T extends Record<string, any>>(props: T) => import("solid-js").JSX.Element;
23
+ export default aliveTransfer;
@@ -1,11 +1,14 @@
1
- import { Context } from "./types";
2
- export declare const CURRENTID: unique symbol;
3
- export declare const SETACTIVECB: unique symbol;
4
- export declare const PARENTID: unique symbol;
5
- declare const _default: import("solid-js").Context<Context>;
6
- export default _default;
7
- export declare const ChildContext: import("solid-js").Context<{
8
- [CURRENTID]: string | undefined;
9
- [SETACTIVECB]?: Context["setActiveCb"];
10
- [PARENTID]?: string;
11
- }>;
1
+ declare const Context: import("solid-js").Context<{
2
+ currentIds: Set<string>;
3
+ include: import("solid-js").Accessor<Set<string>>;
4
+ caches: Record<string, import("./types").Cache>;
5
+ setCaches: import("solid-js/store").SetStoreFunction<import("./types").Caches>;
6
+ setActive: (id: string, t: import("./types").Activate, cb: () => void, t1: import("./types").SetType) => void;
7
+ aniName: () => string | void;
8
+ scrollName: import("./types").AliveProviderProps["scrollContainerName"];
9
+ setDirective: (id: string, dom: HTMLElement, t: import("./types").MapType) => void;
10
+ } | undefined>;
11
+ declare const ChildContext: import("solid-js").Context<{
12
+ id: string;
13
+ } | undefined>;
14
+ export { ChildContext, Context };
@@ -0,0 +1,46 @@
1
+ import { type Context } from "solid-js";
2
+ /**
3
+ * @description alive hook
4
+ * @example
5
+ * ```jsx
6
+ * //@ts-ignore
7
+ * const { aliveScrollDelete, aliveSaveScrollDtv } = useAlive()
8
+ *
9
+ * export function Fn(){
10
+ * const divRef
11
+ * const del = () => { divRef && aliveScrollDelete(divRef) }
12
+ *
13
+ * return <div use:aliveSaveScrollDtv >123</div>
14
+ * }
15
+ *
16
+ * ```
17
+ */
18
+ export declare const useAlive: () => {
19
+ /** 当前id */
20
+ aliveId: string | undefined;
21
+ /**
22
+ * @description 删除 dom的滚动条
23
+ * @example
24
+ * ```jsx
25
+ * aliveScrollDelete(divRef)
26
+ * ```
27
+ * */
28
+ aliveScrollDelete: (dom: HTMLElement) => void | "" | undefined;
29
+ /**
30
+ * @description directive 指令: 保存 dom的滚动条
31
+ * @example
32
+ * ```jsx
33
+ * <div use:aliveSaveScrollDtv >123</div>
34
+ * ```
35
+ * */
36
+ aliveSaveScrollDtv: (el: HTMLElement, v?: () => (v: HTMLElement) => Boolean | void | any) => void;
37
+ };
38
+ /**
39
+ * @description alive context
40
+ * @example
41
+ * ```
42
+ * import UserContext from 'xxx'
43
+ * const data = useAliveContext(UserContext)
44
+ * ```
45
+ */
46
+ export declare const useAliveContext: <T>(context: Context<T>) => T;
@@ -1,5 +1,5 @@
1
- import aliveTransfer from "./aliveTransfer";
2
1
  import AliveProvider from "./AliveProvider";
3
- import { onActivated, onDeactivated, useAliveFrozen } from "./active";
4
- import nextTick from "./nextTick";
5
- export { aliveTransfer, AliveProvider, onActivated, onDeactivated, useAliveFrozen, nextTick };
2
+ import aliveTransfer from "./aliveTransfer";
3
+ import { onActivated, onDeactivated } from "./active";
4
+ import { useAlive, useAliveContext } from "./hooks";
5
+ export { AliveProvider, onActivated, onDeactivated, useAliveContext, aliveTransfer, useAlive };
@@ -1,47 +1,81 @@
1
- import { Owner, JSX, Accessor } from "solid-js"
2
- import { SetStoreFunction } from "solid-js/store"
1
+ import type { JSXElement, Accessor, Owner } from "solid-js"
2
+ import type { SetStoreFunction } from "solid-js/store"
3
+ // 提示扩展
4
+ export type Expand<T> = T extends infer O ? { [K in keyof O]: O[K] } : never
3
5
 
4
- export type EmitType = keyof Emit
5
-
6
- export type EmitValue<T extends EmitType> = Emit[T]
7
-
8
- export type Activate = "onActivated" | "onDeactivated"
9
-
10
- export interface Emit {
11
- onActivated: () => void
12
- onDeactivated: () => void
13
- }
14
-
15
- export interface ProveiderProps {
16
- children: JSX.Element
6
+ export type AliveProviderProps = {
7
+ /** 子组件 */
8
+ children: JSXElement
9
+ /** 缓存的路由, 如 include:['home','about'] */
17
10
  include?: Array<string>
11
+ /** 动画类名,要 css keyframes 动画 */
18
12
  transitionEnterName?: string
13
+ /** 保存滚动条, 使用 document.querySelector(scrollContainerName) 获取dom */
14
+ scrollContainerName?: string
19
15
  }
20
16
 
21
- export interface Info {
22
- frozen: boolean
23
- }
24
-
25
- export interface Element {
17
+ /** 缓存的数据 */
18
+ export type Cache = Expand<{
19
+ /** 唯一值 */
26
20
  id: string
27
- element: JSX.Element
28
- subsets?:Array<string> | null
29
- dispose?: () => void
30
- onActivated?: Set<() => void>
31
- onDeactivated?: Set<() => void>
32
- parentId?: string
33
- owner?: Owner | null
34
- }
35
- export interface Context {
36
- elements: Record<string, Element>
37
- setElements: SetStoreFunction<{}>
38
- aliveIds: () => Array<string> | undefined
39
- setActiveCb: (
40
- id: string,
41
- t: Activate,
42
- cb: () => void,
43
- t1: "add" | "delete"
44
- ) => void
45
- info: { frozen: boolean }
46
- transitionEnterName: () => string | void
21
+ /** 表明dom加载过了 */
22
+ hasEl?: boolean
23
+ /** 是否有加载过, */
24
+ init?: boolean
25
+ /** 其子数据 */
26
+ childIds?: Set<string>
27
+ /** 父级 */
28
+ parentId?: string | null
29
+ /** JSX */
30
+ component?: JSXElement | null
31
+ /** 上下文 */
32
+ owner: Owner | null
33
+ /** 销毁函数 */
34
+ dispose: () => void
35
+ /** 只执行一次的 active */
36
+ aOnceSet?: Set<() => void> | null
37
+ /** 激活 */
38
+ aSet?: Set<() => void>
39
+ /** 离开 */
40
+ dSet?: Set<() => void>
41
+ /** 当 saveScroll 有值时 */
42
+ scrollContainer?: { left: number; top: number }
43
+ /** 指令的 滚动条数据 */
44
+ scrollDtvs?: Map<HTMLElement, { left: number; top: number }>
45
+ }>
46
+
47
+ /** 所有缓存数据 */
48
+ export type Caches = Expand<Record<string, Cache>>
49
+
50
+ /** 共享数据 */
51
+ export type ContextProps = Expand<{
52
+ /** 当前正在展示的 所有id */
53
+ currentIds: Set<string>
54
+ /** 需要缓存的组件 id */
55
+ include: Accessor<Set<string>>
56
+ /** 数据 */
57
+ caches: Record<string, Cache>
58
+ /** 加 缓存 */
59
+ setCaches: SetStoreFunction<Caches>
60
+ /** 缓存回调函数 */
61
+ setActive: (id: string, t: Activate, cb: () => void, t1: SetType) => void
62
+ /** 动画类名, 要 css keyframes 动画*/
63
+ aniName: () => string | void
64
+ /** 滚动容器 名称 */
65
+ scrollName: AliveProviderProps["scrollContainerName"]
66
+ /** 指令函数 */
67
+ setDirective: (id: string, dom: HTMLElement, t: MapType) => void
68
+ }>
69
+
70
+ export type Activate = "aSet" | "dSet" | "aOnceSet"
71
+ export type MapType = "set" | "delete"
72
+ export type SetType = "add" | "delete"
73
+
74
+ declare module "solid-js" {
75
+ namespace JSX {
76
+ interface Directives {
77
+ /** 保存当前元素的滚动条数据 */
78
+ aliveSaveScrollDtv?: boolean | ((el: HTMLElement) => boolean | void | any)
79
+ }
80
+ }
47
81
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "solid-alive",
3
- "version": "0.3.3",
3
+ "version": "0.3.51",
4
4
  "author": "1iuxs",
5
5
  "description": "solid-alive",
6
6
  "type": "module",
@@ -30,21 +30,21 @@
30
30
  },
31
31
  "license": "ISC",
32
32
  "dependencies": {
33
- "solid-js": "^1.9.4"
33
+ "solid-js": "^1.9.11"
34
34
  },
35
35
  "devDependencies": {
36
36
  "@rollup/plugin-json": "^6.1.0",
37
37
  "@rollup/plugin-node-resolve": "^15.3.1",
38
38
  "@rollup/plugin-typescript": "^11.1.6",
39
39
  "@types/css-modules": "^1.0.5",
40
- "autoprefixer": "^10.4.20",
41
- "rollup": "^4.30.1",
40
+ "autoprefixer": "^10.4.27",
41
+ "rollup": "^4.59.0",
42
42
  "rollup-plugin-cleanup": "^3.2.1",
43
43
  "rollup-plugin-postcss": "^4.0.2",
44
44
  "rollup-plugin-serve": "^1.1.1",
45
45
  "rollup-plugin-terser": "^7.0.2",
46
46
  "rollup-plugin-typescript2": "^0.36.0",
47
47
  "rollup-preset-solid": "^2.0.1",
48
- "typescript": "^5.7.3"
48
+ "typescript": "^5.9.3"
49
49
  }
50
50
  }
@@ -1,2 +0,0 @@
1
- declare const nextTick: (cb: () => void) => void;
2
- export default nextTick;
package/readme.md DELETED
@@ -1,155 +0,0 @@
1
- ## solid-alive
2
-
3
- ### 安装(install)
4
- - pnpm add solid-alive / npm i solid-alive / yarn add solid-alive
5
- ### 描述(describe)
6
- - 用于 solid 组件缓存,只测试过2级路由缓存
7
- - AliveProvider
8
- - include : 数组, ['/','/about'], 当数据变少时, 会自动去删除少的数据缓存
9
- - 在 useAlive
10
- - onActivated
11
- - onDeactivated
12
-
13
- - 子父 缓存/删除 问题
14
- - 如果某组件下有子组件,在父的 aliveTransfer中,
15
- 第三个参数,为对象 写上子组件的唯一id: {children:['/childrenId','asf',...]}
16
-
17
-
18
-
19
- ### 使用(use)
20
- 1 /index.tsx,AliveProvider将app 包裹
21
- ```jsx
22
- import { render } from 'solid-js/web'
23
- import App from './App'
24
- import { AliveProvider } from 'solid-alive'
25
-
26
- const root = document.getElementById('root')
27
-
28
- render(() =>
29
- <AliveProvider include={[]}>
30
- <App />
31
- </AliveProvider>
32
- , root!)
33
- ```
34
-
35
- 2 /App.tsx ,在 solid-alive 中 有 aliveTransfer, 参数: JSX , id:string, children?:[string..]
36
- ```jsx
37
- import { Route, Router } from '@solidjs/router';
38
- import { aliveTransfer } from 'solid-alive';
39
-
40
- import Home from './views/Home';
41
- import Client from './views/Client';
42
- import About from './views/About';
43
- import Team from './views/Blog/Team';
44
- import Blog from './views/Blog';
45
- import Single from './views/Blog/Single';
46
-
47
-
48
- const HomeTransfer = aliveTransfer(Home, '/'),
49
- AboutTsf = aliveTransfer(About, '/about'),
50
- BlogTsf = aliveTransfer(Blog, '/blog', ['/contact', 'single']),
51
- SingleTsf = aliveTransfer(Single,'single')
52
-
53
- export default function App() {
54
- return (
55
- <Router>
56
- {/* 这个Client 只是用于标签加跳转的,使用时可不用 */}
57
- <Route component={Client}>
58
- <Route component={Home} path={'/'} />
59
- {/* 单个缓存 single */}
60
- <Route component={AboutTsf} path={'/about'} />
61
- {/* 父子 缓存 Parent Child Nesting */}
62
- <Route component={BlogTsf} path={'/blog'}>
63
- <Route component={SingleTsf} path={'single'} />
64
- </Route>
65
- </Route>
66
- </Router>
67
- );
68
- }
69
- ```
70
- 3 父 /views/Blog/index.tsx
71
- ```jsx
72
- export default function Blog(props: any) {
73
- return (
74
- <div>
75
- <h2>Blog</h2>
76
- <div>{props.children}</div>
77
- </div>
78
- );
79
- }
80
- ```
81
-
82
- - 子 /views/Blog/Single/index.tsx 中
83
- ```tsx
84
- import { onActivated,onDeactivated,useAlive, AliveComponent } from "solid-alive"
85
-
86
- export default function Single() {
87
- const { removeAliveElements,aliveFrozen } = useAlive()
88
-
89
-
90
- //todo call 这个会被调用
91
- onActivated(()=>{
92
- console.log('Single-activeated-1')
93
- })
94
-
95
- //todo call 也会被调用
96
- onActivated(()=>{
97
- console.log('Single-activeated-2')
98
- })
99
- // 缓存离开,
100
- onDeactivated(()=>{
101
- console.log('Single-deactivated')
102
- })
103
- return (
104
- <div>
105
- <h2>Single</h2>
106
- <input type="text" style={{ border: '2px solid red' }} />
107
- </div>
108
- )
109
- }
110
- ```
111
-
112
- 3 动态生成 路由
113
- ```tsx
114
- /** App.tsx */
115
- import { createEffect, lazy, type Component } from 'solid-js'
116
- import { Route, Router } from '@solidjs/router'
117
- import { useAlive, aliveTransfer } from "solid-alive"
118
-
119
- const modules = import.meta.glob<{ default: Component<any> }>([
120
- './views/**/**.tsx',
121
- './views/**.tsx'
122
- ])
123
-
124
- const transferRouter = (data: MenuData[]) =>
125
- data.flatMap(item => {
126
- let module = modules[`./views${item.realPath}`]
127
- if (!module) return []
128
- const Transfer = aliveTransfer(
129
- lazy(module),
130
- item.path,
131
- item.children?.map(item => item.path)
132
- )
133
- return (
134
- <Route component={Transfer} path={item.path.split('/').at(-1)}>
135
- {item.children ? transferRouter(item.children) : null}
136
- </Route>
137
- )
138
- })
139
-
140
- const App: Component = () => {
141
- const { aliveFrozen } = useAlive()
142
-
143
- const [data, setData] = createStore<MenuData[]>([])
144
- return (
145
- <Router>
146
- <Route component={Client}>
147
- {/* treeData 将 data变成 树结构数据 */}
148
- {transferRouter(treeData(data))}
149
- </Route>
150
- </Router>
151
- )
152
- }
153
-
154
- export default App
155
- ```