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'], // 要持久化的属性
  }
})
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容