Vue3使用及用在uni-app小程序开发

Vue3的优点

Vue3 相对于 Vue2 主要有以下优点:

  1. 性能优化:Vue3 通过重新设计了响应式系统,提高了性能。新的编译器和虚拟 DOM 的优化也带来了更高的性能表现。
  2. Composition API:Vue3 引入了 Composition API,可以让开发者更灵活地组织和重用组件逻辑,代码结构更清晰,复用性更高。
  3. TypeScript 支持:Vue3 对 TypeScript 的支持更加友好,可以更好地利用 TypeScript 的优势进行开发和维护。
  4. 更小的包体积:Vue3 的核心体积更小,加载速度更快,减少了对网络带宽的占用。
  5. 更灵活的响应式数据处理:Vue3 提供了更多的选项和方式来处理响应式数据,使得数据处理更加灵活和高效。

总的来说,Vue3 在性能、开发体验以及可维护性上都有很大的提升,是一个更为强大和现代化的前端框架。

选项式 API和组合式 API

Vue3的组件可以按两种不同的风格书写:选项式 API组合式 API

我的选择策略是:

如果使用的框架有组合式 API,那就用组合式API。

个人还是习惯使用选项式 API,网上查资料的时候大多都是选项式 API

选项式 API

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<script>
export default {
data() {
return {
title: 'Hello'
}
},
onLoad() {

},
methods: {

}
}
</script>

组合式API

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<script setup>
import {
ref
} from "vue";
import {
onLoad,
onShow
} from "@dcloudio/uni-app";
const title = ref("Hello");
onLoad((option) => {
console.log("onLoad:", option);
title.value = "你好";
});

onShow(() => {
console.log("onShow");
});
</script>

模块导入/导出

导入

1
2
3
4
5
// 之前 - Vue 2, 使用 commonJS
var utils = require("../../../common/util.js");

// 之后 - Vue 3, 只支持 ES6 模块
import utils from "../../../common/util.js";

导出

1
2
3
4
5
// 之前 - Vue 2, 依赖如使用 commonJS 方式导出
module.exports.X = X;

// 之后 - Vue 3, 只支持 ES6 模块
export default { X };

Props 声明

1
2
3
4
5
6
7
8
<script setup>
const props = defineProps({
title: String,
likes: Number
});

console.log(props.title)
</script>

事件

1
2
3
4
5
6
7
<script setup>
const emit = defineEmits(['inFocus', 'submit'])

function buttonClick() {
emit('submit')
}
</script>

双向绑定

从 Vue 3.4 开始,推荐的实现方式是使用 defineModel() 宏:

1
2
3
4
5
6
7
8
9
10
11
12
13
<!-- Child.vue -->
<script setup>
const model = defineModel()

function update() {
model.value++
}
</script>

<template>
<div>Parent bound v-model is: {{ model }}</div>
<button @click="update">Increment</button>
</template>

父组件可以用 v-model 绑定一个值:

1
2
<!-- Parent.vue -->
<Child v-model="countModel" />

defineModel() 返回的值是一个 ref。它可以像其他 ref 一样被访问以及修改,不过它能起到在父组件和当前变量之间的双向绑定的作用:

  • 它的 .value 和父组件的 v-model 的值同步;
  • 当它被子组件变更了,会触发父组件绑定的值一起更新。

插槽

组件

1
2
3
4
5
6
7
8
9
10
11
<div class="container">
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>

使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<BaseLayout>
<template #header>
<h1>Here might be a page title</h1>
</template>

<template #default>
<p>A paragraph for the main content.</p>
<p>And another one.</p>
</template>

<template #footer>
<p>Here's some contact info</p>
</template>
</BaseLayout>

当一个组件同时接收默认插槽和具名插槽时,所有位于顶级的非 <template> 节点都被隐式地视为默认插槽的内容。

所以上面也可以写成:

1
2
3
4
5
6
7
8
9
10
11
12
13
<BaseLayout>
<template #header>
<h1>Here might be a page title</h1>
</template>

<!-- 隐式的默认插槽 -->
<p>A paragraph for the main content.</p>
<p>And another one.</p>

<template #footer>
<p>Here's some contact info</p>
</template>
</BaseLayout>

全局变量

Vue 3 引入了 provide 和 inject 功能,使得在父子组件之间传输依赖变得简单。

通过这种方式,您可以在父组件中使用 provide 提供全局变量,然后子组件中使用 inject 来接收和访问这个全局变量。

在父组件中:

1
2
3
4
const appProvide = {
myGlobalVar: '这是全局变量'
}
app.provide(appProvide)

在子组件中:

1
const { myGlobalVar } = inject('appProvide')

组合式API使用VUEX

在 Vue 3 中,Vuex 4 提供了对组合式 API 的支持,使您可以在组合式 API 中使用 Vuex 来管理应用程序的状态。以下是使用组合式 API 和 Vuex 的基本步骤:

安装 Vuex
首先,确保您的项目安装了 Vuex 4.x 版本。可以通过 npm 或者 yarn 安装:

1
2
3
npm install vuex@next
# 或者
yarn add vuex@next

创建 Vuex Store
在您的项目中创建一个 Vuex store。在 Vuex 4 中,可以直接使用组合式 API 来编写 store。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// src/store/index.js
import { createStore } from 'vuex'

const store = createStore({
state: {
count: 0
},
mutations: {
increment(state) {
state.count++
}
},
actions: {
incrementAsync({ commit }) {
setTimeout(() => {
commit('increment')
}, 1000)
}
}
})

export default store

在组件中使用 Vuex
使用组合式 API 的 useStore 函数可以在组件中访问到 Vuex 的 store。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// src/components/Counter.vue
<template>
<div>
<p>Count: {{ count }}</p>
<button @click="increment">Increment</button>
</div>
</template>

<script>
import { computed } from 'vue'
import { useStore } from 'vuex'

export default {
setup() {
const store = useStore()
const count = computed(() => store.state.count)

const increment = () => {
store.commit('increment')
}

return {
count,
increment
}
}
}
</script>

注意事项

  • 在组合式 API 中,通过 useStore 函数获取 store 对象,然后可以使用 store.state 访问状态,使用 store.commit 调用 mutations,使用 store.dispatch 调用 actions。
  • Vuex 的其它概念和用法(如 modules、getters 等)在组合式 API 中的使用方式与传统的 Vue 组件中基本一致,只是语法略有不同。

组合式API使用VUE Router

在 Vue 3 中,使用组合式 API 结合 Vue Router 来管理路由非常简单和直观。下面是如何在组合式 API 中使用 Vue Router 的基本步骤:

安装 Vue Router
首先,确保您的项目安装了 Vue Router。可以通过 npm 或者 yarn 安装:

1
2
3
npm install vue-router@next
# 或者
yarn add vue-router@next

创建和配置 Router
在您的项目中创建一个 Vue Router 实例,并配置路由。通常情况下,您需要创建一个路由配置文件并导出一个路由实例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// src/router/index.js
import { createRouter, createWebHistory } from 'vue-router'
import Home from '../views/Home.vue'
import About from '../views/About.vue'

const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/about',
name: 'About',
component: About
}
]

const router = createRouter({
history: createWebHistory(),
routes
})

export default router

在上面的例子中,我们使用了 createWebHistory 来创建一个基于浏览器 history 的路由模式,您也可以选择使用 createWebHashHistory 来创建基于 hash 的路由模式。

在组件中使用 Router
使用组合式 API 的 useRouter 函数可以在组件中访问到 Vue Router 的实例,并进行路由导航等操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// src/components/Navigation.vue
<template>
<nav>
<router-link to="/">Home</router-link>
<router-link to="/about">About</router-link>
</nav>
</template>

<script>
import { useRouter } from 'vue-router'

export default {
setup() {
const router = useRouter()

// 可以在此处定义处理路由导航的函数

return {
router
}
}
}
</script>

注意事项

  • 在组合式 API 中,通过 useRouter 函数获取 router 对象,然后可以使用 router.pushrouter.replace 等方法进行路由导航。
  • Vue Router 的其它概念和用法(如路由参数、路由守卫等)在组合式 API 中的使用方式与传统的 Vue 组件中基本一致,只是语法略有不同。