IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> vue使用pinia (vue2/vue3) -> 正文阅读

[JavaScript知识库]vue使用pinia (vue2/vue3)

pinia是什么?Pinia 是 Vue.js 的轻量级状态管理库

官方网站:Pinia

中文文档: ? 介绍 | Pinia 中文文档

pinia与vuex4

相同

  • 是vue 官方 状态管理工具(作者是 Vue 核心团队成员)
  • 是vue开发者工具支持pinia

不同

  • pinia相比vuex4,对于vue3的 兼容性 更好
  • pinia相比vuex4,具备完善的 类型推荐 ?=> 对 TS 支持很友好
  • Pinia 的 API 设计非常接近 Vuex 5提案
    ?
  • vuex只能有一个根级别的状态, ?pinia 直接就可以定义多个根级别状态

pinia核心概念

  • state: 状态
  • actions: 修改状态(包括同步和异步,pinia中没有mutations)
  • getters: 计算属性

一、使用

1. 安装pinia vue2/vue3 通用

yarn add pinia
# 或者使用 npm
npm install pinia

2.如果是脚手架的创建的项目可以在安装,会自动创建一个出一个实例,帮助你快速引入pinia

vue add vue-cli-plugin-pinia

3.使用 pinia
store/index.js

import {
  defineStore
} from 'pinia'

// 创建store,命名规则: useXxxxStore
// 参数1:store的唯一表示
// 参数2:对象,可以提供state actions getters

export const useCounterStore = defineStore('counter', {
  // data里中的数据
  state: () => ({
    count: 1
  }),
  // 计算属性
  getters: {
    double: state => state.count * 2
  },
  // 相当于 vue中的 methods 既可以写同步代码也可以写异步
  actions: {
    addCount () {
      this.count++
    }
  }
})

vue2:? ? Home.vue

<template>
  <div class="home">
    <img alt="Vue logo" src="../assets/logo.png">
    <div> pinia中的count值 {{count}}</div>
    <div>pinia中的计算属性 {{double}}</div>
    <button @click="addCount">count +1 </button>
    <button @click="getCount">拿到count的值</button>
  </div>
</template>

<script>

// @ is an alias to /src
import { mapState, mapActions } from 'pinia'
import { useCounterStore } from '@/store'
export default {
  name: 'Home',
  computed: {
    ...mapState(useCounterStore, ['count', 'double'])
  },
  methods: {
    ...mapActions(useCounterStore, ['addCount']),
    getCount () {
      console.log(this.count)
    }
  }

}
</script>

vue3?

<template>
  <div class="home">
    <img alt="Vue logo" src="../assets/logo.png">
    <div> pinia中的count值 {{store.count}}</div>
    <div>pinia中的计算属性 {{store.double}}</div>
    <button @click="addCount">count +1 </button>
    <button @click="getCount">拿到count的值</button>
  </div>
</template>

<script >
import { useCounterStore } from '@/store'

export default {
  setup () {
    const store = useCounterStore()
    const addCount = () => {
      // 数据+1
      store.count++
      // 使用$patch 修改数据 好处是可以使用修改多个数据
      // store.$patch({
      //   count: store.count + 1
      // })
    }
    return { store, addCount }
  }
}
</script>

二、持久化 vue3/vue2通用

持久化插件:Pinia Plugin Persist

安装命令

npm  add pinia-plugin-persist

yarn add pinia-plugin-persist

vue2持久化

main.js

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import { createPinia, PiniaVuePlugin } from 'pinia'
import VueCompositionAPI from '@vue/composition-api'
// 引入持久化组件  若不想持久化 可不使用
import piniaPersist from 'pinia-plugin-persist'
const pinia = createPinia()
pinia.use(piniaPersist)

Vue.use(PiniaVuePlugin)
Vue.use(VueCompositionAPI)
Vue.config.productionTip = false

new Vue({
  router,
  pinia,
  render: h => h(App)
}).$mount('#app')

store/index.js

import {
  defineStore
} from 'pinia'

export const useCounterStore = defineStore('counter', {
  // data里中的数据
  state: () => ({
    count: 1
  }),
  persist: {
    enabled: true, // 开启本地存储
    strategies: [
      {
        key: 'counter1', // 修改当前存储的键名 若不修改则是上面的id
        storage: localStorage // 修改当前的存储方式,如果不填 则存储方式为sessionstorage
      }
    ]
  }
})

vue3持久化

main.js

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import { createPinia, PiniaVuePlugin } from 'pinia'
import VueCompositionAPI from '@vue/composition-api'
// 引入持久化组件  若不想持久化 可不使用
import piniaPersist from 'pinia-plugin-persist'
const pinia = createPinia()
pinia.use(piniaPersist)

Vue.use(PiniaVuePlugin)
Vue.use(VueCompositionAPI)
Vue.config.productionTip = false

new Vue({
  router,
  pinia,
  render: h => h(App)
}).$mount('#app')

store/index.js

import {
  defineStore
} from 'pinia'

export const useCounterStore = defineStore('counter', {
  // data里中的数据
  state: () => ({
    count: 1
  }),
  persist: {
    enabled: true, // 开启本地存储
    strategies: [
      {
        key: 'counter1', // 修改当前存储的键名 若不修改则是上面的id
        storage: localStorage // 修改当前的存储方式,如果不填 则存储方式为sessionstorage
      }
    ]
  }
})

三、storeToRefs

使用storeToRefs可以保证解构出来的数据也是响应式的。

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

<template>
    <div>
        {{counter.count}}
    </div>
</template>

<script setup>
import { useCounterStore } from '@/store'
const counter = useCounterStore()
</script>

如果我们想省略counter 第一个思路 解构

<script setup>
import { useCounterStore } from '@/store'
const counter = useCounterStore()
const { count } = counter
</script>

如果直接从pinia中结构,会丢失响应式

storeToRefs

可以保证解构出来的数据也是响应式的。

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

使用

<script setup>
import { storeToRefs } from 'pinia'
import { useCounterStore } from '@/store'
const counter = useCounterStore()
const { count } = storeToRefs(counter)
</script>

使用storeToRefs可以保证解构出来的数据也是响应式的

四、pinia模块化

src
├── store
│   ├── 模块1.js
│?? └── 模块2.js
├── pages
│?? ├── Home.vue
│?? └── Login.vue
└── main.js

在某个.vue中使用模块时,先import useXXXStore from './模块', 然后 const xxx = useXXXStore(),来使用。如果在导入第二个模块就需要写两次

import { useCounterStore } from '@/store/counter'
import { useCounterUser } from '@/store/user'
const counter = useCounterStore()
const counter = useCounterUser()

改进

在复杂项目中,不可能把多个模块的数据都定义到一个store中,一般来说会一个模块对应一个store,最后通过一个根store进行整合

src
├── store
│?? ├── modules
│?? │?? ├── user.js
│?? │?? └── counter.js
│?? └── index.js        // 根store
├── pages
│?? └── 页面.vue
└── main.js

module/counter.js

import { defineStore } from 'pinia'

const useUserStore = defineStore('counter', {
  state: () => ({ count: 1 }),
  getters: {
    double: state => state.count * 2
  },
  actions: {
    addCount () {
      this.count++
    }
  },
  persist: {
    enabled: true
  }
})
export default useUserStore

store/index.js


// 1. 分别导入各个模块
import useCounterStore from './module/counter'
import useUserStore from './module/user'

// 2. 统一导出useStore方法
export default function useStore () {
  return {
    counter: useCounterStore(),
    user: useUserStore()
  }
}

store/user.js

import { defineStore } from 'pinia'

const useUserStore = defineStore('user', {
  state: () => ({ name: '奥特曼', age: 18 }),
  getters: {
    double: state => state.age * 2
  },
  actions: {
    editUserName () {
      this.name = '迪迦'
    }
  },
  persist: {
    enabled: true
  }
})

export default useUserStore

注意:?每个文件中的 defineStore(id,{}) 中的id不要重复 否则在index.js 调用时以第一次调用为准

组件中使用

<template>
    <div>
        {{count}} {{name}}
        <button @click="addCount">+1</button>
    </div>
</template>

<script setup>
import { storeToRefs } from 'pinia'
// 导入工具函数
import useStore from '@/store'
// 解构一下
const { counter, user } = useStore()

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

const { addCount } = counter
</script>

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-09-24 20:47:38  更:2022-09-24 20:48:05 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 10:44:16-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码