diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml new file mode 100644 index 0000000..f1e265c --- /dev/null +++ b/.github/workflows/release.yaml @@ -0,0 +1,40 @@ +name: Release + +on: + push: + branches: + - master + +jobs: + release: + name: Release + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + node-version: 14 + + - name: Install modules + run: npm i + + - name: Build + run: npm run build + + - name: Build Examples + run: npm run build-examples + + - name: Deploy + uses: peaceiris/actions-gh-pages@v3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./dist-examples + + - name: Release + uses: cycjimmy/semantic-release-action@v3 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.gitignore b/.gitignore index 18b8f7a..9d3dd2d 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ lerna-debug.log* node_modules dist dist-ssr +dist-examples *.local package-lock.json diff --git a/.vscode/extensions.json b/.vscode/extensions.json deleted file mode 100644 index a7cea0b..0000000 --- a/.vscode/extensions.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "recommendations": ["Vue.volar"] -} diff --git a/README.md b/README.md index 599b316..428d0a7 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,29 @@ OR yarn add vue-use-sync-url ``` +## API + +## useSyncUrl + +| 属性 | 描述 | 类型 | +| --------------- | ----------------------------------------------------------------------------------- | ------------------------------- | +| configs | 配置 | [SyncUrlConfig](#SyncUrlConfig) | +| onDecodeSuccess | 页面第一次加载或浏览器前进回退, decode 结束会触发的函数,参数为是否由前进回退触发。 | (isPopstate: boolean) => void | + +返回一个函数,可以传入在配置之外的值。例如 `syncToUrl({a: "1"})` + +### SyncUrlConfig + +| 属性 | 描述 | 类型 | 默认值 | +| --------------- | ------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------- | ------ | +| name | 显示在 url 上的名称 | string | - | +| encode | 将值转换到 url 上的操作,不是 string 类型的会自动转换为 string 类型 | () => string \| number \| boolean \| undefined \| null \| (string \| number \| boolean \| undefined \| null)[] | - | +| decode | 将 url 上的值转换到页面上的操作,第一个参数为对应 name 的值,第二个参数为当前 url 上所有的值,第三个参数表示是否由前进回退触发 | (value: string \| string[], allValues: Record, isPopstate: boolean) => void | - | +| omitEmptyString | encode 时,值为空字符串 `""` 时是否忽略 | boolean | true | +| omitNull | encode 时,值为 null 时是否忽略 | boolean | true | +| omitUndefined | encode 时,值为 undefined 时是否忽略 | boolean | true | +| false | + ## Usage ### url 参数的基础知识 @@ -25,7 +48,7 @@ yarn add vue-use-sync-url 假设 url 上的参数为 `?a=1&a=2&b=true`,来看看获取参数的方法 ```js -const searchParams = new URLSearchParams(window.location.search); +const searchParams = new URL(location.href).searchParams; // ["1", "2"] searchParams.getAll("a"); @@ -49,66 +72,50 @@ searchParams.get(b); ```vue ``` -也可以使用 [encodeURIComponent](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent) 和 [decodeURIComponent](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent) 编码复杂的数据结构 - -```js -const values = reactive({ - obj: { a: { b: { c: 1 } } }, -}); - -const { syncToUrl } = useSyncUrl({ - configs: [ - { - key: "obj", - encode: (value) => encodeURIComponent(JSON.stringify(value)), - decode: (value) => JSON.parse(decodeURIComponent(value)), - }, - ], -}); -``` - -**configs** - -配置需要进行 url 同步的 key 值,key 值与组件 `values` 的 key 值相对应。在你需要进行同步的时候将所有组件值传入 `syncToUrl` 并执行。 - -**key** - -同步到 url 上的 key 值,执行 `syncToUrl` 时必须传入包含此 key 的值。 - -**decode** - -自定义将 url 参数转换成组件值的方法。第一个参数的值为 url 上 key 的值。如果设置了 [decodeKeys](#decodeKeys),则第一个参数为其对象值。 +**encode 例子** -**encode** - -自定义将组件值转成 url 参数的方法。例子中判断 `date` 的值是否为 `null` 来处理结果。如果返回空对象 `{}` 则会被忽略,不会同步到 url。每个选项返回的值最后会被收集到 [onDecode](#onDecode) 中的第一个参数中。 +自定义将组件值转成 url 参数的方法。如果返回空对象 `{}` 则会被忽略,不会同步到 url。 ```js -// 转换成 test=1 +// 转换成 name=1 { - key: "test", + name: "name", encode: () => { return "1" } } +// 转换成 name=undefined +{ + name: "name", + omiUndefined: false, + encode: () => { + return undefined + } +} + // 转换成 a=1&b=2 { - key: "test", + name: "name", encode: () => { return { a: "1", @@ -182,7 +167,7 @@ const { syncToUrl } = useSyncUrl({ // 转换成 a=1&b=2&b=3 { - key: "test", + name: "name", encode: () => { return { a: "1", @@ -193,80 +178,32 @@ const { syncToUrl } = useSyncUrl({ // 忽略 { - key: "test", + name: "name", encode: () => { return {} } } -``` - -**decodeKeys** - -若 `encode` 返回的是对象,需要设置 `decodeKeys` 为返回对象的 key 值数组。这样 `decode` 的第一个参数才会解析成返回对象,否为会返回设置的 key 的值。 -```js +// 转换成 a=1 { - key: "test", - decodeKeys: ["a", "b"], - encode: (value: string[]) => ({ - a: value[0], - b: value[1], - }), - decode: (value) => { - // value 为 url 参数中 decodeKeys 的对象值 { a: "1", b: "2" },如果 url 参数中 没有则为空对象 {} - ... + name: "name", + encode: () => { + return { + a: "1", + b: undefined, + } } } -``` - -**omitEmptyString** - -执行 `syncToUrl` 时,值为空字符串 `""` 时是否忽略,如果设置了 `encode` 则无效,`encode` 优先级高。默认为 `true`。 - -**omitUndefined** - -执行 `syncToUrl` 时,值为 `null` 时是否忽略,如果设置了 `encode` 则无效,`encode` 优先级高。默认为 `true`。 - -**omitNull** - -执行 `syncToUrl` 时,值为 `null` 时是否忽略,如果设置了 `encode` 则无效,`encode` 优先级高。默认为 `true`。 - -**onDecode** (params: Record, isPopState: boolean) => void - -页面第一次加载或浏览器前进回退时会触发的函数,`params` 为各个配置项 decode 返回的值的集合,`isPopState` 判断是否由浏览器前进回退触发,为 `false` 则为页面第一次加载触发,加载触发时在 `onMounted` 之前执行。 - -## - -## Type Declarations - -```ts -type EncodeResult = string | number | boolean | (string | number | boolean)[]; - -interface useSyncUrlConfig { - key: string; - decodeKeys?: string[]; - /** - * @default true - */ - omitEmptyString?: boolean; - /** - * @default true - */ - omitUndefined?: boolean; - /** - * @default true - */ - omitNull?: boolean; - decode?: (value: any) => any; - encode?: (value: any) => EncodeResult | Record; -} -interface useSyncUrlOptions { - /** - * @default "history" - */ - mode?: "history" | "hash"; - configs: useSyncUrlConfig[]; - onDecode: (params: Record, isPopState: boolean) => void; +// 转换成 a=1&b=undefined +{ + name: "name", + omitUndefined: false, + encode: () => { + return { + a: "1", + b: undefined, + } + } } ``` diff --git a/examples/App.vue b/examples/App.vue index 7c28e25..6890df1 100644 --- a/examples/App.vue +++ b/examples/App.vue @@ -1,20 +1,22 @@