vue3生态-router和pinia

530 阅读4分钟

vue3生态的变化

生态圈

vue2升级到vue3之后,其对应的整体生态圈也随之升级。从 调试工具到路由,全局状态管理到UI组件库,都随之升级了。 升级之后在使用上也有些变化。

版本

vue升级vue3之后,配套的vue-router也升级为vue-router@4.x版本。

vue-router4的语法和3的版本语法基本一致,但是有一些细微的修改。

vue@2 + vue-router@3 + vuex@3 options api

vue@3 + vue-router@4 + vuex@4 composition api

vue-router4的基本使用

npm init vue@latest创建项目时可以直接创建路由

官网:router.vuejs.org/

安装vue-router

两种情况:

  1. 全新项目

  2. 老项目中额外添加vue-router

情况1:

如果是全新创建的项目,可以直接在交互工具中选择vue3的版本,再选择vue-router时,就会自动安装并配置vue-router 4

情况2:

老项目中,自己手动安装vue-router。这个不加版本号,表示默认安装最新的。 npm i vue-router

使用

安装完成之后,我们就可以来配置使用路由功能了。其基本使用流程与vue-router3一致:
1配置router。导入组件,配置路由规则
2在main.js中使用router
3在App.vue中配置路由出口。

下面是基本目录结构
创建组件Home.vue和Login.vue

src
├── router
│   └── index.js
├── pages
│   ├── Home.vue
│   └── Login.vue
└── main.jsr'

配置router

创建文件router/index.js,内容如下:

import {
  createRouter,
  createWebHashHistory,
  createWebHistory,
} from 'vue-router'

// 1. 创建路由
const router = createRouter({
  // 创建history模式的路由
  // history: createWebHistory(),
  // 创建hash模式的路由
  history: createWebHashHistory(),
  // 配置路由规则
  routes: [
    { path: '/home', component: () => import('../pages/Home.vue') },
    { path: '/login', component: () => import('../pages/Login.vue') },
  ],
})

export default router

在main.js中导入使用

在main.js中引入

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'

createApp(App).use(router).mount('#app')

配置路由出口

App.vue中使用

<template>
  
      <router-link to="/home">首页</router-link>
   
      <router-link to="/login">登陆</router-link>
    
  <!-- 路由出口 -->
  <router-view></router-view>
</template>

组件中使用route与router

背景

在v3中,组件中无法访问this,所以也无法像之前在vue2中采用的this.$routethis.$router来操作路由。

对应的调整为:

vue2 ----> vue3

this.$route ---> const route = useRoute()

this.$router ---> const router = useRouter()

useRoute获取route信息

通过useRoute()可以获取route信息

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

export default {
  setup() {
    const route = useRoute()
    console.log(route.path)
    console.log(route.fullPath)
  },
}
</script>

useRouter获取router信息

通过useRouter()可以获取router信息

<script setup>
    import { useRouter } from 'vue-router'
    const router = useRouter()
    const login = () => {
        router.push('/home')
    }
</script>

Pinia新一代状态管理工具

Pinia 是 Vue.js 的轻量级状态管理库,是vuex的升级版

image.png

官方网站:pinia.vuejs.org/

中文文档:   pinia.web3doc.top/introductio…

pinia核心概念

vuex的内容:

  • state
  • mutations
  • actions
  • getters
  • modules
  • plugins

pinia的内容

  • state
  • actions
  • getters
  • modules
  • plugins

pinia基本使用

步骤

1. 安装 npm i pinia

2. 在main.jsuse

import { createApp } from 'vue'
import App from './App.vue'

import { createPinia } from 'pinia'
const pinia = createPinia()

createApp(App).use(pinia).mount('#app')

3. 定义模块

新建文件src/store/counter.js

import { defineStore } from 'pinia'
// 创建store,命名规则: useXxxxStore
// 参数1:store的唯一标识
// 参数2:回调函数,类似于setup()的功能,可以提供state actions getters
import { ref } from 'vue'
const useCounterStore = defineStore('counter', () => {
  // 数据(state)
	const count = ref(0)

  // 修改数据的方法 (action)
  const addCount = () => {
  	count.value++
	}
  // 以对象形式返回
  return {count, addCount}
})

export default useCounterStore

4. 使用模块步骤

  1. 在组件中引入模块
  2. 调用store函数得到store
  3. 使用store
<script setup>
// 1. 在组件中引入模块
import useCounterStore from '@/src/store/counter'
// 2. 调用store函数得到store
const counter = useCounterStore()
console.log(counter)
</script>

<template>
  // 使用store
  count: {{ counter.count }}
  <button @click="counter.addCount">点击增加</button>
</template>

可以导入storeToRefs进行解构,但函数不能; 直接从pinia中解构数据,会丢失响应式

使用storeToRefs可以保证解构出来的数据(state + getter)也是响应式的。注意: 不要对action进行解构

import { storeToRefs } from 'pinia'
const { list } = storeToRefs(counter)

pinia中getters的使用

pinia中的getters直接使用computed函数进行模拟,再把getters return出去.

定义getters(计算属性)

import { defineStore } from 'pinia'
// 创建store,命名规则: useXxxxStore
// 参数1:store的唯一表示
// 参数2:回调函数,类似于setup()的功能,可以提供state actions getters
import { ref, computed } from 'vue'
const useCounterStore = defineStore('counter', () => {
  // 数据(state)
	const count = ref(0)

  // 修改数据的方法 (action)
  const addCount = () => {
  	count.value++
	}
  // 计算属性
  const doubleCount = computed(() => count.value * 2)

  // 以对象形式返回
  return {count, addCount, doubleCount}
})

export default useCounterStore

在组件中使用

<script setup>
  import useCounterStore from '@/stores/counter.js'
  const counterStore = useCounterStore()
  console.log(counterStore)
</script>
<template>
<div>
  {{ counterStore.doubleCount }}
  <button @click="counterStore.addCount">+1</button>
  count: {{ counterStore.count }}
</div>
</template>

pinia中异步actions的使用

新建的一个store

import { defineStore } from 'pinia'
import { ref } from 'vue'
import axios from 'axios'
export default defineStore('newList', () => {

    const list = ref([])

    const getList = async () => {
        const res = await axios.get('xxx')
        list.value = res
    }

    return { list, getList }
})

在组件中使用

<script setup>
  import useNewsListStore from '@/stores/newsList.js'
  import { onMounted } from 'vue';
  const newsListStore = useNewsListStore()

  onMounted(() => {
    newsListStore.getList()
  })

</script>
<template>
  <div>
    {{ newsListStore.list }}
  </div>
</template>

持久化工具

有现成的第三方插件可以使用

prazdevs.github.io/pinia-plugi…

1. 安装

npm i pinia-plugin-persistedstate

2. 配置

mian.js

import { createPinia } from 'pinia'
// 引入持久化插件
import piniaPluginPersist from 'pinia-plugin-persistedstate'
const storePinia = createPinia()
// 使用该插件
storePinia.use(piniaPluginPersist)

app.use(store)

3. 在某个store中使用

const useCounterStore = defineStore('counter', () => {
  // 以对象形式返回
  return {xxx}
},{
  persist: {
    key: 'my-custom-key' // 持久化使用的属性名,默认是 store.$id
    storage: sessionStorage, //  默认是localStorage
    paths: ['list', 'type'], // 要持久化的属性
  }
})