diff --git a/docs/vue-vuex.md b/docs/vue-vuex.md
index 37e3a4ac4fdbd2b4e6836e64dfd3bc2dcece8e5f..cf383b1b1241dc1c7c08ea11614033a0cd46385c 100644
--- a/docs/vue-vuex.md
+++ b/docs/vue-vuex.md
@@ -181,28 +181,6 @@ app.$mount()
-```html
-
-
-
- 用户名:{{username}}
- 年龄:{{age}}
-
-
-
-```
@@ -218,37 +196,6 @@ app.$mount()
在 `uni-app` 项目根目录下,`store` 目录 `index.js` 文件下:
-```js
-
-import Vue from 'vue'
-import Vuex from 'vuex'
-
-Vue.use(Vuex);
-
-const store = new Vuex.Store({
- state: {
- todos: [{
- id: 1,
- text: '我是内容一',
- done: true
- },
- {
- id: 2,
- text: '我是内容二',
- done: false
- }
- ]
- },
- getters: {
- doneTodos: state => {
- return state.todos.filter(todo => todo.done)
- }
- }
-})
-
-export default store
-
-```
@@ -335,51 +282,6 @@ export default store
- 在 `mutation` 传参(载荷)可以传递一个参数。
-```js
-
-import Vue from 'vue'
-import Vuex from 'vuex'
-
-Vue.use(Vuex);
-
-const store = new Vuex.Store({
- state: {
- count: 1
- },
- mutations: {
- add(state, n) {
- state.count += n
- }
- }
-})
-export default store
-```
-
-
-```html
-
-
-
- 数量:{{count }}
-
-
-
-
-```
- 在 `mutation` 传参(载荷)可以也可以传递一个对象。让我们修改上面累加器的例子:
@@ -476,43 +378,12 @@ export default store
```
-```js
-
-import Vue from 'vue'
-import Vuex from 'vuex'
-
-Vue.use(Vuex);
-
-const store = new Vuex.Store({
- state: {
- count: 1
- },
- mutations: {
- add(state) {
- // 变更状态
- state.count += 2
- }
- }
-})
-export default store
-```
-
-
我们要通过提交 `mutation` 的方式来改变状态数据,是因为我们想要更明确地追踪到状态的变化。如果是类似下面这样异步的话:
-```js
- mutations: {
- someMutation (state) {
- api.callAsyncMethod(() => {
- state.count++
- })
- }
- }
-```
我们就不知道什么时候状态会发生改变,所以也就无法追踪了,这与 `mutation` 的设计初心相悖,所以强制规定它必须是同步函数。
@@ -570,26 +441,9 @@ export default store
- `mapActions` 也支持传入参数(载荷):
-```js
- methods: {
- ...mapActions([
- 'addCountAction'
- // 将 `this.addCountAction(amount)` 映射为
- //`this.$store.dispatch('addCountAction', amount)`
- ]),
- }
-```
- `mapActions` 也支持传递一个对象:
-```js
- methods: {
- ...mapActions({
- addCount: 'addCountAction',
- // 将 `this.addCount()` 映射为 `this.$store.dispatch('addCountAction')`
- })
- }
-```
diff --git a/docs/vue3-api.md b/docs/vue3-api.md
index 27d29327b686521c280de67420aec0ba134f40b3..731abc465dd8f066ef4255456b5e14243e3031f2 100644
--- a/docs/vue3-api.md
+++ b/docs/vue3-api.md
@@ -1,288 +1,28 @@
-## 应用配置
-`config` 是一个包含了 `Vue` 应用全局配置的对象。你可以在应用挂载前修改其以下 `property`:
-```js
-const app = Vue.createApp({})
-app.config = {...}
-```
-|应用配置|描述 |H5 |App端|说明 |
-|-- |-- |-- |-- |-- |
-|errorHandler |指定一个处理函数,来处理组件渲染方法执行期间以及侦听器抛出的未捕获错误。[详情](https://vue3js.cn/docs/zh/api/application-config.html#errorhandler) |√ |√ ||
-|warnHandler |为 `Vue` 的运行时警告指定一个自定义处理函数。[详情](https://vue3js.cn/docs/zh/api/application-config.html#warnhandler) |√ |√ ||
-|globalProperties |添加可以在应用程序内的任何组件实例中访问的全局 `property`。[详情](https://vue3js.cn/docs/zh/api/application-config.html#globalproperties) |√ |√ ||
-|isCustomElement |指定一个方法,用来识别在 `Vue` 之外定义的自定义元素。[详情](https://vue3js.cn/docs/zh/api/application-config.html#iscustomelement) |√ |√ ||
-|optionMergeStrategies |为自定义选项定义合并策略。[详情](https://vue3js.cn/docs/zh/api/application-config.html#optionmergestrategies) |√ |√ ||
-|performance|设置为 `true` 以在浏览器开发工具的 `performance/timeline` 面板中启用对组件初始化、编译、渲染和更新的性能追踪。[详情](https://vue3js.cn/docs/zh/api/application-config.html#performance) |√ |x |只在Web环境下支持|
-## 应用 API
-在 Vue 3 中,改变全局 `Vue` 行为的 `API` 现在被移动到了由新的 `createApp` 方法所创建的应用实例上。此外,现在它们的影响仅限于该特定应用实例:
-
-```js
-import { createApp } from 'vue'
-
-const app = createApp({})
-```
-
-
-调用 `createApp` 返回一个应用实例。该实例提供了一个应用上下文。应用实例挂载的整个组件树共享相同的上下文,该上下文提供了之前在 `Vue 2.x` 中“全局”的配置。
-
-另外,由于 `createApp` 方法返回应用实例本身,因此可以在其后链式调用其它方法,这些方法可以在以下部分中找到。
-
-
-|应用 API|描述 |H5 |App端|
-|-- |-- |-- |-- |
-|component |注册或检索全局组件。[详情](https://vue3js.cn/docs/zh/api/application-api.html#component) |√ |√ |
-|config |包含应用配置的对象。[详情](https://vue3js.cn/docs/zh/api/application-api.html#config) |√ |√ |
-|directive |注册或检索全局指令。[详情](https://vue3js.cn/docs/zh/api/application-api.html#directive) |√ |√ |
-|mixin |在整个应用范围内应用混入。[详情](https://vue3js.cn/docs/zh/api/application-api.html#mixin) |√ |√ |
-|provide|设置一个可以被注入到应用范围内所有组件中的值。[详情](https://vue3js.cn/docs/zh/api/application-api.html#provide) |√ |√ |
-|use|安装 `Vue.js` 插件。[详情](https://vue3js.cn/docs/zh/api/application-api.html#use) |√ |√ |
-
-
-
-## 全局 API
-
-|全局 API|描述 |H5 |App端|
-|-- |-- |-- |-- |
-|createApp |返回一个提供应用上下文的应用实例。应用实例挂载的整个组件树共享同一个上下文。[详情](https://vue3js.cn/docs/zh/api/global-api.html#createapp) |√ |√ |
-|h |返回一个”虚拟节点“,通常缩写为 `VNode`:一个普通对象,其中包含向 `Vue` 描述它应在页面上渲染哪种节点的信息,包括所有子节点的描述。[详情](https://vue3js.cn/docs/zh/api/global-api.html#h) |√ |x |
-|defineComponent |从实现上看,`defineComponent` 只返回传递给它的对象。但是,就类型而言,返回的值有一个合成类型的构造函数,用于手动渲染函数、`TSX` 和 `IDE` 工具支持。[详情](https://vue3js.cn/docs/zh/api/global-api.html#definecomponent) |√ |x |
-|defineAsyncComponent |创建一个只有在需要时才会加载的异步组件。[详情](https://vue3js.cn/docs/zh/api/global-api.html#defineasynccomponent) |√ |x |
-|resolveComponent |如果在当前应用实例中可用,则允许按名称解析 `component`。返回一个 `Component`。[详情](https://vue3js.cn/docs/zh/api/global-api.html#resolvecomponent) |√ |x |
-|resolveDynamicComponent|允许使用与 `component :is=""` 相同的机制来解析一个 `component`。[详情](https://vue3js.cn/docs/zh/api/global-api.html#resolvedynamiccomponent) |√ |x |
-|resolveDirective|如果在当前应用实例中可用,则允许通过其名称解析一个 `directive`。返回一个 `Directive`。[详情](https://vue3js.cn/docs/zh/api/global-api.html#resolvedirective) |√ |x |
-|withDirectives|允许将指令应用于 `VNode`。返回一个包含应用指令的 `VNode`。[详情](https://vue3js.cn/docs/zh/api/global-api.html#withdirectives) |√ |x |
-|createRenderer|createRenderer 函数接受两个泛型参数: `HostNode` 和 `HostElement`,对应于宿主环境中的 `Node` 和 `Element` 类型。[详情](https://vue3js.cn/docs/zh/api/global-api.html#createrenderer) |√ |x|
-|nextTick|将回调推迟到下一个 `DOM` 更新周期之后执行。在更改了一些数据以等待 `DOM` 更新后立即使用它。[详情](https://vue3js.cn/docs/zh/api/global-api.html#nexttick) |√ | x |
-
-
-
-
-## 选项/Data
-
-
-|Data|描述 |H5 |App端|
-|-- |-- |-- |-- |
-|data |返回组件实例的 `data` 对象的函数。[详情](https://vue3js.cn/docs/zh/api/options-data.html) |√ |√ |
-|props |`props` 可以是数组或对象,用于接收来自父组件的数据。[详情](https://vue3js.cn/docs/zh/api/options-data.html#props) |√ |√ |
-|computed |计算属性将被混入到组件实例中。所有 `getter` 和 `setter` 的 `this` 上下文自动地绑定为组件实例。[详情](https://vue3js.cn/docs/zh/api/options-data.html#computed) |√ |√ |
-|methods |methods 将被混入到组件实例中。可以直接通过 `VM` 实例访问这些方法,或者在指令表达式中使用。方法中的 `this` 自动绑定为组件实例。[详情](https://vue3js.cn/docs/zh/api/options-data.html#methods) |√ |√ |
-|watch |一个对象,键是需要观察的表达式,值是对应回调函数。值也可以是方法名,或者包含选项的对象。[详情](https://vue3js.cn/docs/zh/api/options-data.html#watch) |√ |√ |
-|emits|emits 可以是数组或对象,从组件触发自定义事件,`emits` 可以是简单的数组,或者对象作为替代,允许配置和事件验证。[详情](https://vue3js.cn/docs/zh/api/options-data.html#emits) |√ |√ |
-
-
-## 选项/DOM
-
-
-|DOM|描述 |H5 |App端|说明 |
-|-- |-- |-- |-- |-- |
-|template |一个字符串模板作为 `component` 实例的标识使用。[详情](https://vue3js.cn/docs/zh/api/options-dom.html#template) |√ |x | uni-app使用的vue是只包含运行时的版本 |
-|render |字符串模板的另一种选择,允许你充分利用 `JavaScript` 的编程功能。[详情](https://vue3js.cn/docs/zh/api/options-dom.html#render) |√ | x | - |
-
-
-
-## 选项/生命周期钩子
-
-
-|生命周期钩子|描述 |H5 |App端|
-|-- |-- |-- |-- |
-|beforeCreate |在实例初始化之后,数据观测` (data observer) `和 `event/watcher` 事件配置之前被调用。[详情](https://vue3js.cn/docs/zh/api/options-lifecycle-hooks.html#beforecreate) |√ |√ |
-|created |在实例创建完成后被立即调用。[详情](https://vue3js.cn/docs/zh/api/options-lifecycle-hooks.html#created) |√ |√ |
-|beforeMount |在挂载开始之前被调用:相关的 `render` 函数首次被调用。[详情](https://vue3js.cn/docs/zh/api/options-lifecycle-hooks.html#beforemount) |√ |√ |
-|mounted |实例被挂载后调用,这时 `Vue.createApp({}).mount()` 被新创建的 `vm.$el` 替换了。[详情](https://vue3js.cn/docs/zh/api/options-lifecycle-hooks.html#mounted) |√ |√ |
-|beforeUpdate |数据更新时调用,发生在虚拟 `DOM` 打补丁之前。[详情](https://vue3js.cn/docs/zh/api/options-lifecycle-hooks.html#beforeupdate) |√ |√ |
-|updated|由于数据更改导致的虚拟 `DOM` 重新渲染和打补丁,在这之后会调用该钩子。[详情](https://vue3js.cn/docs/zh/api/options-lifecycle-hooks.html#updated) |√ |√ |
-|activated|被 `keep-alive` 缓存的组件激活时调用。[详情](https://vue3js.cn/docs/zh/api/options-lifecycle-hooks.html#activated) |√ |√ |
-|deactivated|被 `keep-alive` 缓存的组件停用时调用。[详情](https://vue3js.cn/docs/zh/api/options-lifecycle-hooks.html#deactivated) |√ |√ |
-|beforeUnmount|在卸载组件实例之前调用。在这个阶段,实例仍然是完全正常的。[详情](https://vue3js.cn/docs/zh/api/options-lifecycle-hooks.html#beforeunmount) |√ |√ |
-|unmounted|卸载组件实例后调用。调用此钩子时,组件实例的所有指令都被解除绑定,所有事件侦听器都被移除,所有子组件实例被卸载。[详情](https://vue3js.cn/docs/zh/api/options-lifecycle-hooks.html#unmounted) |√ |√ |
-|errorCaptured |当捕获一个来自子孙组件的错误时被调用。此钩子会收到三个参数:错误对象、发生错误的组件实例以及一个包含错误来源信息的字符串。[详情](https://vue3js.cn/docs/zh/api/options-lifecycle-hooks.html#errorcaptured) |√ |√ |
-|renderTracked |跟踪虚拟 `DOM` 重新渲染时调用。钩子接收 `debugger event` 作为参数。此事件告诉你哪个操作跟踪了组件以及该操作的目标对象和键。[详情](https://vue3js.cn/docs/zh/api/options-lifecycle-hooks.html#rendertracked) |√ |√ |
-|renderTriggered |当虚拟 `DOM` 重新渲染为 `triggered.Similarly` 为`renderTracked`,接收 `debugger event` 作为参数。此事件告诉你是什么操作触发了重新渲染,以及该操作的目标对象和键。[详情](https://vue3js.cn/docs/zh/api/options-lifecycle-hooks.html#rendertriggered) |√ |√ |
-
-
-## 选项/资源
-
-
-|资源|描述 |H5 |App端|
-|-- |-- |-- |-- |
-|directives |包含组件实例可用指令的哈希表。[详情](https://vue3js.cn/docs/zh/api/options-assets.html#directives) |√ |√ |
-|components |包含组件实例可用组件的哈希表。[详情](https://vue3js.cn/docs/zh/api/options-assets.html#components) |√ |√ |
-
-
-## 选项/组合
-
-
-|组合|描述 |H5 |App端|
-|-- |-- |-- |-- |
-|mixins |接收一个混入对象的数组。这些混入对象可以像正常的实例对象一样包含实例选项,这些选项将会被合并到最终的选项中,使用特定的选项合并逻辑。[详情](https://vue3js.cn/docs/zh/api/options-composition.html#mixins) |√ |√ |
-|extends |允许声明扩展另一个组件 (可以是一个简单的选项对象或构造函数)。这主要是为了便于扩展单文件组件。[详情](https://vue3js.cn/docs/zh/api/options-composition.html#extends) |√ |√ |
-|provide / inject |这对选项需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在起上下游关系成立的时间里始终生效。[详情](https://vue3js.cn/docs/zh/api/options-composition.html#provide-inject) |√ |√ |
-|setup |`setup` 函数是一个新的组件选项。它作为在组件内部使用组合式 `API` 的入口点。[详情](https://vue3js.cn/docs/zh/api/options-composition.html#setup) |√ |√ |
-
-
-
-## 选项/杂项
-
-
-|杂项|描述 |H5 |App端|
-|-- |-- |-- |-- |
-|name |允许组件模板递归地调用自身。注意,组件在全局用 `Vue.createApp({}).component({})` 注册时,全局 `ID` 自动作为组件的 `name`。[详情](https://vue3js.cn/docs/zh/api/options-misc.html#name) |√ |√ |
-|delimiters |设置用于模板内文本插入的分隔符。[详情](https://vue3js.cn/docs/zh/api/options-misc.html#delimiters) |√ |x |
-|inheritAttrs |默认情况下父作用域的不被认作 `props` 的 `attribute` 绑定 (`attribute bindings`) 将会“回退”且作为普通的 `HTML attribute` 应用在子组件的根元素上。当撰写包裹一个目标元素或另一个组件的组件时,通过设置 `inheritAttrs` 到 `false`,这些默认行为将会被去掉。[详情](https://vue3js.cn/docs/zh/api/options-misc.html#inheritattrs) |√ |√ |
-
-
-
-## 实例 property
-
-
-|实例 property|描述 |H5 |App端|说明 |
-|-- |-- |-- |-- |-- |
-|$data |组件实例观察的数据对象。组件实例代理了对其 `data` 对象 `property` 的访问。[详情](https://vue3js.cn/docs/zh/api/instance-properties.html#data) |√ |√ ||
-|$props |当前组件接收到的 `props` 对象。组件实例代理了对其 `props` 对象 `property` 的访问。[详情](https://vue3js.cn/docs/zh/api/instance-properties.html#props) |√ |√ ||
-|$el |组件实例使用的根 `DOM` 元素。[详情](https://vue3js.cn/docs/zh/api/instance-properties.html#el) |√ | x||
-|$options |用于当前组件实例的初始化选项。需要在选项中包含自定义 `property` 时会有用处。[详情](https://vue3js.cn/docs/zh/api/instance-properties.html#options) |√ |√ ||
-|$parent |父实例,如果当前实例有的话。[详情](https://vue3js.cn/docs/zh/api/instance-properties.html#parent) |√ |√ | H5端 `view`、`text` 等内置标签是以 `Vue` 组件方式实现,`$parent` 会获取这些到内置组件,导致的问题是 `this.$parent` 与其他平台不一致,解决方式是使用 `this.$parent.$parent` 获取或自定义组件根节点由 `view` 改为 `div`|
-|$root |当前组件树的根组件实例。如果当前实例没有父实例,此实例将会是其自己。[详情](https://vue3js.cn/docs/zh/api/instance-properties.html#root) |√ |√ ||
-|$slots |用来访问被插槽分发的内容。每个具名插槽有其相应的 `property` (例如:`v-slot:foo` 中的内容将会在 `this.$slots.foo` 中被找到)。[详情](https://vue3js.cn/docs/zh/api/instance-properties.html#slots) |√ |x ||
-|$refs |一个对象,持有注册过 `ref attribute` 的所有 `DOM` 元素和组件实例。[详情](https://vue3js.cn/docs/zh/api/instance-properties.html#refs) |√ |√ | 非H5端只能用于获取自定义组件,不能用于获取内置组件实例(如:`view`、`text`)|
-|$attrs |包含了父作用域中不作为组件 `props` 或自定义事件。[详情](https://vue3js.cn/docs/zh/api/instance-properties.html#attrs) |√ |√ |-|
-
-
-## 实例方法
-
-|实例方法|描述 |H5 |App端|
-|-- |-- |-- |-- |
-|$watch |侦听组件实例上的响应式 `property` 或函数计算结果的变化。[详情](https://vue3js.cn/docs/zh/api/instance-methods.html#watch) |√ |√ |
-|$emit |触发当前实例上的事件。附加参数都会传给监听器回调。[详情](https://vue3js.cn/docs/zh/api/instance-methods.html#emit) |√ |√ |
-|$forceUpdate |迫使组件实例重新渲染。注意它仅仅影响实例本身和插入插槽内容的子组件,而不是所有子组件。[详情](https://vue3js.cn/docs/zh/api/instance-methods.html#forceupdate) |√ |√ |
-|$nextTick |将回调延迟到下次 `DOM` 更新循环之后执行。在修改数据之后立即使用它,然后等待 `DOM` 更新。[详情](https://vue3js.cn/docs/zh/api/instance-methods.html#nexttick) |√ |√ |
-
-
-
-
-## 指令
-
-|Vue 指令 |描述 |H5 |App端|说明 |
-| -- | -- | -- |-- | -- |
-|v-text | 更新元素的 `textContent`。 [详情](https://vue3js.cn/docs/zh/api/directives.html#v-text) |√ |√ | |
-|v-html | 更新元素的 `innerHTML`。 [详情](https://vue3js.cn/docs/zh/api/directives.html#v-html) |√ | √ | x | |
-|v-show | 根据表达式的真假值,切换元素的 `display CSS property`。 [详情](https://vue3js.cn/docs/zh/api/directives.html#v-show) |√ | √ | |
-|v-if | 根据表达式的真假值来有条件地渲染元素。 [详情](https://vue3js.cn/docs/zh/api/directives.html#v-if) |√ | √ | |
-|v-else | 为 `v-if` 或者 `v-else-if` 添加`“else 块”`。[详情](https://vue3js.cn/docs/zh/api/directives.html#v-else) |√ | √ | |
-|v-else-if| 表示 `v-if` 的`“else if 块”`。可以链式调用。 [详情](https://vue3js.cn/docs/zh/api/directives.html#v-else-if) |√ | √ | |
-|v-for | 基于源数据多次渲染元素或模板块。 [详情](https://vue3js.cn/docs/zh/api/directives.html#v-for) |√ | √ | |
-|v-on | 绑定事件监听器。 [详情](https://vue3js.cn/docs/zh/api/directives.html#v-on) |√ | √ | |
-|v-bind | 动态地绑定一个或多个 `attribute`,或一个组件 `prop` 到表达式。 [详情](https://vue3js.cn/docs/zh/api/directives.html#v-bind) |√ | √ ||
-|v-model| 在表单控件或者组件上创建双向绑定。 [详情](https://vue3js.cn/docs/zh/api/directives.html#v-model) |√ | √ | |
-|v-slot | 提供具名插槽或需要接收 `prop` 的插槽。 [详情](https://vue3js.cn/docs/zh/api/directives.html#v-slot) |√ | √ | |
-|v-pre | 跳过这个元素和它的子元素的编译过程。 [详情](https://vue3js.cn/docs/zh/api/directives.html#v-pre) |√ | √ | |
-|v-cloak| 这个指令保持在元素上直到关联组件实例结束编译。 [详情](https://vue3js.cn/docs/zh/api/directives.html#v-cloak) |√ | x | |
-|v-once | 只渲染元素和组件一次。 [详情](https://vue3js.cn/docs/zh/api/directives.html#v-once) |√ | √ | |
|v-is | 在 `DOM` 内模板使用时,模板受原生 `HTML` 解析规则的约束。 [详情](https://vue3js.cn/docs/zh/api/directives.html#v-is) |√ | x | - |
-## 特殊属性
-
-|特殊属性 |描述 |H5 |App端|说明 |
-| -- | -- | -- |-- | -- |
-|key | `key` 的特殊 `attribute` 主要用在 `Vue` 的虚拟 `DOM` 算法,在新旧 `nodes` 对比时辨识 `VNodes`。 [详情](https://vue3js.cn/docs/zh/api/special-attributes.html#key) |√ | √ | |
-|ref | ref 被用来给元素或子组件注册引用信息。 [详情](https://vue3js.cn/docs/zh/api/special-attributes.html#ref) |√ | √ | 非 H5 平台只能获取 `vue` 组件实例不能获取到内置组件实例|
-|is | 使用[动态组件](https://vue3js.cn/docs/zh/guide/component-dynamic-async.html)。 [详情](https://vue3js.cn/docs/zh/api/special-attributes.html#is) |√ | √ | - |
-
-
-
-## 内置组件
-
-|内置组件 |描述 |H5 |App端|
-| -- | -- | -- |-- |
-|component | 渲染一个“元组件”为动态组件。依 `is` 的值,来决定哪个组件被渲染。 [详情](https://vue3js.cn/docs/zh/api/built-in-components.html#component) |√ | √ | |
-|transition | 作为单个元素/组件的过渡效果。 [详情](https://vue3js.cn/docs/zh/api/built-in-components.html#transition) |√ | x | |
-|transition-group | 作为多个元素/组件的过渡效果。 [详情](https://vue3js.cn/docs/zh/api/built-in-components.html#transition-group) |√ | x | |
-|keep-alive | 包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们,主要用于保留组件状态或避免重新渲染。 [详情](https://vue3js.cn/docs/zh/api/built-in-components.html#keep-alive) |√ |x | |
-|slot | 作为组件模板之中的内容分发插槽。`slot` 元素自身将被替换。 [详情](https://vue3js.cn/docs/zh/api/built-in-components.html#slot) |√ | √ | |
-|teleport | 将模板的一部分移动到 `DOM` 中 `Vue app` 之外的其他位置。 [详情](https://vue3js.cn/docs/zh/api/built-in-components.html#teleport) |√ | x | - |
-
-
-## 响应性 API
-### 响应性基础 API
-|响应性基础 API|描述 |H5 |App端|
-|-- |-- |-- |-- |
-|reactive |返回对象的响应式副本。[详情](https://vue3js.cn/docs/zh/api/basic-reactivity.html#reactive) |√ |√ |
-|readonly |获取一个对象 (响应式或纯对象) 或 `ref` 并返回原始代理的只读代理。[详情](https://vue3js.cn/docs/zh/api/basic-reactivity.html#readonly) |√ |√ |
-|isProxy |检查对象是 `reactive` 还是 `readonly`创建的代理。[详情](https://vue3js.cn/docs/zh/api/basic-reactivity.html#isproxy) |√ |√ |
-|isReactive |检查对象是否是 `reactive`创建的响应式 `proxy`。[详情](https://vue3js.cn/docs/zh/api/basic-reactivity.html#isreactive) |√ |√ |
-|isReadonly |检查对象是否是由`readonly`创建的只读代理。[详情](https://vue3js.cn/docs/zh/api/basic-reactivity.html#isreadonly) |√ |√ |
-|toRaw |返回 `reactive` 或 `readonly` 代理的原始对象。[详情](https://vue3js.cn/docs/zh/api/basic-reactivity.html#toraw) |√ |√ |
-|markRaw |标记一个对象,使其永远不会转换为代理。返回对象本身。[详情](https://vue3js.cn/docs/zh/api/basic-reactivity.html#markraw) |√ |√ |
-|shallowReactive |创建一个响应式代理,该代理跟踪其自身 `property` 的响应性,但不执行嵌套对象的深度响应式转换 (暴露原始值)。[详情](https://vue3js.cn/docs/zh/api/basic-reactivity.html#shallowreactive) |√ |√ |
-|shallowReadonly |创建一个代理,使其自身的 `property` 为只读,但不执行嵌套对象的深度只读转换 (暴露原始值)。[详情](https://vue3js.cn/docs/zh/api/basic-reactivity.html#shallowreadonly) |√ |√ |
-### Refs
-|Refs|描述 |H5 |App端|
-|-- |-- |-- |-- |
-|ref |接受一个内部值并返回一个响应式且可变的 `ref` 对象。`ref` 对象具有指向内部值的单个 property `.value`。[详情](https://vue3js.cn/docs/zh/api/refs-api.html#ref) |√ |√ |
-|unref |如果参数为 `ref`,则返回内部值,否则返回参数本身。这是 `val = isRef(val) ? val.value : val`。[详情](https://vue3js.cn/docs/zh/api/refs-api.html#unref) |√ |√ |
-|toRef |可以用来为源响应式对象上的 `property` 性创建一个 `ref`。然后可以将 `ref` 传递出去,从而保持对其源 `property` 的响应式连接。[详情](https://vue3js.cn/docs/zh/api/refs-api.html#toref) |√ |√ |
-|toRefs |将响应式对象转换为普通对象,其中结果对象的每个 `property` 都是指向原始对象相应 `property` 的`ref`。[详情](https://vue3js.cn/docs/zh/api/refs-api.html#torefs) |√ |√ |
-|isRef |检查值是否为`ref`对象[详情](https://vue3js.cn/docs/zh/api/refs-api.html#isref) |√ |√ |
-|customRef |创建一个自定义的 `ref`,并对其依赖项跟踪和更新触发进行显式控制。[详情](https://vue3js.cn/docs/zh/api/refs-api.html#customref) |√ |√ |
-|shallowRef |创建一个 `ref`,它跟踪自己的 `.value` 更改,但不会使其值成为响应式的。[详情](https://vue3js.cn/docs/zh/api/refs-api.html#shallowref) |√ |√ |
-|triggerRef |手动执行与 `shallowRef` 关联的任何效果。[详情](https://vue3js.cn/docs/zh/api/refs-api.html#triggerref) |√ |√ |
-
-
-
-### Computed 与 watch
-
-|Computed 与 watch|描述 |H5 |App端|
-|-- |-- |-- |-- |
-|computed |使用 `getter` 函数,并为从 `getter` 返回的值返回一个不变的响应式 `ref` 对象。[详情](https://vue3js.cn/docs/zh/api/computed-watch-api.html#computed) |√ |√ |
-|watchEffect |在响应式地跟踪其依赖项时立即运行一个函数,并在更改依赖项时重新运行它。[详情](https://vue3js.cn/docs/zh/api/computed-watch-api.html#watcheffect) |√ |√ |
-|watch |`watch` API 与选项式 API `this.$watch` (以及相应的 `watch` 选项) 完全等效。`watch` 需要侦听特定的 `data` 源,并在单独的回调函数中副作用。[详情](https://vue3js.cn/docs/zh/api/computed-watch-api.html#watch) |√ |√ |
-
-
-
-
-## 组合式 API
-
-|组合式 API|描述 |H5 |App端|
-|-- |-- |-- |-- |
-|setup |一个组件选项,在创建组件之前执行,一旦 `props` 被解析,并作为组合式 `API` 的入口点。[详情](https://vue3js.cn/docs/zh/api/composition-api.html#setup) |√ |√ |
-|生命周期钩子 |可以使用直接导入的 `onX` 函数注册生命周期钩子。[详情](https://vue3js.cn/docs/zh/api/composition-api.html#%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E9%92%A9%E5%AD%90) |√ |√ |
-|Provide / Inject |provide 和 inject 启用依赖注入。只有在使用当前活动实例的 `setup()` 期间才能调用这两者。[详情](https://vue3js.cn/docs/zh/api/composition-api.html#provide-inject) |√ |√ |
-|getCurrentInstance |允许访问对高级使用或库创建者有用的内部组件实例。[详情](https://vue3js.cn/docs/zh/api/composition-api.html#getcurrentinstance) |√ |√ |
-
-
-
-
-## 全局变量
-
-实现全局变量的方式需要遵循 `Vue` 单文件模式的开发规范。详细参考:[uni-app全局变量的几种实现方式](https://ask.dcloud.net.cn/article/35021)。
-
-## 常见问题
-
-### 1. 如何获取上个页面传递的数据
-
-在 `onLoad` 里得到,`onLoad` 的参数是其他页面打开当前页面所传递的数据。
### 2. 如何设置全局的数据和全局的方法
@@ -290,120 +30,7 @@ const app = createApp({})
`uni-app` 内置了 [Vuex](https://uniapp.dcloud.io/vue-vuex) ,在`app`里的使用,可参考 `hello-uniapp` ` store/index.js`。
-```javaScript
- //store.js
- import {createStore} from 'vuex'
- const store = createStore({
- state: {...},
- mutations: {...},
- actions: {...}
- })
- export default store
-
- //main.js
- import App from './App'
- import {createSSRApp} from 'vue'
- import store from './store'
- export function createApp() {
- const app = createSSRApp(App)
- app.use(store)
- return {
- app
- }
- }
-
- //test.vue 使用时:
- import {mapState,mapMutations} from 'vuex'
-```
-
-
-
-### 3. 如何捕获 app 的 onError
-
-由于 `onError` 并不是完整意义的生命周期,所以只提供一个捕获错误的方法,在 `app` 的根组件上添加名为 `onError` 的回调函数即可。如下:
-
-```javaScript
- export default {
- // 只有 app 才会有 onLaunch 的生命周期
- onLaunch () {
- // ...
- },
-
- // 捕获 app error
- onError (err) {
- console.log(err)
- }
- }
-```
-
-
-### 4. 组件属性设置不生效解决办法
-
-当重复设置某些属性为相同的值时,不会同步到`view`层。 例如:每次将`scroll-view`组件的`scroll-top`属性值设置为0,只有第一次能顺利返回顶部。 这和`props`的单向数据流特性有关,组件内部`scroll-top`的实际值改动后,其绑定的属性并不会一同变化。
-
-解决办法有两种(以`scroll-view`组件为例):
-
-1.监听`scroll`事件,记录组件内部变化的值,在设置新值之前先设置为记录的当前值
-
-
-
-```html
-
-```
-
-
-```javaScript
-export default {
- data() {
- return {
- scrollTop: 0,
- old: {
- scrollTop: 0
- }
- }
- },
- methods: {
- scroll: function(e) {
- this.old.scrollTop = e.detail.scrollTop
- },
- goTop: function(e) {
- this.scrollTop = this.old.scrollTop
- this.$nextTick(function() {
- this.scrollTop = 0
- });
- }
- }
-}
-
-```
-
-2.监听scroll事件,获取组件内部变化的值,实时更新其绑定值
-
-```html
-
-```
-
-
-```js
- export default {
- data() {
- return {
- scrollTop: 0,
- }
- },
- methods: {
- scroll: function(e) {
- // 如果使用此方法,请自行增加防抖处理
- this.scrollTop = e.detail.scrollTop
- },
- goTop: function(e) {
- this.scrollTop = 0
- }
- }
- }
-```
-
-
-第二种解决方式在某些组件可能造成抖动,**推荐第一种解决方式**。
+
+
diff --git a/docs/vue3-basics.md b/docs/vue3-basics.md
index 2e2dadba0a6ce24094e284ee850689425a714fed..152c9f79c34cbd18fb4a37add74dd80763a70503 100644
--- a/docs/vue3-basics.md
+++ b/docs/vue3-basics.md
@@ -7,9 +7,6 @@
-**Vue.js 是什么**
-
-Vue (读音 /vjuː/,类似于 `view`) 是一套用于构建用户界面的**渐进式框架**。与其它大型框架不同的是,`Vue` 被设计为可以自底向上逐层应用。
`Vue.js` 的核心是一个允许采用简洁的模板语法来声明式地将数据渲染进 `DOM` 的系统,**只关注视图层,易于上手**。所有东西都是响应式的。
@@ -29,1651 +26,253 @@ Vue (读音 /vjuː/,类似于 `view`) 是一套用于构建用户界面的**
- 组合API,加强API设计一致性,实现逻辑模块化和重用
- 加强TypeScript支持
- 暴露了自定义渲染API
-- 提高自身可维护性
-
-
-## vue相比传统js的开发优势
-
-在传统开发中,用原生的 JavaScript DOM 操作函数对 DOM 进行频繁操作的时候,浏览器要不停的渲染新的 DOM 树,导致页面看起来非常卡顿。
-
-vue 是单页面应用,使页面局部刷新,不用每次跳转页面都要请求所有数据和 DOM ,这样大大加快了访问速度和提升用户体验。
-
-
-
-**vue的优势:**
-
-- 轻量级渐进式框架
-- 视图、数据和结构的分离
-- 响应式双向数据绑定
-- 组件化
-- 虚拟DOM
-- 运行速度快,易于上手
-- 便于与第三方库或既有项目整合
-
-
-
-### 文件类型变化
-
-- 以前是.html文件,开发也是html,运行也是html。
-- 现在是.vue文件,开发是vue,经过编译后,运行时已经变成了js文件。
-- 现代前端开发,很少直接使用HTML,基本都是开发、编译、运行。所以 `uni-app` 有编译器、运行时的概念。
-
-
-### 文件内代码架构的变化
-
-- 以前一个 `html` 大节点,里面有 `script` 和 `style` 节点;
-
-```html
-
-
-
-
-
-
-
-
-
-
-
-```
-
-
-- 现在 `template` 是一级节点,用于写tag组件, `script` 和 `style` 是并列的一级节点,也就是有3个一级节点。这个叫[vue单文件组件规范sfc](https://cn.vuejs.org/v2/guide/single-file-components.html)。
-
-```html
-
-
- 注意必须有一个view,且只能有一个根view。所有内容写在这个view下面。
-
-
-
-
-```
-
-
-### 外部文件引用方式变化
-
-- 以前通过script src、link href引入外部的js和css;
-
-```html
-
-
-```
-
-
-- 现在是es6的写法, `import` 引入外部的js模块(注意不是文件)或css;
-
-**js要require进来,变成了对象**。
-在hello uni-app的 `common` 目录有一个工具类 `util.js` ,可以在hello uni-app中搜索这个例子查看。hello uni-app示例代码可从 [github](https://github.com/dcloudio/hello-uniapp) 获取。
-
-
-```html
-
-```
-
-而在这个 `util.js` 里,要把之前的 `function` 封装为对象的方法
-
-```js
- function formatTime(time) {
- return time;//这里没写逻辑
- }
- module.exports = {
- formatTime: formatTime
- }
-```
-
-
-当然还有一些高级的用法
-
-```js
-
- var dateUtils = require('../../../common/util.js').dateUtils;
-
- import * as echarts from '/components/echarts/echarts.simple.min.js';
-```
-
-**css外部文件导入**。全局样式,在根目录下的 `app.vue` 里写入,每个页面都会加载 `app.vue` 里的样式。
-
-
-```html
-
-```
-
-
-**另外,vue支持组件导入,可以更方便的封装一个包括界面、js、样式的库**。[详见](/vue-components.md)
-
-
-### 组件/标签的变化
-
-以前是html标签,比如 `` ,现在是内置组件,比如 `
` 。
-
-那么标签和组件有什么区别,不都是用尖括号包围起来一段英文吗?
-- 其实标签是老的概念,标签属于浏览器内置的东西。
-- 但组件,是可以自由扩展的。类似你可以把一段js封装成函数或模块,你也可以把一个ui控件封装成一个组件。
-
-`uni-app` 提供了一批[内置组件](https://uniapp.dcloud.io/component/README)。
-
-
-### js的变化
-
-
-- 以前的 DOM 操作,如果你想改变某个 DOM 元素的显示内容,比如一个view的显示文字:给view设id,然后js里通过选择器获取 DOM 元素,进一步通过js进行赋值操作,修改 DOM 元素的属性或值。
-
-```html
-
-
-
-
-
- 123
-
-
-
-```
-
-
-- 现在的做法,是vue的绑定模式,给这个 DOM 元素绑定一个js变量,在script中修改js变量的值,DOM 会自动变化,页面会自动更新渲染。
- - 前端改用 [MVVM](https://baike.baidu.com/item/MVVM/96310?fr=aladdin) (Model-View-ViewModel的简写)模式,简单来说,Model:代表数据模型,View:只专注视图UI处理,ViewModel:只处理业务和数据。它的核心是 MVVM 中的 VM,也就是 ViewModel。 ViewModel负责连接 View 和 Model,保证视图和数据的一致性,这种轻量级的架构让前端开发更加高效、便捷,大幅减少代码行数,同时差量渲染性能更好。
- - `uni-app` 使用vue的数据绑定方式解决js和 DOM 界面交互的问题。
-
-
-```html
-
-
- {{textvalue}}
-
-
-
-
-```
-
-
-
-
-## 在 uni-app 中使用差异
-
-`uni-app` 在发布到H5时支持所有vue的语法;发布到App时,由于平台限制,无法实现全部vue语法,但 `uni-app` 仍是对vue语法支持度最高的跨端框架。
-
-相比Web平台, Vue.js 在 `uni-app` 中使用差异主要集中在两个方面:
-
-- 新增:`uni-app` 除了支持Vue实例的生命周期,还支持[应用生命周期](https://uniapp.dcloud.io/collocation/frame/lifecycle?id=%e5%ba%94%e7%94%a8%e7%94%9f%e5%91%bd%e5%91%a8%e6%9c%9f)以及[页面生命周期](https://uniapp.dcloud.io/collocation/frame/lifecycle?id=%e9%a1%b5%e9%9d%a2%e7%94%9f%e5%91%bd%e5%91%a8%e6%9c%9f)。
-- 受限:相比web平台,在App端部分功能受限。
-- uni-app 完整支持 Vue 模板语法。
-
-
-[uni-app 项目支持 vue 3.0介绍,及升级指南](https://ask.dcloud.net.cn/article/37834)
-
-
-`HBuilderX 3.2.5-alpha`新增在App平台支持 vue 3.0,至此 `uni-app` 项目对 vue 3.0 的支持情况如下:
-
-- H5/PC Web平台支持,编译器升级为`vite`。
-- App 平台:支持,编译器升级为`vite`,`nvue`暂不支持。
-
-
-
-**注意事项**
-
-- vue3 响应式基于 `Proxy` 实现,不支持`iOS9`和`ie11`。
-- 暂不支持新增的 `Teleport`,`Suspense` 组件。
-- 暂不支持 `template` 下存在多个根节点。
-- 目前 `HBuilderX 3.2` 起已预置,之前的版本只能使用cli方式。
-
-
-
-
-## 模板语法
-
-`Vue.js` 使用了基于 `HTML` 的模板语法,允许开发者声明式地将 `DOM` 绑定至底层组件实例的数据。
-所有 `Vue.js` 的模板都是合法的 `HTML`,所以能被遵循规范的浏览器和 `HTML` 解析器解析。
-
-在底层的实现上,`Vue` 将模板编译成虚拟 `DOM` 渲染函数。结合响应性系统,`Vue` 能够智能地计算出最少需要重新渲染多少组件,并把 `DOM` 操作次数减到最少。
-
-
-### 插值
-
-#### 文本
-
-数据绑定最常见的形式就是文本插值:
-
-```html
-
-
- Message: {{ msg }}
-
-
-
-```
-
-{{msg}}里的内容将会被替代为对应数据对象上msg的值。无论何时,绑定的数据对象上msg发生了改变,插值处的内容都会更新。
-
-
-#### 使用 JavaScript 表达式
-
-
-迄今为止,在我们的模板中,我们一直都只绑定简单的 `property` 键值。但实际上,对于所有的数据绑定,Vue.js 都提供了完全的 `JavaScript` 表达式支持。
-
-**示例一**
-
-```html
-
-
- {{ number + 1 }}
- {{ ok ? 'YES' : 'NO' }}
-
- {{ message.split('').reverse().join('') }}
-
-
-
-```
-
-
-**示例二**
-
-```html
-
-
-
-
- {{index%2}}
-
-
-
-
-
-```
-
-
-这些表达式会在所属 Vue 实例的数据作用域下作为 `JavaScript` 被解析。有个限制就是,每个绑定都只能包含单个表达式,所以下面的例子都不会生效。
-
-**错误示例**
-```html
-
-
-
- {{ var a = 1 }}
-
- {{ if (ok) { return message } }}
-
-
-
-```
-
-
-
-
-> 模板表达式都被放在沙盒中,只能访问**全局变量的一个白名单**:
-> - `Infinity`
-> - `undefined`
-> - `NaN`
-> - `isFinite`
-> - `isNaN`
-> - `parseFloat`
-> - `parseInt`
-> - `decodeURI`
-> - `decodeURIComponent`
-> - `encodeURI`
-> - `encodeURIComponent`
-> - `Math`
-> - `Number`
-> - `Date`
-> - `Array`
-> - `Object`
-> - `Boolean`
-> - `String`
-> - `RegExp`
-> - `Map`
-> - `Set`
-> - `JSON`
-> - `Intl`
-> - `BigInt`
->
-> 你不应该在模板表达式中试图访问用户定义的全局变量。
-
-
-
-### 指令
-
-指令是带有 v- 前缀的特殊属性。
-
-- 指令属性的值预期是**单个 `JavaScript` 表达式** (`v-for` 和 `v-on` 是例外情况,稍后我们再讨论)。
-- 指令的作用是,当表达式的值改变时,将其产生的连带影响,响应式地作用于 `DOM` 。
-- 一些指令能够接收一个“参数”,在指令名称之后以冒号( : )表示。
-
-
-#### v-bind
-
-动态地绑定一个或多个属性,`v-bind`缩写为‘ : ’,可以用于响应式地更新 `HTML attribute`:
-
-```html
-
-
-
-
-
-
-```
-
-在这里 `src` 是参数,告知 `v-bind` 指令将该元素的 `src` attribute 与表达式 `imgUrl` 的值绑定。
-
-如果 `isButtonDisabled` 的值是 `null` 或 `undefined`,则 `disabled` attribute 甚至不会被包含在渲染出来的 `button` 元素中。
-
-
-#### v-on
-
-v-on 指令,它用于监听 `DOM` 事件。v-on缩写为‘ @ ’,下文简称为 `@事件`
-
-```html
-
- 点击
-
- 点击
-```
-
-
-#### v-once
-
-只渲染元素和组件一次。随后的重新渲染,元素/组件及其所有的子节点将被视为静态内容并跳过。
-
-和前端框架中的理解不同,客户端里要实现复用的逻辑,会标记模板节点的状态,添加了 `v-once` 能保证节点只渲染一次,但是并不一定能优化渲染性能,反而可能会拖慢客户端复用节点时的比对效率。
-
-```html
-
- This will never change: {{msg}}
-
-
- comment
- {{msg}}
-
-```
-
-
-#### v-html
-
-更新元素的 [`innerHTML`](https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML) 。
-
-- 注意:**内容按普通 HTML 插入 - 不会作为 Vue 模板进行编译。**
-- 如果试图使用 v-html 组合模板,可以重新考虑是否通过使用组件来替代。
-
-
-跨端的富文本处理方案详见:[https://ask.dcloud.net.cn/article/35772](https://ask.dcloud.net.cn/article/35772)
-
-```html
-
-
-
-
-
-
-```
-
-
-
-## Data 选项
-
-`data` 选项已标准化为只接受**返回一个初始数据对象的函数**(注意函数内返回的数据对象不要直接引用函数外的对象);否则页面关闭时,数据不会自动销毁,再次打开该页面时,会显示上次数据。
-
-```js
- //正确用法,使用函数返回对象
- data() {
- return {
- title: 'Hello'
- }
- }
-
- //错误写法,会导致再次打开页面时,显示上次数据
- data: {
- title: 'Hello'
- }
-
- //错误写法,同样会导致多个组件实例对象数据相互影响
- const obj = {
- title: 'Hello'
- }
- data() {
- return {
- obj
- }
- }
-```
-
-
-
-## Class 与 Style 绑定
-
-
-### 绑定 HTML Class
-
-
-**对象语法**
-
-
-我们可以传给 `:class` (`v-bind:class` 的简写) 一个对象,实现动态地切换 `class`。
-
-也可以在对象中传入更多字段来动态切换多个 `class`。此外,`v-bind:class` 指令也可以与普通的 `class` 共存。
-
-
-```html
-
-
- hello uni-app
- hello uni-app
-
-
-
-
-```
-
-渲染结果为
-
-```html
-
-```
-
-当 `isActive` 或者 `hasError` 变化时,class 列表将相应地更新。例如,如果 `hasError` 的值为 `true` ,class 列表将变为 `static active text-danger`。
-
-
-
-**数组语法**
-
-可以把一个数组传给 `v-bind:class`,以应用一个 `class` 列表。
-
-```html
-
-
- hello uni-app
-
-
-
-
-```
-
-
-渲染的结果为:
-
-```html
-
-```
-
-如果你想根据条件切换列表中的 class,可以使用三元表达式:
-
-
-```html
-
-```
-
-
-这样写将始终添加 `errorClass`,但是只有在 `isActive` 为 `truthy` 时才添加 `activeClass`。
-
-> 在 `JavaScript` 中,`truthy`(真值)指的是在布尔值上下文中,转换后的值为真的值。所有值都是真值,除非它们被定义为 假值(即除 `false`、0、""、`null`、`undefined` 和 `NaN` 以外皆为真值)。
-
-
-不过,当有多个条件 class 时这样写有些繁琐。所以在数组语法中也可以使用对象语法:
-
-```html
-
-
- hello uni-app
-
-
-
-
-```
-
-**注意:以:style=""这样的方式设置px像素值,其值为实际像素,不会被编译器转换。**
-
-
-此外还可以用计算属性 `computed` 方法生成 `class` 或者 `style` 字符串,插入到页面中,举例说明:
-
-```html
-
-
- hello uni-app
- hello uni-app
-
-
-
-
-```
-
-
-
-### 绑定内联样式
-
-**对象语法**
-
-:style 的对象语法十分直观——看着非常像 CSS,但其实是一个 `JavaScript` 对象。CSS property 名可以用驼峰式 (`camelCase`) 或短横线分隔 (`kebab-case`,记得用引号括起来) 来命名:
-
-```html
-
- hello uni-app
-
-
-```
-
-
-直接绑定到一个样式对象通常更好,这会让模板更清晰:
-
-```html
-
- hello uni-app
-
-
-```
-
-同样的,对象语法常常结合返回对象的计算属性使用。
-
-
-**数组语法**
-
-`:style` 的数组语法可以将多个样式对象应用到同一个元素上:
-
-```html
-
-
- hello uni-app
-
-
-
-```
-
-
-**自动添加前缀**
-
-在 `:style` 中使用需要 (浏览器引擎前缀) [vendor prefixesa](https://developer.mozilla.org/en-US/docs/Glossary/Vendor_Prefix) 的 `CSS property` 时,如 `transform`,`Vue` 将自动侦测并添加相应的前缀。
-
-
-
-**多重值**
-
-可以为 `style` 绑定中的 `property` 提供一个包含多个值的数组,常用于提供多个带前缀的值,例如:
-
-```html
-
-```
-
-这样写只会渲染数组中最后一个被浏览器支持的值。在本例中,如果浏览器支持不带浏览器前缀的 `flexbox`,那么就只会渲染 `display: flex`。
-
-
-## 条件渲染
-
-### v-if和v-else
-
-`v-if` 指令用于条件性地渲染一块内容。这块内容只会在指令的表达式返回 `truthy` 值的时候被渲染。
-使用 `v-else` 指令来表示 `v-if` 的“else 块”。
-`v-else` 元素必须紧跟在带 `v-if` 或者 `v-else-if` 的元素的后面,否则它将不会被识别。
-
-> 在 `JavaScript` 中,`truthy`(真值)指的是在布尔值上下文中,转换后的值为真的值。所有值都是真值,除非它们被定义为 假值(即除 `false`、0、""、`null`、`undefined` 和 `NaN` 以外皆为真值)。
-
-```html
-
-
- 现在你看到我了
- 你看不到我了
-
-
-
-```
-
-
-`v-else-if`,顾名思义,充当 v-if 的“else-if 块”,可以连续使用:
-
-
-```html
-
-
-
- A
-
-
- B
-
-
- C
-
-
- Not A/B/C
-
-
-
-
-```
-
-类似于 `v-else` ,`v-else-if` 也必须紧跟在带 `v-if` 或者 `v-else-if` 的元素之后。
-
-
-### 条件渲染分组
-
-因为 `v-if` 是一个指令,所以必须将它添加到一个元素上。但是如果想切换多个元素呢?
-
-此时可以把一个 `template` 元素当做不可见的包裹元素,并在上面使用 `v-if`。最终的渲染结果将不包含 `template` 元素。
-
-
-```html
-
- 标题
- 内容:现在你看到我了
-
-```
-
-
-### v-show
-
-另一个用于根据条件展示元素的选项是 `v-show` 指令。用法大致一样:
-
-```html
- Hello!
-```
-
-不同的是带有 `v-show` 的元素始终会被渲染并保留在 `DOM` 中。`v-show` 只是简单地切换元素的 `CSS` 属性的 `display` 。
-
-> 注意,v-show 不支持 template 元素,也不支持 v-else。nvue 页面不支持 v-show。
-
-
-### v-if 和 v-show 区别
-
-
-`v-if` 是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。
-
-`v-if` 也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。
-
-相比之下,`v-show` 就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换,来控制元素的显示和隐藏。
-
-**根据应用场景选择**
-
-- `v-if` 有更高的切换开销,如果在运行时条件很少改变,则使用 v-if 较好。
-- `v-show` 有更高的初始渲染开销。如果需要非常频繁地切换,则使用 v-show 较好。
-
-
-**注意**
-
-- 不推荐同时使用 `v-if` 和 `v-for`。
-- 当 `v-if` 与 `v-for` 一起使用时,**`v-if` 具有比 `v-for` 更高的优先级**。
-
-
-## 列表渲染
-
-### 在 v-for 里使用数组
-
-v-for 指令可以实现基于一个数组来渲染一个列表。
-
-- `v-for` 指令需要使用 `item in items` 形式的特殊语法,其中 `items` 是源数据数组,而 `item` 则是被迭代的数组元素的别名。
- - 在 v-for 块中,我们可以访问所有父作用域的 `property`
- - 第一个参数 `item` 则是被迭代的数组元素的别名。
- - 第二个参数,即当前项的索引 `index` ,是可选的。
-
-```html
-
-
-
- {{ parentMessage }} - {{ index }} - {{ item.message }}
-
-
-
-
-```
-
-结果:
-
-```html
- Parent - 0 - Foo
- Parent - 1 - Bar
-```
-
-
-### 在 v-for 里使用对象
-
-你也可以用 v-for 来遍历一个对象的 `property`。
-
-- 第一个参数 `value` 是被迭代的对象元素的属性值。
-- 第二个参数为 `property` 名称 (也就是键名)。
-- 第三个参数作为索引。
-
-```html
-
-
-
- {{ index }}. {{ name }}: {{ value }}
-
-
-
-
-```
-
-
-结果:
-
-```html
- 0.title: How to do lists in Vue,
- 1.author: Jane Doe,
- 2.publishedAt: 2021-05-10
-```
-
-
-> 在遍历对象时,会按 `Object.keys()` 的结果遍历,但是不能保证它在不同 `JavaScript` 引擎下的结果都一致。
-
-
-### 列表渲染分组
-
-类似于 `v-if`,你也可以利用带有 `v-for` 的 `template` 来循环渲染一段包含多个元素的内容。比如:
-
-```html
-
- {{ item.message }}
-
-
-```
-
-
-### 维护状态
-
-
-当 `Vue` 正在更新使用 `v-for` 渲染的元素列表时,它默认使用“就地更新”的策略。如果数据项的顺序被改变,`Vue` 将不会移动 `DOM` 元素来匹配数据项的顺序,而是就地更新每个元素,并且确保它们在每个索引位置正确渲染。
-
-
-这个默认的模式是高效的,但是**只适用于不依赖子组件状态或临时 DOM 状态 (例如:表单输入值) 的列表渲染输出**。
-
-
-为了给 `Vue` 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一 `key` attribute:
-
-```html
-
-
-
-```
-
-建议尽可能在使用 `v-for` 时提供 `key` attribute,除非遍历输出的 DOM 内容非常简单,或者是刻意依赖默认行为以获取性能上的提升。
-
-- 如果不使用 key,Vue 会使用一种最大限度减少动态元素并且尽可能的尝试就地修改/复用相同类型元素的算法。
-- 而使用 key 时,它会基于 key 的变化重新排列元素顺序,并且会移除/销毁 key 不存在的元素。
-- 有相同父元素的子元素必须有独特的 key。重复的 key 会造成渲染错误。
-
-> 不要使用对象或数组之类的非基本类型值作为 v-for 的 key。请用字符串或数值类型的值。
->
-> 如不提供 :key,会报一个 `warning`, 如果明确知道该列表是静态,或者不必关注其顺序,可以选择忽略。
-
-示例:
-
-```html
-
-
-
-
- {{index +':'+ item.name}}
-
-
-
- {{index +':'+ item}}
-
-
-
-
-```
-
-
-### 注意事项
-
-- 在H5平台 使用 v-for 循环整数时和其他平台存在差异,如 `v-for="(item, index) in 10"` 中,在H5平台 item 从 1 开始,其他平台 item 从 0 开始,可使用第二个参数 index 来保持一致。
-- 在非H5平台 循环对象时不支持第三个参数,如 `v-for="(value, name, index) in object"` 中,index 参数是不支持的。
-
-
-
-### 结合 ``
-
-在`Vue3`中,`key` 则应该被设置在 `` 标签上
-
-```html
-
- ...
- ...
-
-```
-
-
-类似地,当使用 `` 时存在使用 `v-if` 的子节点,`key` 应改为设置在 `` 标签上。
-
-```html
-
- ...
- ...
-
-```
-
-
-
-
-### 在组件上使用 v-for
-
-在自定义组件上,你可以像在任何普通元素上一样使用 `v-for` 。
-
-```html
-
-```
-
-**当在组件上使用 v-for 时,key是必须的。**
-
-
-
-### v-for 与 v-if 一同使用
-
-> 不推荐在同一元素上使用 v-if 和 v-for
-
-当它们处于同一节点,**`v-if` 的优先级比 `v-for` 更高**,这意味着 `v-if` 将没有权限访问 `v-for` 里的变量:
-
-
-```html
-
-
- {{ todo }}
-
-```
-
-
-可以把 `v-for` 移动到 `template` 标签中来修正:
-
-```html
-
-
- {{ todo }}
-
-
-```
-
-
-
-## 事件处理
-
-
-### 监听事件
-
-我们可以使用 `v-on` 指令 (通常缩写为 @ 符号,下文简称为:@事件) 来监听 DOM 事件,并在触发事件时执行一些 `JavaScript`。
-用法为 `v-on:click="methodName"` 或使用快捷方式 `@click="methodName"`
-
-```html
-
-
-
- The button above has been clicked {{ counter }} times.
-
-
-
-```
-
-
-### 事件处理方法
-
-然而许多事件处理逻辑会更为复杂,所以直接把 `JavaScript` 代码写在@事件中是不可行的。因此@事件还可以接收一个需要调用的方法名称。
-
-示例:
-
-```html
-
-
-
-
-
-
-
-```
-
-
-
-### 内联处理器中的方法
-
-除了直接绑定到一个方法,也可以在内联 `JavaScript` 语句中调用方法:
-
-
-```html
-
-
-
-
-
-
-
-```
-
-有时也需要在内联语句处理器中访问原始的 DOM 事件。可以用特殊变量 `$event` 把它传入方法:
-
-```html
-
-
-
-
-
-
-```
-
-
-### 多事件处理器
-
-事件处理程序中可以有多个方法,这些方法由逗号运算符分隔:
-
-```html
-
-
-
-
-
-
-
-```
+- 提高自身可维护性
-### 事件修饰符
-修饰符 (modifier) 是以半角句号 . 指明的特殊后缀,用于指出一个指令应该以特殊方式绑定。例如,`.prevent` 修饰符告诉 @事件对于触发的事件调用 `event.preventDefault()`:
-@事件(v-on)提供了事件修饰符:
-- `.stop`: 各平台均支持, 使用时会阻止事件冒泡,在非 H5 端同时也会阻止事件的默认行为
-- `.prevent`: 仅在 H5 平台支持
-- `.capture`: 仅在 H5 平台支持
-- `.self`: 仅在 H5 平台支持
-- `.once`: 仅在 H5 平台支持
-- `.passive`: 仅在 H5 平台支持
+**vue的优势:**
-```html
-
-
-```
+- 虚拟DOM
+- 运行速度快,易于上手
+- 便于与第三方库或既有项目整合
-> 使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生。因此,用 `@click.prevent.self` 会阻止所有的点击,而 `@click.self.prevent` 只会阻止对元素自身的点击。
-**注意**
-- 为兼容各端,不能在 JS 中使用`event.preventDefault()`和`event.stopPropagation()`方法;
-- 若需要禁止蒙版下的页面滚动,可使用 `@touchmove.stop.prevent="moveHandle"`,`moveHandle` 可以用来处理 `touchmove` 的事件,也可以是一个空函数。
+在hello uni-app的 `common` 目录有一个工具类 `util.js` ,可以在hello uni-app中搜索这个例子查看。hello uni-app示例代码可从 [github](https://github.com/dcloudio/hello-uniapp) 获取。
-```html
-
+
+`
+
+
+当然还有一些高级的用法
+
+```js
+
+ var dateUtils = require('../../../common/util.js').dateUtils;
+
+ import * as echarts from '/components/echarts/echarts.simple.min.js';
```
-- 按键修饰符:`uni-app` 运行在手机端,没有键盘事件,所以不支持按键修饰符。
+**css外部文件导入**。全局样式,在根目录下的 `app.vue` 里写入,每个页面都会加载 `app.vue` 里的样式。
-**使用 v-on 或 @ 有几个好处**
-1. 扫一眼 `HTML` 模板便能轻松定位在 `JavaScript` 代码里对应的方法。
-2. 因为你无须在 `JavaScript` 里手动绑定事件,你的 `ViewModel` 代码可以是非常纯粹的逻辑,和 `DOM` 完全解耦,更易于测试。
+*
+`uni-app` 提供了一批[内置组件](https://uniapp.dcloud.io/component/README)。
+
-3. 当一个 `ViewModel` 被销毁时,所有的事件处理器都会自动被删除。你无须担心如何清理它们。
+ - `uni-app` 使用vue的数据绑定方式解决js和 DOM 界面交互的问题。
-### 事件映射表
+## 在 uni-app 中使用差异
-```js
-// 事件映射表,左侧为 WEB 事件,右侧为 ``uni-app`` 对应事件
- {
- click: 'tap',
- touchstart: 'touchstart',
- touchmove: 'touchmove',
- touchcancel: 'touchcancel',
- touchend: 'touchend',
- tap: 'tap',
- longtap: 'longtap', //推荐使用longpress代替
- input: 'input',
- change: 'change',
- submit: 'submit',
- blur: 'blur',
- focus: 'focus',
- reset: 'reset',
- confirm: 'confirm',
- columnchange: 'columnchange',
- linechange: 'linechange',
- error: 'error',
- scrolltoupper: 'scrolltoupper',
- scrolltolower: 'scrolltolower',
- scroll: 'scroll'
- }
-```
+`uni-app` 在发布到H5时支持所有vue的语法;发布到App时,由于平台限制,无法实现全部vue语法,但 `uni-app` 仍是对vue语法支持度最高的跨端框架。
+相比Web平台, Vue.js 在 `uni-app` 中使用差异主要集中在两个方面:
+- 新增:`uni-app` 除了支持Vue实例的生命周期,还支持[应用生命周期](https://uniapp.dcloud.io/collocation/frame/lifecycle?id=%e5%ba%94%e7%94%a8%e7%94%9f%e5%91%bd%e5%91%a8%e6%9c%9f)以及[页面生命周期](https://uniapp.dcloud.io/collocation/frame/lifecycle?id=%e9%a1%b5%e9%9d%a2%e7%94%9f%e5%91%bd%e5%91%a8%e6%9c%9f)。
+- 受限:相比web平台,在App端部分功能受限。
+- uni-app 完整支持 Vue 模板语法。
-## 表单输入绑定
+[uni-app 项目支持 vue 3.0介绍,及升级指南](https://ask.dcloud.net.cn/article/37834)
-### v-model
+`HBuilderX 3.2.5-alpha`新增在App平台支持 vue 3.0,至此 `uni-app` 项目对 vue 3.0 的支持情况如下:
-你可以用 v-model 指令在表单 `input`、`textarea` 及 `select` 元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。尽管有些神奇,但 `v-model` 本质上不过是语法糖。它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理。
+- H5/PC Web平台支持,编译器升级为`vite`。
+- App 平台:支持,编译器升级为`vite`,`nvue`暂不支持。
-> v-model 会忽略所有表单元素的 `value`、`checked`、`selected` attribute 的初始值而总是将 Vue 实例的数据作为数据来源。你应该通过 JavaScript 在组件的 data 选项中声明初始值。
-```html
-
-
-
- Message is: {{ message }}
-
-
-
-```
+**注意事项**
+
+- vue3 响应式基于 `Proxy` 实现,不支持`iOS9`和`ie11`。
+- 暂不支持新增的 `Teleport`,`Suspense` 组件。
+- 暂不支持 `template` 下存在多个根节点。
+- 目前 `HBuilderX 3.2` 起已预置,之前的版本只能使用cli方式。
-### uni-app表单组件
-建议开发过程中直接使用 `uni-app`:[表单组件](https://uniapp.dcloud.io/component/button)。
-##### 用法示例:
-- H5 的 `select` 标签用 `picker` 组件进行代替
```html
-
-
-
- 当前选择:{{array[index]}}
-
-
-
+
+ {{ number + 1 }}
+ {{ ok ? 'YES' : 'NO' }}
+
+ {{ message.split('').reverse().join('') }}
+
```
-- 表单元素 `radio` 用 `radio-group` 组件进行代替
+
```html
-
-
-
-
-
+
+
+
+ {{index%2}}
+
+
+
```
-## 计算属性和侦听器
-### 计算属性computed
+和前端框架中的理解不同,客户端里要实现复用的逻辑,会标记模板节点的状态,添加了 `v-once` 能保证节点只渲染一次,但是并不一定能优化渲染性能,反而可能会拖慢客户端复用节点时的比对效率。
-每一个计算属性都包含一个 `getter` 函数和一个 `setter`函数 ,默认是利用 `getter` 函数来读取。所有 `getter` 和 `setter` 函的 `this` 上下文自动地绑定为 Vue 实例。
-#### 计算属性的 getter
+跨端的富文本处理方案详见:[https://ask.dcloud.net.cn/article/35772](https://ask.dcloud.net.cn/article/35772)
-模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的。在模板中放入太多的逻辑会让模板过重且难以维护。例如,有一个嵌套数组对象:
+`data` 选项已标准化为只接受**返回一个初始数据对象的函数**(注意函数内返回的数据对象不要直接引用函数外的对象);否则页面关闭时,数据不会自动销毁,再次打开该页面时,会显示上次数据。
```js
+ //正确用法,使用函数返回对象
data() {
return {
- author: {
- name: 'John Doe',
- books: [
- 'Vue 2 - Advanced Guide',
- 'Vue 3 - Basic Guide',
- 'Vue 4 - The Mystery'
- ]
- }
+ title: 'Hello'
+ }
+ }
+
+ //错误写法,会导致再次打开页面时,显示上次数据
+ data: {
+ title: 'Hello'
+ }
+
+ //错误写法,同样会导致多个组件实例对象数据相互影响
+ const obj = {
+ title: 'Hello'
+ }
+ data() {
+ return {
+ obj
}
}
```
-我们想根据 author 是否已经有一些书来显示不同的消息
-```html
-
- Has published books:
- {{ author.books.length > 0 ? 'Yes' : 'No' }}
-
-```
-此时,模板不再是简单的和声明性的。你必须先看一下它,然后才能意识到它执行的计算取决于 author.books。如果要在模板中多次包含此计算,则问题会变得更糟。
-所以,对于任何包含响应式数据的复杂逻辑,你都应该使用**计算属性**。
+### 结合 ``
-**例子**
+在`Vue3`中,`key` 则应该被设置在 `` 标签上
```html
-
-
- OHas published books:
- {{ publishedBooksMessage }}
-
+
+ ...
+ ...
-
```
-这里声明了一个计算属性 `publishedBooksMessage`。
-
-尝试更改应用程序 `data` 中 `books` 数组的值,你将看到 `publishedBooksMessage` 如何相应地更改。
+类似地,当使用 `` 时存在使用 `v-if` 的子节点,`key` 应改为设置在 `` 标签上。
-你可以像普通属性一样将数据绑定到模板中的计算属性。Vue 知道 `publishedBookMessage` 依赖于 `author.books`,因此当 `author.books` 发生改变时,所有依赖 `publishedBookMessage` 绑定也会更新。而且最妙的是我们已经声明的方式创建了这个依赖关系:计算属性的 getter 函数没有副作用,这使得更易于测试和理解。
+```html
+
+ ...
+ ...
+
+```
-计算属性还可以依赖多个 Vue 实例的数据,只要其中任一数据变化,计算属性就会重新执行,视图也会更新。
-#### 计算属性的 setter
-计算属性默认只有 `getter`,不过在需要时你也可以提供一个 `setter`, 当手动修改计算属性的值时,就会触发 `setter` 函数,执行一些自定义的操作。
-```html
-
-
- {{ fullName }}
-
-
-
-```
-现在再运行 `fullName = 'John Doe'` 时,`setter` 会被调用,`firstName` 和 `lastName` 也会相应地被更新。
-#### getter与setter区别
-- get:通过设置get方法可以得到fullName的新值。
-- set:通过set的方法,设置一个值(newValue)来改变fullName相关联的值,引起fullName重新的计算,相应的页面上fullName也会发生改变成新的内容。
+- 为兼容各端,不能在 JS 中使用`event.preventDefault()`和`event.stopPropagation()`方法;
-### 计算属性缓存 vs 方法
+- 按键修饰符:`uni-app` 运行在手机端,没有键盘事件,所以不支持按键修饰符。
-我们可以通过在表达式中调用方法来达到同样的效果:
-```html
-
-
- {{ calculateBooksMessage() }}
-
-
-
-```
-我们可以将同一函数定义为一个方法而不是一个计算属性。两种方式的最终结果确实是完全相同的。然而,不同的是**计算属性是基于它们的反应依赖关系缓存的**。
-计算属性只在相关响应式依赖发生改变时它们才会重新求值。这就意味着只要 `author.books` 还没有发生改变,多次访问 `publishedBookMessage` 计算属性会立即返回之前的计算结果,而不必再次执行函数。
-这也同样意味着下面的计算属性将不再更新,因为 `Date.now ()` 不是响应式依赖:
+### 事件映射表
```js
- computed: {
- now(){
- return Date.now()
- }
- }
+// 事件映射表,左侧为 WEB 事件,右侧为 ``uni-app`` 对应事件
+
```
-相比之下,每当触发重新渲染时,**调用方法将总会再次执行函数**。
-我们为什么需要缓存?
-假设我们有一个性能开销比较大的计算属性 `list`,它需要遍历一个巨大的数组并做大量的计算。然后我们可能有其他的计算属性依赖于 `list`。如果没有缓存,我们将不可避免的多次执行 `list` 的 `getter`!如果你不希望有缓存,请用 `method` 来替代。
+
+### uni-app表单组件
+
+建议开发过程中直接使用 `uni-app`:[表单组件](https://uniapp.dcloud.io/component/button)。
+
+##### 用法示例:
+
+- H5 的 `select` 标签用 `picker` 组件进行代替
+
+
+
+- 表单元素 `radio` 用 `radio-group` 组件进行代替
+
+
+
-### 侦听器watch
-虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的侦听器。这就是为什么 `Vue` 通过 `watch` 选项提供了一个更通用的方法,来响应数据的变化。当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。
当你有一些数据需要随着其它数据变动而变动时,就可以使用`Watch`来监听他们之间的变化。
-一个对象,键是需要观察的表达式,值是对应回调函数。值也可以是方法名,或者包含选项的对象。
+
`Vue` 实例将会在实例化时调用 `$watch()` ,遍历 `watch` 对象的每一个 `property` 。
@@ -1721,9 +320,6 @@ v-for 指令可以实现基于一个数组来渲染一个列表。
以上示例有个问题,就是页面刚加载时,因为没有变化,所以不会执行。下面用`immediate`来解决。
-#### 选项:immediate
-
-在选项参数中指定 `immediate: true` 将立即以表达式的当前值触发回调:
`watch`方法默认就是`handler`,而当`immediate:true`时,就会先执行`handler`方法。
@@ -1771,9 +367,7 @@ v-for 指令可以实现基于一个数组来渲染一个列表。
-#### 选项:deep
-
-为了发现对象内部值的变化,可以在选项参数中指定 `deep: true` 。深度监听一个对象整体的变化(即监听对象所有属性值的变化),注意监听数组的变更不需要这么做。
+#
```html
@@ -1839,47 +433,3 @@ v-for 指令可以实现基于一个数组来渲染一个列表。
```
-
-### 计算属性 vs 侦听属性
-
-`Vue` 提供了一种更通用的方式来观察和响应 `Vue` 实例上的数据变动:**侦听属性**。当你有一些数据需要随着其它数据变动而变动时,你很容易滥用 `watch` 。然而,通常更好的做法是使用计算属性而不是命令式的 `watch` 回调。
-
-
-```js
- export default {
- data() {
- return {
- firstName: 'Foo',
- lastName: 'Bar',
- fullName: 'Foo Bar'
- }
- },
- watch: {
- firstName: function(val) {
- this.fullName = val + ' ' + this.lastName
- },
- lastName: function(val) {
- this.fullName = this.firstName + ' ' + val
- }
- }
- }
-```
-
-上面代码是命令式且重复的。将它与计算属性的版本进行比较:
-
-
-```js
- export default {
- data() {
- return {
- firstName: 'Foo',
- lastName: 'Bar'
- }
- },
- computed: {
- fullName(){
- return this.firstName + ' ' + this.lastName
- }
- }
- }
-```
diff --git a/docs/vue3-components.md b/docs/vue3-components.md
index 5f3cad8a744850a3168daf06c781f0c61023d6b4..0c51b11170eaaf9d7714107328bb2693a8c587e2 100644
--- a/docs/vue3-components.md
+++ b/docs/vue3-components.md
@@ -4,31 +4,12 @@
> 已经有 Vue 2项目,需要适配 Vue 3 的可参阅[vue2 项目迁移 vue3](https://uniapp.dcloud.io/migration-to-vue3)!
-## 概念
-- 组件是视图层的基本组成单元。
-- 组件是一个单独且可复用的功能模块的封装。
-- 一个组件包括开始标签和结束标签,标签上可以写属性,并对属性赋值。内容则写在两个标签之内。
- 根节点为 ``,这个 `` 下在App、H5可以有多个根 `` 组件。
- - 一个组件的 data 选项必须是一个函数。
+
下面是一个基本组件示例,在根``组件下再次引入一个``组件,并给组件的`text`区绑定一个`data`。
-```html
-
-
- {{userName}}
-
-
-
-```
+
基础组件是内置在`uni-app`框架中的,包括`view`、`text`、`input`、`button`、`video`等几十个基础组件,列表详见:[uni-app基础组件](https://uniapp.dcloud.net.cn/component/README?id=%e5%9f%ba%e7%a1%80%e7%bb%84%e4%bb%b6)
@@ -49,32 +30,11 @@
-## 优势
-- 可以将组件进行任意次数的复用。
-- 合理的划分组件,有助于提高应用性能。
-- 代码更加方便组织和管理,并且扩展性也更强,便于多人协同开发。
-- 组件化开发能大幅度提高应用开发效率、测试性、复用性等。
-
-## 注册
-
-在注册一个组件的时候,我们始终需要给它一个名字。
-定义组件名的方式有两种:
-
-- 使用 kebab-case
-
-当使用 `kebab-case` (短横线分隔命名) 定义一个组件时,你也必须在引用这个自定义元素时使用 `kebab-case`,例如 ``。
-
-- 使用 PascalCase
-
-当使用 `PascalCase` (首字母大写命名) 定义一个组件时,你在引用这个自定义元素时两种命名法都可以使用。
-也就是说 `` 和 `` 都是可接受的。
-
-
在uni-app工程根目录下的 `components` 目录,创建并存放自定义组件:
```html
@@ -86,108 +46,9 @@
-### 全局注册
-
-`uni-app` 支持配置全局组件,需在 `main.js` 里进行全局注册,注册后就可在所有页面里使用该组件。
-
-**注意**
-
-- app.component 的第一个参数必须是静态的字符串。
-- nvue 页面暂不支持全局组件。
-
-1.`main.js` 里进行全局导入和注册
-
-```js
- import App from './App'
- import {createSSRApp} from 'vue'
- //引入组件
- import myComponent from './components/my-component/my-component.vue'
- export function createApp() {
- const app = createSSRApp(App)
- //调用app.component方法全局注册组件
- app.component('my-component', myComponent)
- return {
- app
- }
- }
-```
-
-2.`index.vue` 里可直接使用组件
-
-
-```html
-
-
-
-
-
-```
-
-
-### 局部注册
-
-
-局部注册之前,在需要引用该组件的页面,导入你想使用的组件。
-
-**页面引入组件方式**
-
-
-如下通过两种方式导入一个角标的组件库,[详见](https://ext.dcloud.net.cn/plugin?id=21),推荐使用 `easycom` 方式引入。
-
-1.**传统vue规范:** 在 index.vue 页面中,通过 `import` 方式引入组件 ,在 `components` 选项中定义你想要使用的组件。
-
-```html
-
-
-
-
-
-
-
-```
-
-对于 `components` 对象中的每个 `property` 来说,其 `property` 名就是自定义元素的名字,其 `property` 值就是这个组件的选项对象。
-
-在对象中放一个类似 `uniBadge` 的变量名其实是 `uniBadge : uniBadge` 的缩写,即这个变量名同时是:
-
-- 用在模板中的自定义元素的名称
-- 包含了这个组件选项的变量名(仅支持驼峰法命名)
-
-
-2.**通过uni-app的[easycom](https://uniapp.dcloud.io/collocation/pages?id=easycom):** 将组件引入精简为一步。只要组件安装在项目的 `components` 目录下,并符合 `components/组件名称/组件名称.vue` 目录结构。就可以不用引用、注册,直接在页面中使用。
-
-
-```html
-
-
-
-
-
-
-
-```
-
-- **easycom是自动开启的**,不需要手动开启,有需求时可以在 `pages.json` 的 `easycom` 节点进行个性化设置,[详见](https://uniapp.dcloud.io/collocation/pages?id=easycom)。
-
-- 不管`components`目录下安装了多少组件,`easycom`打包后会自动剔除没有使用的组件,对组件库的使用尤为友好。
-
+#
-组件是 `vue` 技术中非常重要的部分,组件使得与ui相关的轮子可以方便的制造和共享,进而使得 `vue` 使用者的开发效率大幅提升。
-
`uni-app` 搭建了组件的插件市场,有很多现成的组件,若下载`符合components/组件名称/组件名称.vue`目录结构的组件,均可直接使用。[uni-app插件市场](https://ext.dcloud.net.cn/)
@@ -196,203 +57,67 @@
-## props
-
-`props` 可以是数组或对象,用于接收来自父组件的数据。`props` 可以是简单的数组,或者使用对象作为替代,对象允许配置高级选项,如类型检测、自定义验证和设置默认值。
-
-
-|选项 |类型 |说明 |
-|-- |-- |-- |
-|type | `String` 、 `Number` 、 `Boolean` 、 `Array` 、 `Object` 、 `Date` 、 `Function` 、 `Symbol` ,任何自定义构造函数、或上述内容组成的数组 |会检查一个 `prop` 是否是给定的类型,否则抛出警告 |
-|default |any |为该 `prop` 指定一个默认值。如果该 `prop` 没有被传入,则换做用这个值。对象或数组的默认值必须从一个工厂函数返回。 |
-|required |Boolean |定义该 `prop` 是否是必填项|
-|validator |Function |自定义验证函数会将该 `prop` 的值作为唯一的参数代入。在非生产环境下,如果该函数返回一个 `false` 的值 (也就是验证失败),一个控制台警告将会被抛出|
-
-
-##### 示例:
-
-```html
-
-
-
- {{age}}
-
-
-
-```
-
-```html
-
-
-
-
-
-
-```
-
-
-
-
-### 传递静态或动态的 Prop
-
-
-- 可以像这样给 `prop` 传入一个静态的值:
-
-```html
-
-```
-
-- 可以通过 `v-bind` 或简写 : 动态赋值,例如:
-
-```html
-
-
-
-
-
-```
-
-
-在上述两个示例中,我们传入的值都是字符串类型的,但实际上任何类型的值都可以传给一个 `prop`。
-
-
-- 传入一个数字
-
-
-```html
-
-
-
-
-
-
-```
-
-- 传入一个布尔值
-
-
-```html
-
-
-
-
-
-
-
-
-
-```
-
-
-
-- 传入一个数组
-
-
-```html
-
-
-
-
-
-```
-
-
-
-- 传入一个对象
-
-
-```html
-
-
-
-
-
-
-```
-
-
-- 传入一个对象的所有 `property`
-
-
-如果你想要将一个对象的所有 `property` 都作为 `prop` 传入,你可以使用不带参数的 v-bind (取代 v-bind:prop-name)。例如,对于一个给定的对象 post:
-
-```js
- post: {
- id: 1,
- title: 'My Journey with Vue'
- }
-```
+则监听这个名字的 `kebab-case` (短横线隔开式) 版本是不会有任何效果的:
```html
-
-
-
+
+
```
-### 单向数据流
-
-
-所有的 `prop` 都使得其父子 `prop` 之间形成了一个**单向下行绑定**:
-父级 `prop` 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外变更父级组件的状态,从而导致你的应用的数据流向难以理解。
-
-
-> 每次父级组件发生变更时,子组件中所有的 `prop` 都将会刷新为最新的值。这意味着你不应该在一个子组件内部改变 `prop`。如果你这样做了,Vue 会在浏览器的控制台中发出警告。
+不同于组件和 `prop`,事件名不会被用作一个 `JavaScript` 变量名或 `property` 名,所以就没有理由使用 `camelCase` (驼峰命名法) 或 `PascalCase`(帕斯卡命名法) 了。并且 `v-on` 事件监听器在 `DOM` 模板中会被自动转换为全小写 (因为 `HTML` 是大小写不敏感的),所以 `@myEvent` 将会变成 `@myevent`——导致 `myEvent` 不可能被监听到。
-这里有两种常见的试图变更一个 prop 的情形:
+因此,我们推荐你始终使用 `kebab-case` (短横线隔开式) 的事件名。
-1. **这个 `prop` 用来传递一个初始值**;这个子组件接下来希望将其作为一个本地的 `prop` 数据来使用。在这种情况下,最好定义一个本地的 `data property `并将这个 `prop` 作为其初始值:
+示例
```html
-
- {{myTitle}}
+
+ counter的值是:{{count}}
+
```
+
```html
-
+
+
-```
```html
-
-
+ 父组件-count的值是:{{count}}
+
+
```
-```html
-
-
-
-
-
-
-```
-
-
-## 非 Prop 的 Attribute
-
-一个非 `prop` 的 `attribute` 是指传向一个组件,但是该组件并没有相应 `props` 或 `emits` 定义的 `attribute`。常见的示例包括 `class`、`style` 和 `id` 属性。
-
-### Attribute 继承
-
-当组件返回单个根节点时,非 `prop` attribute 将自动添加到根节点的 `attribute` 中。例如,在 `` 组件的实例中:
-
-
-```html
-
-
-
-
-
-
-```
-
-
-如果我们需要通过 `data status` property 定义 `` 组件的状态,它将应用于根节点 (即 `div.date-picker`)。
-
-```html
-
-
-
-
-
-
-
-```
-
-同样的规则适用于事件监听器:
-
-```html
-
-```
-
-
-```js
-
- export default {
- created() {
- console.log(this.$attrs) // { onChange: () => {} }
- }
- }
-```
-
-当有一个 `HTML` 元素将 `change` 事件作为 `date-picker` 的根元素时,这可能会有帮助。
-
-
-```html
-
-
-
-
-```
-
-
-在这种情况下,`change` 事件监听器从父组件传递到子组件,它将在原生 `select` 的 `change` 事件上触发。我们不需要显式地从 `date-picker` 发出事件:
-
-
-```html
-
-
-
-
-
-
-```
-
-
-
-### 禁用 Attribute 继承
-
-
-如果你不希望组件的根元素继承 `attribute`,你可以在组件的选项中设置 `inheritAttrs: false`。例如:
-
-禁用 `attribute` 继承的常见情况是需要将 `attribute` 应用于根节点之外的其他元素。
-
-通过将 `inheritAttrs` 选项设置为 `false`,你可以访问组件的 `$attrs property`,该 `property` 包括组件 `props` 和 `emits property` 中未包含的所有属性 (例如,`class`、`style`、`v-on` 监听器等)。
-
-使用上一节中的 `date-picker` 组件示例,如果需要将所有非 prop attribute 应用于 `input` 元素而不是根 `div` 元素,则可以使用 `v-bind` 缩写来完成。
-
-
-```html
-
-
-
-
-
-
-```
-
-有了这个新配置,`data status` attribute 将应用于 `input` 元素!
-
-```js
-
-
-
-
-
-
-
-```
-
-
-### 多个根节点上的 Attribute 继承
-
-与单个根节点组件不同,具有多个根节点的组件不具有自动 `attribute` 回退行为。如果未显式绑定 `$attrs`,将发出运行时警告。
-
-
-```html
-
-```
-
-```html
- // 我是custom-layout组件
- // 这将发出警告
-
-
- ...
-
-
-
- // 没有警告,$attrs被传递到元素
-
-
-
- ...
-
-
-
-```
-
-
-## 自定义事件
-
-### 事件名
-
-不同于组件和 `prop`,事件名不存在任何自动化的大小写转换。而是触发的事件名需要完全匹配监听这个事件所用的名称。举个例子,如果触发一个 `camelCase` (驼峰命名法) 名字的事件:
-
-```js
- this.$emit('myEvent')
-```
-
-
-则监听这个名字的 `kebab-case` (短横线隔开式) 版本是不会有任何效果的:
-
-```html
-
-
-```
-
-
-不同于组件和 `prop`,事件名不会被用作一个 `JavaScript` 变量名或 `property` 名,所以就没有理由使用 `camelCase` (驼峰命名法) 或 `PascalCase`(帕斯卡命名法) 了。并且 `v-on` 事件监听器在 `DOM` 模板中会被自动转换为全小写 (因为 `HTML` 是大小写不敏感的),所以 `@myEvent` 将会变成 `@myevent`——导致 `myEvent` 不可能被监听到。
-
-因此,我们推荐你始终使用 `kebab-case` (短横线隔开式) 的事件名。
-
-
-### 定义自定义事件
-
-可以通过 `emits` 选项在组件上定义已发出的事件。
-
-```js
- // 在组件内
- export default {
- emits: ['in-focus', 'submit']
- }
-```
-
-当在 `emits` 选项中定义了原生事件 (如 `click`) 时,将使用组件中的事件替代原生事件侦听器。
-
-
-> 建议定义所有发出的事件,以便更好地记录组件应该如何工作。
-
-
-示例
-
-```html
-
-
-
- counter的值是:{{count}}
-
-
-
-
-```
-
-
-```html
-
-
-
-
-
-
-
-
-```
-
-
-
-**验证抛出的事件**
-
-
-与 `prop` 类型验证类似,如果使用对象语法而不是数组语法定义发出的事件,则可以验证它。
-
-要添加验证,将为事件分配一个函数,该函数接收传递给 `$emit` 调用的参数,并返回一个布尔值以指示事件是否有效。
-
-
-```js
- export default {
- emits: {
- // 没有验证
- click: null,
-
- // 验证submit 事件
- submit: ({ email, password }) => {
- if (email && password) {
- return true
- } else {
- console.warn('Invalid submit event payload!')
- return false
- }
- }
- },
- methods: {
- submitForm() {
- this.$emit('submit', { email, password })
- }
- }
- }
-```
-
-
-
-
-
-### v-model 参数
-
-
-默认情况下,组件上的 `v-model` 使用 `modelValue` 作为 `prop` 和 `update:modelValue` 作为事件。我们可以通过向 `v-model` 传递参数来修改这些名称:
-
-
-```html
-
-```
-
-
-在本例中,子组件将需要一个 foo prop 并发出 `update:foo` 要同步的事件:
-
-
-```html
-
-
-
-
-
-
-```
-
-```html
-
-```
-
-**示例**
-
-```html
-
-
- 父组件-count的值是:{{count}}
-
-
-
-
-
-```
-
-
-```html
-
-
-
- 子组件-count的值是:{{number}}
-
-
-
-
-```
-
-
-
-### 多个 v-model 绑定
-
-通过利用以特定 `prop` 和事件为目标的能力,正如我们之前在 `v-model` 参数中所学的那样,我们现在可以在单个组件实例上创建多个 `v-model` 绑定。
-
-每个 `v-model` 将同步到不同的 `prop`,而不需要在组件中添加额外的选项:
-
-```html
-
-
-
-
-
-
-
-```
-
-```html
-
-
-
-
-
-
-
-
-```
-
-
-### 处理 v-model 修饰符
-
-
-让我们创建一个示例自定义修饰符 `capitalize`,它将 `v-model` 绑定提供的字符串的第一个字母大写。
-
-添加到组件 `v-model` 的修饰符将通过 `modelModifiers` prop 提供给组件。在下面的示例中,我们创建了一个组件,其中包含默认为空对象的 `modelModifiers` prop。
-
-请注意,当组件的 created 生命周期钩子触发时,`modelModifiers` prop 包含 `capitalize`,其值为 `true`——因为它被设置在 `v-model` 绑定 `v-model.capitalize="bar"`。
-
-
-```html
-
-
-
-
-
-
-
-```
-
-
-
-```html
-
-
-
-
-
-
-
-```
-
-
-对于带参数的 `v-model` 绑定,生成的 `prop` 名称将为 `arg + "Modifiers"`:
-
-
-```html
-
-```
-
-
-```html
-
-
-
-
-
-
-
-```
-
-
-## 插槽
-
-
-### 插槽内容
-
-
-Vue 实现了一套内容分发的 API,这套 API 的设计灵感源自 [Web Components 规范草案](https://github.com/WICG/webcomponents/blob/gh-pages/proposals/Slots-Proposal.md),将 `` 元素作为承载分发内容的出口。
-
-
-它允许你像这样合成组件:
-
-```html
-
- Add todo
-
-```
-
-
-然后在 `todo-button` 的模板中,你可能有:
-
-```html
-
-
-```
-
-
-当组件渲染的时候,将会被替换为`“Add Todo”`。
-
-```html
-
-
-```
-
-
-不过,字符串只是开始!插槽还可以包含任何模板代码,包括 `HTML`:
-
-```html
-
-
-
- Add todo
-
-```
-
-或其他组件
-
-```html
-
-
-
- Add todo
-
-```
-
-如果 `todo-button` 的 `template` 中没有包含一个 `slot` 元素,则该组件起始标签和结束标签之间的任何内容都会被抛弃
-
-```html
-
-
-```
-
-```html
-
-
- Add todo
-
-```
-
-
-### 渲染作用域
-
-
-当你想在一个插槽中使用数据时,例如:
-
-```html
-
- Delete a {{ item.name }}
-
-```
-
-
-该插槽可以访问与模板其余部分相同的实例 `property` (即相同的“作用域”)。
-
-![](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-a90b5f95-90ba-4d30-a6a7-cd4d057327db/710a2056-a06a-4bb2-8c5d-b13ddef16968.png)
-
-
-插槽不能访问 `todo-button` 的作用域。例如,尝试访问 `action` 将不起作用:
-
-```html
-
- Clicking here will {{ action }} an item
-
-
-```
-
-
-作为一条规则,请记住:
-**父级模板里的所有内容都是在父级作用域中编译的;子模板里的所有内容都是在子作用域中编译的。**
-
-
-### 后备内容
-
-有时为一个插槽设置具体的后备 (也就是默认的) 内容是很有用的,它只会在没有提供内容的时候被渲染。例如在一个 `submit-button` 组件中:
-
-```html
-
-```
-
-我们可能希望这个 `button` 内绝大多数情况下都渲染文本`“Submit”`。为了将`“Submit”`作为后备内容,我们可以将它放在 `slot` 标签内:
-
-```html
-
-```
-
-
-现在当我在一个父级组件中使用 `submit-button` 并且不提供任何插槽内容时:
-
-```html
-
-```
-
-后备内容“Submit”将会被渲染:
-
-```html
-
-```
-
-但是如果我们提供内容:
-
-```html
-
- Save
-
-```
-
-则这个提供的内容将会被渲染从而取代后备内容:
-
-```html
-
-```
-
-
-### 具名插槽
-
-
-有时我们需要多个插槽。例如对于一个带有如下模板的 `base-layout` 组件:
-
-```html
-
-
-
-
-
-
-
-
-```
-
-对于这样的情况,`slot` 元素有一个特殊的 `attribute:name`。这个 `attribute` 可以用来定义额外的插槽:
-
-```html
-
-
-
-
-
-
-
-```
-
-**一个不带 `name` 的 `slot` 出口会带有隐含的名字`“default”`。**
-
-在向具名插槽提供内容的时候,我们可以在一个 `template` 元素上使用 `v-slot` 指令,并以 `v-slot` 的参数的形式提供其名称:
-
-```html
-
-
-
-
-
- Here might be a page title
-
-
- A paragraph for the main content.
- And another one.
-
-
- Here's some contact info
-
-
-
-
-```
-
-现在 `template` 元素中的所有内容都将会被传入相应的插槽。
-
-渲染的 `HTML` 将会是:
-
-```html
-
-
-
- A paragraph for the main content.
- And another one.
-
-
-
-```
-
-
-注意,`v-slot` 只能添加在 `template` 上 (只有一种例外情况)
-
-
-#### 具名插槽的缩写
-
-跟 `v-on` 和 `v-bind` 一样,`v-slot` 也有缩写,即把参数之前的所有内容 (v-slot:) 替换为字符 **#**。例如 `v-slot:header` 可以被重写为 `#header`:
-
-
-```html
-
-
- Here might be a page title
-
-
-
- A paragraph for the main content.
- And another one.
-
-
-
- Here's some contact info
-
-
-```
-
-
-然而,和其它指令一样,该缩写只在其有参数的时候才可用。这意味着以下语法是无效的:
-
-```html
-
-
-
- {{ item }}
-
-```
-
-
-如果你希望使用缩写的话,你必须始终以明确插槽名取而代之:
-
-```html
-
-
- {{ item }}
-
-```
-
-
-
-### 作用域插槽
-
-有时让插槽内容能够访问子组件中才有的数据是很有用的。当一个组件被用来渲染一个项目数组时,这是一个常见的情况,我们希望能够自定义每个项目的渲染方式。
-
-例如,我们有一个组件,包含 `todo-items` 的列表。
-
-```html
-
-
-
- {{ item }}
-
-
-
-
-```
-
-
-我们可能需要替换插槽以在父组件上自定义它:
-
-```html
-
- before--
- {{ item }}
-
-```
-
-但是,这是行不通的,因为只有 `todo-list` 组件可以访问 `item`,我们将从其父组件提供槽内容。
-
-要使 `item` 可用于父级提供的 `slot` 内容,我们可以添加一个 `slot` 元素并将其绑定为属性:
-
-
-```html
-
-
-
-
-
-
-
-
-```
-
-
-绑定在 `slot` 元素上的 `attribute` 被称为**插槽 prop**。现在在父级作用域中,我们可以使用带值的 `v-slot` 来定义我们提供的插槽 `prop` 的名字:
-
-
-```html
-
-
-
-
-
- {{ slotProps.item }}
-
-
-
-
-```
-
-![](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-a90b5f95-90ba-4d30-a6a7-cd4d057327db/facb2e6a-b7b5-4571-b7cf-4b3c545de8a9.png)
-
-在这个例子中,我们选择将包含所有插槽 `prop` 的对象命名为 `slotProps`,但你也可以使用任意你喜欢的名字。
-
-
-#### 独占默认插槽的缩写语法
-
-在上述情况下,当被提供的内容只有默认插槽时,组件的标签才可以被当作插槽的模板来使用。这样我们就可以把 `v-slot` 直接用在组件上:
-
-```html
-
-
- {{ slotProps.item }}
-
-```
-
-
-这种写法还可以更简单。就像假定未指明的内容对应默认插槽一样,不带参数的 `v-slot` 被假定对应默认插槽:
-
-```html
-
-
- {{ slotProps.item }}
-
-```
-
-注意**默认插槽的缩写语法不能和具名插槽混用**,因为它会导致作用域不明确:
-
-```html
-
-
-
-
- {{ slotProps.item }}
-
-
- slotProps is NOT available here
-
-
-```
-
-只要出现多个插槽,请始终为所有的插槽使用完整的基于 `template` 的语法:
-
-```html
-
-
-
- {{ slotProps.item }}
-
-
-
- ...
-
-
-```
-
-
-#### 解构插槽 Prop
-
-作用域插槽的内部工作原理是将你的插槽内容包括在一个传入单个参数的函数里:
-
-```js
-function (slotProps) {
- // ... 插槽内容 ...
-}
-```
-
-这意味着 `v-slot` 的值实际上可以是任何能够作为函数定义中的参数的 `JavaScript` 表达式。你也可以使用 [ES2015](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Object_destructuring) 解构来传入具体的插槽 `prop`,如下:
-
-```html
-
-
- {{ item }}
-
-```
-
-这样可以使模板更简洁,尤其是在该插槽提供了多个 `prop` 的时候。它同样开启了 `prop` 重命名等其它可能,例如将 `item` 重命名为 `todo`:
-
-```html
-
-
- {{ todo }}
-
-```
-
-你甚至可以定义后备内容,用于插槽 `prop` 是 `undefined` 的情形:
-
-```html
-
-
- {{ item }}
-
-```
-
-## 命名限制
-
-在 uni-app 中以下这些作为保留关键字,不可作为组件名。
-
-- `a`
-- `canvas`
-- `cell`
-- `content`
-- `countdown`
-- `datepicker`
-- `div`
-- `element`
-- `embed`
-- `header`
-- `image`
-- `img`
-- `indicator`
-- `input`
-- `link`
-- `list`
-- `loading-indicator`
-- `loading`
-- `marquee`
-- `meta`
-- `refresh`
-- `richtext`
-- `script`
-- `scrollable`
-- `scroller`
-- `select`
-- `slider-neighbor`
-- `slider`
-- `slot`
-- `span`
-- `spinner`
-- `style`
-- `svg`
-- `switch`
-- `tabbar`
-- `tabheader`
-- `template`
-- `text`
-- `textarea`
-- `timepicker`
-- `transition-group`
-- `transition`
-- `video`
-- `view`
-- `web`
-
-
-Tips
-- 除以上列表中的名称外,标准的 HTML 及 SVG 标签名也不能作为组件名。
-- methods中不可使用与生命周期同名的方法名。
\ No newline at end of file
diff --git a/docs/vue3-vuex.md b/docs/vue3-vuex.md
index 6ef563d1c8ed4a98c0b20af7a07f48d0bde1c97d..dce95afe6163981738a7182219224e6ffc8e339b 100644
--- a/docs/vue3-vuex.md
+++ b/docs/vue3-vuex.md
@@ -1,5 +1,5 @@
-# 状态管理Vuex
+
> 这是与 Vue 3 匹配的 Vuex 4 的文档。差异对比可参阅[从 3.x 迁移到 4.0](https://next.vuex.vuejs.org/zh/guide/migrating-to-4-0-from-3-x.html)
>
@@ -7,78 +7,11 @@
-## 介绍
-
-
-### Vuex 是什么?
-
-Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
uni-app 内置了 [Vuex](https://vuex.vuejs.org/zh/) 。
-### 什么是“状态管理模式”?
-
-让我们从一个简单的 Vue 计数应用开始:
-
-
-```html
-
-
-
- {{count}}
-
-
-
-```
-
-
-这个状态自管理应用包含以下几个部分:
-
-- state,驱动应用的数据源;
-- view,以声明方式将 state 映射到视图;
-- actions,响应在 view 上的用户输入导致的状态变化。
-
-以下是一个表示“单向数据流”理念的简单示意:
-
-
-
-
-
-
-但是,当我们的应用遇到**多个组件共享状态**时,单向数据流的简洁性很容易被破坏:
-
-- 多个视图依赖于同一状态。
-- 来自不同视图的行为需要变更同一状态。
-
-因此,我们把组件的共享状态抽取出来,以一个全局单例模式管理。在这种模式下,我们的组件树构成了一个巨大的“视图”,不管在树的哪个位置,任何组件都能获取状态或者触发行为!这就是vuex的产生。
-
-通过定义和隔离状态管理中的各种概念并通过强制规则维持视图和状态间的独立性,我们的代码将会变得更结构化且易维护。这就是 Vuex 背后的基本思想。
-
-
-Vuex 是专门为 Vue.js 设计的状态管理库,以利用 Vue.js 的细粒度数据响应机制来进行高效的状态更新。
-
-
-
-
-
-如果你想交互式地学习 Vuex,可以看这个 [Scrimba 上的 Vuex 课程](https://scrimba.com/learn/vuex),它将录屏和代码试验场混合在了一起,你可以随时暂停并尝试。
@@ -149,46 +82,10 @@ Vuex 是专门为 Vue.js 设计的状态管理库,以利用 Vue.js 的细粒
-## 核心概念
-
-
-每一个 `Vuex` 应用的核心就是 `store`(仓库),它包含着你的应用中大部分的状态 (`state`)。
-
-状态管理有5个核心:`state`、`getter`、`mutation`、`action`、`module`。
-
-
-
-### State
单一状态树,定义应用状态的默认初始值,页面显示所需的数据从该对象中进行读取。
-- `Vuex` 使用单一状态树,用一个对象就包含了全部的应用层级状态。它便作为一个“唯一数据源”而存在。这也意味着,每个应用将仅仅包含一个 store 实例。
-- 单一状态树让我们能够直接地定位任一特定的状态片段,在调试的过程中也能轻易地取得整个当前应用状态的快照。
-- 不可直接对 `state` 进行更改,需要通过 `Mutation` 方法来更改。
-
-
-由于 `Vuex` 的状态存储是响应式的,从 `store` 实例中读取状态最简单的方法就是在计算属性中返回某个状态:
-
-```js
-// 创建一个 Counter 组件
-const Counter = {
- computed: {
- count () {
- return store.state.count
- }
- }
-}
-```
-
-
-每当 `store.state.count` 变化的时候, 都会重新求取计算属性,并且触发更新相关联的 DOM。
-
-然而,这种模式导致组件依赖全局状态单例。在模块化的构建系统中,在每个需要使用 `state` 的组件中需要频繁地导入,并且在测试组件时需要模拟状态。
-
-
-
-Vuex 通过 store 选项,提供了一种机制将状态从根组件“注入”到每一个子组件中(需调用 Vue.use(Vuex)):
1.在 `uni-app` 项目根目录下,新建 `store` 目录,在此目录下新建 `index.js` 文件。在 `index.js` 文件配置如下:
@@ -209,19 +106,7 @@ export default store
2.在 `main.js` 中导入文件。
-```js
-
-import App from './App'
-import store from './store'
-import {createSSRApp} from 'vue'
-export function createApp() {
- const app = createSSRApp(App)
- app.use(store)
- return {
- app
- }
-}
-```
+
**获取state**
@@ -278,120 +163,6 @@ export function createApp() {
3.通过 `mapState` 辅助函数获取。
-当一个组件需要获取多个状态的时候,将这些状态都声明为计算属性会有些重复和冗余。
-为了解决这个问题,我们可以使用 **mapState 辅助函数** 帮助我们生成计算属性,让你少按几次键:
-
-
-```html
-
-
-
- 用户名:{{username}}
- 年龄:{{age}}
-
-
-
-```
-
-
-- 当映射的计算属性的名称与 `state` 的子节点名称相同时,我们也可以给 `mapState` 传一个字符串数组。
-
-```html
-
-
-
- 用户名:{{username}}
- 年龄:{{age}}
-
-
-
-```
-
-
-- 为了能够使用 `this` 获取组件自己的data数据,必须使用常规函数。
-
-```html
-
-
-
- 用户名:{{username}}
- 年龄:{{age}}
-
-
-
-```
-
-
-- 使用对象展开运算符
-
-`mapState` 函数返回的是一个对象。使用对象展开运算符将多个对象合并为一个,以使我们可以将最终对象传给 `computed` 属性。极大地简化写法:
-
-```html
-
-
-
- 用户名:{{username}}
- 年龄:{{age}}
-
-
-
-```
-
-
### Getter
@@ -403,32 +174,6 @@ export function createApp() {
在 `uni-app` 项目根目录下,`store` 目录 `index.js` 文件下:
-```js
-
-import { createStore } from 'vuex'
-const store = createStore({
- state: {
- todos: [{
- id: 1,
- text: '我是内容一',
- done: true
- },
- {
- id: 2,
- text: '我是内容二',
- done: false
- }
- ]
- },
- getters: {
- doneTodos: state => {
- return state.todos.filter(todo => todo.done)
- }
- }
-})
-export default store
-```
-
在 `store` 上注册 `getter`,`getter` 方法接受以下参数:
@@ -475,54 +220,99 @@ export default store
**获取getters**
-1.通过属性访问,`Getter` 会暴露为 `store.getters` 对象,你可以以属性的形式访问这些值。
+
+2.通过 `this.$store` 访问。
+
+
+
+
+4.通过 `mapGetters` 辅助函数访问。
+
+
+
+
+
+
+
+
+通俗的理解,`mutations` 里面装着改变数据的方法集合,处理数据逻辑的方法全部放在 `mutations` 里,使数据和视图分离。
+
+
+
+**注意**:`store.commit` 调用 `mutation`(需要在根节点注入 store)。
+
+
+
+
+
+**传入参数**
+
+
+还是以累加器的例子来实现 `mutation` 函数的传参,来动态定义累加的数量。
+
+
+- 在 `mutation` 传参(载荷)可以传递一个参数。
+
+
+
+- 在 `mutation` 传参(载荷)可以也可以传递一个对象。让我们修改上面累加器的例子:
+
+
+`
+
```html
-
-
- {{item.id}}
- {{item.text}}
- {{item.done}}
-
+
+ 数量:{{count }}
+
```
-注意,`getter` 在通过属性访问时是作为 `Vue` 的响应式系统的一部分缓存其中的。
-
+**提交方式**
-2.通过 `this.$store` 访问。
```html
-
-
- {{item.id}}
- {{item.text}}
- {{item.done}}
-
+
+ 数量:{{count }}
+
@@ -558,700 +353,36 @@ export default store
-#### mapGetters
-4.通过 `mapGetters` 辅助函数访问。
-`mapGetters` 辅助函数仅仅是将 `store` 中的 `getter` 映射到局部计算属性:
+我们要通过提交 `mutation` 的方式来改变状态数据,是因为我们想要更明确地追踪到状态的变化。如果是类似下面这样异步的话:
-```html
-
-
-
- {{doneTodosCount}}
-
-
-
-```
-
-
-如果你想将一个 `getter` 属性另取一个名字,使用对象形式:
-
-```html
-
-
-
- {{doneCount}}
-
-
-
-```
-
-
-
-
-### Mutation
-
-
-**Vuex中store数据改变的唯一方法就是mutation**
-
-
-通俗的理解,`mutations` 里面装着改变数据的方法集合,处理数据逻辑的方法全部放在 `mutations` 里,使数据和视图分离。
-
-Vuex 中的 `mutation` 非常类似于事件:每个 `mutation` 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 `state` 作为第一个参数:
-
-
-```js
-
-import { createStore } from 'vuex'
-const store = createStore({
- state: {
- count: 1
- },
- mutations: {
- add(state) {
- // 变更状态
- state.count += 2
- }
- }
-})
-export default store
-```
-
-
-你不能直接调用一个 mutation handler。这个选项更像是事件注册:“当触发一个类型为 add 的 `mutation` 时,调用此函数”,要唤醒一个 mutation handler,你需要以相应的 type 调用 `store.commit` 方法。
-
-
-**注意**:`store.commit` 调用 `mutation`(需要在根节点注入 store)。
-
-```html
-
-
-
- 数量:{{count}}
-
-
-
-
-```
-
-
-
-**传入参数**
-
-你可以向 `store.commit` 传入额外的参数,即 `mutation` 的 载荷(payload):
-
-还是以累加器的例子来实现 `mutation` 函数的传参,来动态定义累加的数量。
-
-
-- 在 `mutation` 传参(载荷)可以传递一个参数。
-
-```js
-
-import { createStore } from 'vuex'
-const store = createStore({
- state: {
- count: 1
- },
- mutations: {
- add(state, n) {
- state.count += n
- }
- }
-})
-export default store
-```
-
-
-```html
-
-
-
- 数量:{{count }}
-
-
-
-
-```
-
-- 在 `mutation` 传参(载荷)可以也可以传递一个对象。让我们修改上面累加器的例子:
-
-
-```js
-
-import { createStore } from 'vuex'
-const store = createStore({
- state: {
- count: 1
- },
- mutations: {
- add(state, payload) {
- state.count += payload.amount
- }
- }
-})
-export default store
-```
-
-
-```html
-
-
-
- 数量:{{count }}
-
-
-
-
-```
-
-
-**提交方式**
-
-
-1.对象风格的提交方式
-
-我们修改组件中 `store.commit` 提交方式:
-
-```html
-
-
-
- 数量:{{count }}
-
-
-
-
-```
-
-
-当使用对象风格的提交方式,整个对象都作为载荷传给 mutation 函数,因此 handler 保持不变:
-
-```js
- mutations: {
- add(state, payload) {
- state.count += payload.amount
- }
- }
-```
-
-
-#### mapMutations
-
-2.通过 `mapMutations` 辅助函数提交。
-
-创建组件方法提交 `mutation`。
-
-使用 `mapMutations` 辅助函数将组件中的 `methods` 映射为 `store.commit` 调用(需要在根节点注入 `store`)。
-
-
-```html
-
-
-
- 数量:{{count}}
-
-
-
-
-```
-
-
-```js
-
-import { createStore } from 'vuex'
-const store = createStore({
- state: {
- count: 1
- },
- mutations: {
- add(state) {
- // 变更状态
- state.count += 2
- }
- }
-})
-export default store
-```
-
-
-
-**遵守规则**
-
-
-既然 `Vuex` 的 `store` 中的状态是响应式的,那么当我们变更状态时,监视状态的 `Vue` 组件也会自动更新。这也意味着 `Vuex` 中的 `mutation` 也需要与使用 `Vue` 一样遵守一些注意事项:
-
-- 最好提前在你的 `store` 中初始化好所有所需属性。
-
-- 当需要在对象上添加新属性时,你应该
-
- - 使用 `Vue.set(obj, 'newProp', 123)`, 或者
-
- - 以新对象替换老对象。例如,利用对象展开运算符我们可以这样写:
-
-```js
- state.obj = { ...state.obj, newProp: 123 }
-```
-
-
-
-**Mutation 必须是同步函数**
-
-一条重要的原则就是要记住** mutation 必须是同步函数**
-
-我们要通过提交 `mutation` 的方式来改变状态数据,是因为我们想要更明确地追踪到状态的变化。如果是类似下面这样异步的话:
-
-
-```js
- mutations: {
- someMutation (state) {
- api.callAsyncMethod(() => {
- state.count++
- })
- }
- }
-```
我们就不知道什么时候状态会发生改变,所以也就无法追踪了,这与 `mutation` 的设计初心相悖,所以强制规定它必须是同步函数。
-### Action
-
-
-`action` 类似于 `mutation` ,不同在于:
-
-- action 提交的是 `mutation`,通过 `mutation` 来改变 `state` ,而不是直接变更状态。
-- action 可以包含任意异步操作。
-
-
-让我们来注册一个简单的 `action` :
-
-```js
-
-import { createStore } from 'vuex'
-const store = createStore({
- state: {
- count: 1
- },
- mutations:{
- add(state) {
- // 变更状态
- state.count += 2
- }
- },
- actions:{
- addCountAction (context) {
- context.commit('add')
- }
- }
-})
-export default store
-```
-`action` 函数接受一个与 `store` 实例具有相同方法和属性的 `context` 对象,因此你可以调用 `context.commit` 提交一个 `mutation`,或者通过 `context.state` 和 `context.getters` 来获取 `state` 和 `getters`。
-实践中,我们会经常用到 ES2015 的参数解构来简化代码(特别是我们需要调用 `commit` 很多次的时候):
-```js
- actions: {
- //参数解构
- addCountAction ({commit}) {
- commit('add')
- }
- }
-```
-
-
-
-
-**分发 Action**
-
-1.`actions` 通过 `store.dispatch` 方法触发。
-
-```html
-
-
-
- 数量:{{count}}
-
-
-
-
-
-```
-
-
-
-- `actions` 支持以载荷形式分发:
-
-
-```js
-
-import { createStore } from 'vuex'
-const store = createStore({
- state: {
- count: 1
- },
- mutations:{
- add(state, payload) {
- state.count += payload.amount
- }
- },
- actions:{
- addCountAction (context , payload) {
- context.commit('add',payload)
- }
- }
-})
-export default store
-```
-
-
-```html
-
-
-
- 数量:{{count }}
-
-
-
-
-```
-
-
-- `actions` 支持以对象形式分发:
-
-```js
- methods: {
- add () {
- // 以对象形式分发
- store.dispatch({
- type: 'addCountAction',
- amount: 5
- })
- }
- }
-```
-
-
-
-`action` 可以执行任意的同步和异步操作
-
-我们可以在 `action` 内部执行异步操作:
-
-
-```js
-
-import { createStore } from 'vuex'
-const store = createStore({
- state: {
- count: 1
- },
- mutations:{
- add(state) {
- // 变更状态
- state.count += 2
- }
- },
- actions:{
- addCountAction (context) {
- //在执行累加的时候,会等待两秒才执行
- setTimeout(function () {
- context.commit('add')
- }, 2000)
- }
- }
-})
-export default store
-```
-
-
-来看一个更加实际的购物车示例,涉及到**调用异步 API** 和**分发多重 mutation**:
-
-
-```js
- actions: {
- checkout ({ commit, state }, products) {
- // 把当前购物车的物品备份起来
- const savedCartItems = [...state.cart.added]
- // 发出结账请求,然后乐观地清空购物车
- commit(types.CHECKOUT_REQUEST)
- // 购物 API 接受一个成功回调和一个失败回调
- shop.buyProducts(
- products,
- // 成功操作
- () => commit(types.CHECKOUT_SUCCESS),
- // 失败操作
- () => commit(types.CHECKOUT_FAILURE, savedCartItems)
- )
- }
- }
-```
-
-注意我们正在进行一系列的异步操作,并且通过提交 `mutation` 来记录 `action` 产生的状态变更。
-
-
-#### mapActions
-
2.通过 `mapActions` 辅助函数分发。
-创建组件方法分发 `action`。
-
-- 你在组件中使用 `this.$store.dispatch('xxx')` 分发 `action`
-- 或者使用 `mapActions` 辅助函数将组件的 `methods` 映射为 `store.dispatch` 调用(需要先在根节点注入 `store` )
-
-
-```html
-
-
-
- 数量:{{count }}
-
-
-
-
-
-```
- `mapActions` 也支持传入参数(载荷):
-```js
- methods: {
- ...mapActions([
- 'addCountAction'
- // 将 `this.addCountAction(amount)` 映射为
- //`this.$store.dispatch('addCountAction', amount)`
- ]),
- }
-```
-
-- `mapActions` 也支持传递一个对象:
-
-```js
- methods: {
- ...mapActions({
- addCount: 'addCountAction',
- // 将 `this.addCount()` 映射为 `this.$store.dispatch('addCountAction')`
- })
- }
-```
-
-**组合 Action**
-
-
-`action` 通常是异步的,那么如何知道 `action` 什么时候结束呢?更重要的是,我们如何才能组合多个 `action`,以处理更加复杂的异步流程?
-
-首先,你需要明白 `store.dispatch` 可以处理被触发的 `action` 的处理函数返回的 `Promise`,并且 `store.dispatch` 仍旧返回 `Promise` :
-
-
-```js
- actions: {
- actionA ({ commit }) {
- return new Promise((resolve, reject) => {
- setTimeout(() => {
- commit('someMutation')
- resolve()
- }, 1000)
- })
- }
- }
-```
-
-现在你可以在组件中使用:
-
-```js
- store.dispatch('actionA').then(() => {
- // ...
- })
-```
-
-
-在另外一个 `action` 中也可以:
-
-
-```js
- actions: {
- // ...
- actionB ({ dispatch, commit }) {
- return dispatch('actionA').then(() => {
- commit('someOtherMutation')
- })
- }
- }
-```
-
-
-最后,如果我们利用 `async / await`,我们可以如下组合 `action` :
-
-
-```js
- // 假设 getData() 和 getOtherData() 返回的是 Promise
- actions: {
- async actionA ({ commit }) {
- commit('gotData', await getData())
- },
- async actionB ({ dispatch, commit }) {
- await dispatch('actionA') // 等待 actionA 完成
- commit('gotOtherData', await getOtherData())
- }
- }
-```
-
-
-> 一个 `store.dispatch` 在不同模块中可以触发多个 `action` 函数。在这种情况下,只有当所有触发函数完成后,返回的 `Promise` 才会执行。
+- `mapActions` 也支持传递一个对象:
-### Module
-由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,`store` 对象就有可能变得相当臃肿。
-为了解决以上问题,`Vuex` 允许我们将 `store` 分割成模块(module)。每个模块拥有自己的 `state`、`mutation`、`action`、`getter`、甚至是嵌套子模块——从上至下进行同样方式的分割:
1.在 `store` 文件夹下新建 `modules` 文件夹,并在下面新建 `moduleA.js` 和 `moduleB.js` 文件用来存放 `vuex` 的 `modules` 模块。