From cda4b18518bd34af634bb838d76082a94932c5ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=83=A1=E9=95=87?= Date: Tue, 21 Nov 2023 15:22:31 +0800 Subject: [PATCH] docs: update docs of vue-options and development --- docs/contributing/03-developing-guidelines.md | 2 +- docs/tutorial/10-framework/01-vue-options.md | 170 ++++++++++++++++-- .../contributing/03-developing-guidelines.md | 2 +- .../tutorial/10-framework/01-vue-options.md | 150 +++++++++++++++- 4 files changed, 305 insertions(+), 19 deletions(-) diff --git a/docs/contributing/03-developing-guidelines.md b/docs/contributing/03-developing-guidelines.md index 27b1887519..3576692689 100644 --- a/docs/contributing/03-developing-guidelines.md +++ b/docs/contributing/03-developing-guidelines.md @@ -19,7 +19,7 @@ Use the `git clone` command line, or the `Github Desktop` application to clone f ## 3. New pull request -You can first modify something and commit it, then create a new pull request and use `close #xxx` to associate with the issue you are solving, which will indicate that you have owned the issue, [How to create pull request through a forked repo](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request-from-a-fork)it's here. +You can [create pull request through a forked repo](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request-from-a-fork) after writing code. You can also commit code in arbitrary batches, without commiting a complete code. ## 4. Code something in your computer diff --git a/docs/tutorial/10-framework/01-vue-options.md b/docs/tutorial/10-framework/01-vue-options.md index a024795513..cf77deccff 100644 --- a/docs/tutorial/10-framework/01-vue-options.md +++ b/docs/tutorial/10-framework/01-vue-options.md @@ -6,7 +6,7 @@ sidebar_position: 10 import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; -Usually, use hook can only be used in vue's setup, but through the auxiliary function provided by `@alova/vue-options`, you can also use alova's use hook in vue options style, which is perfectly compatible with almost all functions of alova. +Usually, use hook can only be used in vue's setup, but through the helper function provided by `@alova/vue-options`, you can also use alova's use hook in vue's options, which is perfectly compatible with almost all functions of alova. > Available in both vue2 and vue3. @@ -35,14 +35,16 @@ yarn add alova @alova/vue-options -:::info alova version requirements +:::info alova requirements -alova version >= 2.13.1 +alova version >= 2.13.2 ::: ## Usage +### Map hook status and functions to vue instances + First use `vueOptionHook` to create an alova instance. ```javascript @@ -65,7 +67,7 @@ export const getData = () => alovaInst.Get('/todolist'); Then use `mapAlovaHook` to map the return value set of use hook to the component instance. The following is how to access the reactive state and operation functions: 1. You can access responsive status such as `loading/data/error` through the key of the collection, such as `this.key.loading`, `this.key.data`. -2. You can access the operation function by adding the key of the collection and the function name, and use `$` to splice it, such as `this.key$send`, `this.key$onSuccess`. +2. You can access the operation function through the key of the collection plus the function name, and use `$` to splice it, such as `this.key$send`, `this.key$onSuccess`. Below is a complete example. @@ -121,7 +123,110 @@ Below is a complete example. ``` -## mapAlovaHook function description +### Computed properties + +If you need to define a computed property that depends on hook-related request status, just write it as usual. + +```javascript +export default { + computed: { + todoRequestLoading() { + return this.todoRequest.loading; + }, + todoRequestData() { + return this.todoRequest.data; + } + } +}; +``` + +### Watch hook status changes + +Due to the limitations of vue2, all hook states are mounted on an object named `alovaHook$`, so you need to add the `alovaHook$` prefix when listening. + +```javascript +export default { + watch: { + // ❌Unable to watch + 'todoRequest.loading'(newVal, oldVal) { + // ... + }, + // ✅watching is work + 'alovaHook$.todoRequest.loading'(newVal, oldVal) { + // ... + } + } +}; +``` + +But this is a bit troublesome, so a `mapWatcher` helper function is provided, which can not only automatically add prefixes, nested watching, but also batch watching. + +#### Define single watch handler + +```javascript +export default { + watch: mapWatcher({ + // Usage 1 + 'todoRequest.loading'(newVal, oldVal) {}, + + // Usage 2 + todoRequest: { + loading(newVal, oldVal) {}, + data(newVal, oldVal) {} + } + }) +}; +``` + +Watching object is also supported. + +```javascript +export default { + watch: mapWatcher({ + todoRequest: { + data: { + handler(newVal, oldVal) {}, + deep: true + } + } + }) +}; +``` + +#### Batch define watch handlers + +Multiple watching keys are separated by `,`. + +```javascript +export default { + watch: mapWatcher({ + // Usage 1 + 'todoRequest1.data, todoRequest2.data'(newVal, oldVal) {}, + + // Usage 2 + 'todoRequest1, todoRequest2': { + loading(newVal, oldVal) {}, + data(newVal, oldVal) {} + }, + + // Usage 3 + todoRequest1: { + 'loading, data'(newVal, oldVal) {} + }, + + // Usage 4 + 'todoRequest1, todoRequest2': { + 'loading, data'(newVal, oldVal) {} + } + }) +}; +``` + +> Batch watching also supports watching object. + +## Function description + +### mapAlovaHook `mapAlovaHook` is used to map the state and function collection returned by alova's use hook to the vue component instance through mixins. It receives a callback function and returns the return value collection of use hook. @@ -146,6 +251,46 @@ mapAlovaHook(vm => { }); ``` +### mapWatcher + +`mapWatcher` is an helper function used to quickly define the watching handlers of hook states. It receives an object whose key is the key of the hook state or a string representation of the nested value, and whose value is the watching handler or watching object. + +```javascript +mapWatcher({ + 'todoRequest.loading'(newVal, oldVal) { + //... + }, + todoRequest: { + data(newVal, oldVal) { + //... + } + }, + todoRequest: { + 'loading, data'(newVal, oldVal) { + //... + } + } +} +``` + +In addition to supporting watching assistance for alova useHook, `mapWatcher` can also be used to batch set watching handlers of custom states. + +```javascript +export default { + data() { + state1: '', + state2: 0 + }, + + // pass false at the second parameter to watch the custom states + watch: mapWatcher({ + 'state1, state2'(newVal, oldVal) { + //... + } + }, false) +} +``` + ## Type support ### Automatic inference @@ -167,8 +312,7 @@ this.todoRequest$onComplete; // (handler: CompleteHandler) => void Except for `this.todoRequest.data`, all other values have the correct type, so how to set the type for `data` too? In fact, it is the same as alova used in other environments. - - +**javascript** In javascript, you can use type annotations to add types. The first two generic parameters of Method are `unknown`, and the third generic parameter is the type of response data. @@ -179,15 +323,11 @@ import { Method } from 'alova'; export const getData = () => alovaInst.Get('/todolist'); ``` - - - -To add response data type in typescript, please read [alova documentation typescript](/tutorial/advanced/typescript/#the-type-of-response-data) +**typescript** - - +To add response data type in typescript, please read [alova documentation typescript chapter](/tutorial/advanced/typescript/#the-type-of-response-data) -## Limitation +## limit 1. [Manage extra states](/tutorial/next-step/manage-extra-states) is not supported yet. -2. Currently, only alova’s 3 core useHooks of `useRequest/useWatcher/useFetcher` are supported, as well as the wrapped useHook based on the core useHook in your own project. The extended useHook in [@alova/scene](https://github.com/alova/scene) is not supported yet. +2. Currently, only alova’s three core useHooks of `useRequest/useWatcher/useFetcher` are supported, as well as the encapsulation based on the core useHook in your own project. [@alova/scene](https://github.com/alovajs/scene) is not supported yet. extension useHook. diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/contributing/03-developing-guidelines.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/contributing/03-developing-guidelines.md index b3588e1b94..c3177a591c 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/contributing/03-developing-guidelines.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/contributing/03-developing-guidelines.md @@ -19,7 +19,7 @@ Node.js 16+, npm 8+ ## 3. 新建 pull request -你可以先随便修改一些什么并提交,然后新建 pull request 并使用`close #xxx`来关联正在解决的 issue,这将表示你已占有该 issue,[如何通过 fork 仓库创建 pull request](https://docs.github.com/zh/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request-from-a-fork)在这里。 +你可以在编写完代码后[通过 fork 仓库创建 pull request](https://docs.github.com/zh/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request-from-a-fork),也可以分为任意多次提交代码,而无需一次提交完整代码。 ## 4. 在本地编码 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/tutorial/10-framework/01-vue-options.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/tutorial/10-framework/01-vue-options.md index f3ab4f74ea..92b2f481a6 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/tutorial/10-framework/01-vue-options.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/tutorial/10-framework/01-vue-options.md @@ -37,12 +37,14 @@ yarn add alova @alova/vue-options :::info alova 版本要求 -alova 版本 >= 2.13.1 +alova 版本 >= 2.13.2 ::: ## 用法 +### 映射 hook 状态和函数到 vue 实例上 + 先使用`vueOptionHook`创建 alova 实例。 ```javascript @@ -121,7 +123,110 @@ export const getData = () => alovaInst.Get('/todolist'); ``` -## mapAlovaHook 函数说明 +### 计算属性 + +如果你需要定义依赖 hook 相关的请求状态的计算属性,只需要和平时一样编写即可。 + +```javascript +export default { + computed: { + todoRequestLoading() { + return this.todoRequest.loading; + }, + todoRequestData() { + return this.todoRequest.data; + } + } +}; +``` + +### 监听 hook 状态变化 + +由于 vue2 的限制,所有 hook 状态都是挂载在一个名叫`alovaHook$`的对象上,因此在监听时需要添加`alovaHook$`前缀。 + +```javascript +export default { + watch: { + // ❌无法监听 + 'todoRequest.loading'(newVal, oldVal) { + // ... + }, + // ✅监听正常 + 'alovaHook$.todoRequest.loading'(newVal, oldVal) { + // ... + } + } +}; +``` + +但这样稍显麻烦,因此提供了一个`mapWatcher`辅助函数,不仅可以自动添加前缀、嵌套监听,还可以批量监听。 + +#### 设置单个监听函数 + +```javascript +export default { + watch: mapWatcher({ + // 用法1 + 'todoRequest.loading'(newVal, oldVal) {}, + + // 用法2 + todoRequest: { + loading(newVal, oldVal) {}, + data(newVal, oldVal) {} + } + }) +}; +``` + +同时也支持监听器对象。 + +```javascript +export default { + watch: mapWatcher({ + todoRequest: { + data: { + handler(newVal, oldVal) {}, + deep: true + } + } + }) +}; +``` + +#### 批量设置监听函数 + +多个监听 key 使用`,`分隔。 + +```javascript +export default { + watch: mapWatcher({ + // 用法1 + 'todoRequest1.data, todoRequest2.data'(newVal, oldVal) {}, + + // 用法2 + 'todoRequest1, todoRequest2': { + loading(newVal, oldVal) {}, + data(newVal, oldVal) {} + }, + + // 用法3 + todoRequest1: { + 'loading, data'(newVal, oldVal) {} + }, + + // 用法4 + 'todoRequest1, todoRequest2': { + 'loading, data'(newVal, oldVal) {} + } + }) +}; +``` + +> 批量监听也同样支持监听器对象 + +## 函数说明 + +### mapAlovaHook `mapAlovaHook`是用于将 alova 的 use hook 返回的状态和函数集合,通过 mixins 映射到 vue 组件实例上。它接收一个回调函数并返回 use hook 的返回值集合。 @@ -146,6 +251,47 @@ mapAlovaHook(vm => { }); ``` +### mapWatcher + +`mapWatcher`是用于快速定义 hook 状态变化的辅助函数,它接收一个对象,键为 hook 状态的 key 或嵌套值的字符串表示,值为监听函数或监听器对象。 + +```javascript +// 1. 监听单个状态 +mapWatcher({ + 'todoRequest.loading'(newVal, oldVal) { + //... + }, + todoRequest: { + data(newVal, oldVal) { + //... + } + }, + todoRequest: { + 'loading, data'(newVal, oldVal) { + //... + } + } +} +``` + +`mapWatcher`除了支持对 alova useHook 的监听辅助外,你还可以使用它批量设置普通状态值的监听。 + +```javascript +export default { + data() { + state1: '', + state2: 0 + }, + + // 第二个参数传入false即可监听普通状态 + watch: mapWatcher({ + 'state1, state2'(newVal, oldVal) { + //... + } + }, false) +} +``` + ## 类型支持 ### 自动推断