您现在的位置是:首页 >技术教程 >vue-router4、vuex4、Pinia网站首页技术教程
vue-router4、vuex4、Pinia
vue-router4
vue 升级 vue3 之后,配套的 vue-router 也升级为 vue-router@4.x 版本
vue-router4 的语法和 3 的版本语法基本一致,但是有一些细微的修改。
vue-router官网:Vue Router | The official Router for Vue.js/
vue@2 + vue-router@3 + vuex@3 options api
vue@3 + vue-router@4 + vuex@4 composition api
基本使用
(1) 安装 vue-router
npm i vue-router
# 或
yarn add vue-router
(2) 创建路由实例对象
router/index.js
// vue3 中,提倡函数式编程 =》 干啥事,都是调用函数
import {
createRouter,
createWebHashHistory,
createWebHistory,
} from 'vue-router'
// 创建路由对象
const router = createRouter({
// 创建 history 模式的路由
// history: createWebHistory(),
// 创建 hash 模式的路由
history: createWebHashHistory()
})
export default router
(3) 挂载路由实例对象
main.js
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
const app = createApp(App)
// 挂载 router
app.use(router)
app.mount('#app')
(4) 配置路由规则
router/index.js
const router = createRouter({
// 配置路由规则
routes: [
{ path: '/home', component: () => import('../views/Home.vue') },
{ path: '/login', component: () => import('../views/Login.vue') },
],
})
(5) 声明路由链接和路由占位符
App.vue
<template>
<ul>
<li>
<!-- 路由链接 -->
<router-link to="/home">首页</router-link>
</li>
<li>
<!-- 路由链接 -->
<router-link to="/login">登陆</router-link>
</li>
</ul>
<!-- 路由出口 -->
<router-view></router-view>
</template>
在组件中使用 route 与 router
由于组件中无法访问 this, 所以也无法使用 this.与router
(1)通过 useRoute() 可以获取 route 对象
<script setup>
import { useRoute } from 'vue-router'
const route = useRoute()
console.log(route.path)
console.log(route.query)
</script>
(2)通过 useRouter() 可以获取 router 对象
<script setup>
import { useRouter } from 'vue-router'
const router = useRouter()
const login = () => {
router.push('/home')
}
</script>
vuex4
基本使用
(1) 安装依赖包
npm i vuex
# 或
yarn add vuex
(2) 创建 store 实例对象
store/index.js
import { createStore } from 'vuex'
const store = createStore({
state: {
count: 0,
},
mutations: {
changeCount(state) {
state.count++
},
},
actions: {
changeCountAsync(ctx) {
setTimeout(() => {
ctx.commit('changeCount')
}, 1000)
},
},
getters: {},
modules: {}
})
export default store
(3) 挂载 store 实例对象
main.js
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
const app = createApp(App)
app.use(router)
app.use(store)
app.mount('#app')
在组件中使用 vuex
login.vue
<script setup>
import { useStore } from 'vuex'
const store = useStore()
// 注意:mapState mapMutations mapActions mapGetters 辅助函数 只能在 options api 中使用
</script>
<template>
<div>我是 login 组件 --- {{ store.state.count }}</div>
<button @click="store.commit('changeCount')">+1</button>
<button @click="store.dispatch('changeCountAsync')">1秒后+1</button>
</template>
总结:vuex4 在 vue3 项目中能用,但是不好用
Pinia
基本介绍
Pinia 是 Vue.js 的轻量级状态管理库
官方网站:Pinia | The intuitive store for Vue.js/
中文文档: 介绍 | Pinia 中文文档
为什么学习 pinia?
-
pinia 和 vuex4 一样,也是 vue 官方 状态管理工具(作者是 Vue 核心团队成员)
-
pinia 相比 vuex4,对于 vue3 的 兼容性 更好
-
pinia 相比 vuex4,具备完善的 类型推荐 => 对 TS 支持很友好
-
pinia 同样支持 vue 开发者工具
-
pinia 的 API 设计非常接近
Vuex5
的 提案,管理数据简单,提供数据和修改数据的逻辑即可,不像Vuex需要记忆太多的API,更加简单易用。
pinia 核心概念:
-
state: 状态
-
actions: 修改状态
-
getters: 计算属性
注意:
-
pinia 中没有 mutations,同步和异步的函数都写在 actions 中
-
pinia 中没有模块的概念:使用 pinia 时,会直接创建多个仓库,所以不需要再分模块了。vuex 中,只有一个仓库,所以需要在仓库下再分模块。
基本使用
目标:掌握 pinia 的使用步骤
(1) 安装
npm i pinia
# or
yarn add pinia
(2) 创建和挂载 pinia
main.js
import { createApp } from 'vue'
import App from './App.vue'
// 引入 createPinia
import { createPinia } from 'pinia'
// 创建 pinia
const pinia = createPinia()
const app = createApp(App)
// 挂载 pinia
app.use(pinia)
app.mount('#app')
具体使用
目标:在组件中使用 pinia
(1) 创建仓库
选项式 api
store/count.js
import { defineStore } from 'pinia'
// 仓库名称命名规则:useXxxxStore
// const 仓库名称 = defineStore('仓库标识', 选项式api)
const useCountStore = defineStore('count', {
state() {
return {
num: 1
}
},
// 在 pinia 中没有 mutations,只有 actions,不管是同步还是异步的代码,都可以在 actions 中完成。
actions: {
addNum() {
// this 指向当前仓库
this.num++
},
addNumAsync() {
setTimeout(() => {
this.num++
}, 1000)
}
},
getters: {
doubleNum() {
return this.num * 2
}
}
})
export default useCountStore
组合式 api
store/count.js
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
// 仓库名称命名规则:useXxxxStore
// const 仓库名称 = defineStore('仓库标识', 组合式api)
const useCountStore = defineStore('count', () => {
const num = ref(1)
const addNum = () => {
num.value++
}
const addNumAsync = () => {
setTimeout(() => {
num.value++
}, 1000)
}
const doubleNum = computed(() => {
return num.value * 2
})
return { num, addNum, addNumAsync, doubleNum }
})
export default useCountStore
(2) 在组件中使用
App.vue
<script setup>
// 引入仓库
import useCountStore from '../store/count'
// 调用仓库,得到仓库内容
const countStore = useCountStore()
</script>
<template>
<!-- 使用仓库中的数据和方法 -->
<h1>num 的值:{{ countStore.num }}</h1>
<h1>doubleNum 的值:{{ countStore.doubleNum }}</h1>
<button @click="countStore.addNum">+1</button>
<button @click="countStore.addNumAsync">1秒后+1</button>
</template>
storeToRefs 的使用
目标:掌握 storeToRefs 的使用
如果直接从 pinia 中解构数据,会丢失响应式,使用 storeToRefs 可以保证解构出来的数据也是响应式的
Login.vue
<script setup>
import { storeToRefs } from 'pinia'
import useCountStore from '../store/count'
const count = useCountStore()
// 如果直接从 pinia 中解构数据,会丢失响应式
const { num, doubleNum } = count
// 使用 storeToRefs 可以保证解构出来的数据也是响应式的
const { num, doubleNum } = storeToRefs(count)
</script>