vue3生态-router-pinia

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的基本使用

目标

掌握vue-router4的基本使用

官网:https://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中配置路由出口。

下面是基本目录结构

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

创建组件Home.vue和Login.vue

配置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

目标

掌握在组件内部使用route和router的方式

背景

在v3中,组件中无法访问this,所以也无法像之前在vue2中采用的this.route与this.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


image.png

Pina-新一代状态管理工具

pinia是什么

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

官方网站:https://pinia.vuejs.org/

中文文档: https://pinia.web3doc.top/introduction.html

pinia核心概念

vuex的内容:
● state
● mutations
● actions
● getters
● modules
● plugins
pinia的内容
● state
● actions
● getters
● modules
● plugins

pinia基本使用

目标

掌握pinia的使用步骤

步骤

  1. 安装 npm i pinia
  2. 在main.js中use
  3. 定义模块
  4. 使用模块

在main.js中引入pinia

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

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

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

定义模块

新建文件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

使用模块

步骤:

  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>

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的使用

目标

掌握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('http://api-toutiao-web.itheima.net/mp/v1_0/channels')
        list.value = res.data.data.channels
    }

    return { list, getList }
})

在组件中使用

<script setup>
  import useCounterStore from '@/stores/counter.js'
  const counterStore = useCounterStore()

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

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

</script>
<template>
  <div>
    {{ counterStore.doubleCount }}
    <button @click="counterStore.addCount">+1</button>
    count: {{ counterStore.count }}
    {{ newsListStore.list }}
  </div>
</template>

用storeToRefs来优化pinia的使用

目标

掌握storeToRefs的使用

问题

在模板中使用数据时,要加上模块的名字,例如:

<template>
  <h1>根组件---{{ counter.count }}</h1>
  <h3>{{ counter.double }}</h3>
</template>

思考:上面代码中的counter 可以省略么?用解构赋值?
结论:如果直接从pinia中解构数据,会丢失响应式。

const counterStore = useCounterStore()

// 这样的count没有响应式效果
const { count } = counterStore

console.log(count, addCount)

storeToRefs

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

const { state属性名1, state属性名2 } = storeToRefs(模块名)

测试使用

<script setup>
import { storeToRefs } from 'pinia'
import useCounterStore from './store/counter'

const counter = useCounterStore()
// 如果直接从pinia中解构数据,会丢失响应式
const { count, double } = counter

// 使用storeToRefs可以保证解构出来的数据也是响应式的
const { count, double } = storeToRefs(counter)
</script>

持久化

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

https://prazdevs.github.io/pinia-plugin-persistedstate/guide/why.html

  1. 安装

npm i pinia-plugin-persistedstate

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

app.use(store)
  1. 在某个store中使用
    参考如下
const useCounterStore = defineStore('counter', () => {

  // 以对象形式返回
  return {count, addCount, doubleCount}
},{
  persist: {
    key: 'my-custom-key' // 持久化使用的属性名,默认是 store.$id
    storage: sessionStorage, //  默认是localStorage
    paths: ['list', 'type'], // 要持久化的属性
  }
})
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容