• vue3的pinia详解


    引入pinia

    安装pinia

    cnpm install pinia --save

    main.js

    1. import {createPinia} from "pinia"
    2. const pinia=createPinia()
    3. app.use(pinia)

    state

    state是store的核心部分

    创建store仓库【src/store/count.js】

    选项式

    1. import { defineStore } from "pinia"
    2. //模块命名规则:use+关键功能+Store
    3. //defineStore:参数1:命名 参数2:对象
    4. export const useConutStore = defineStore("count", {
    5. //state必须是函数类型
    6. state: () => {
    7. return {
    8. count:20
    9. }
    10. }
    11. })

    组合式

    1. import { defineStore } from "pinia"
    2. import {ref,reactive} from "vue"
    3. //模块命名规则:use+关键功能+Store
    4. //组合式API优势:不需要引入state
    5. export const useConutStore = defineStore("count", ()=>{
    6. const count=ref(200)
    7. const userInfo=reactive({
    8. name:"wkj"
    9. })
    10. return {
    11. count,
    12. userInfo
    13. }
    14. })

    访问 “state”

    【组合式API】

    1. <template>
    2. <p>Count1:{{ count }}</p>
    3. </template>
    4. <script setup>
    5. import { useCountStore } from "../store/count"
    6. const { count } = useCountStore();
    7. </script>

    【选项式API】

    1. <template>
    2. <p>Count1:{{ count }}</p>
    3. <p>Count2:{{ doubleCount }}</p>
    4. </template>
    5. <script>
    6. import { mapState } from "pinia"
    7. import { useCountStore } from "../store/count"
    8. export default {
    9. computed:{
    10. ...mapState(useCountStore,{
    11. myOwnName:"count",
    12. count:store => store.count,
    13. doubleCount(store){
    14. return store.count * 2
    15. }
    16. })
    17. }
    18. }
    19. </script>

    修改 “state”

    pinia 中修改状态要比在 vuex 中修改状态简单的多,因为不用引入额外的概念,直接用 store.counter++ 修改 store

    组合式API

    1. import { useCountStore } from "../store/count"
    2. const store = useCountStore();
    3. function updateClick(){
    4. store.count++
    5. }

    选项式API

    1. import { mapState,mapWritableState } from "pinia"
    2. import { useCountStore } from "../store/count"
    3. export default {
    4. computed:{
    5. ...mapState(useCountStore,{
    6. myOwnName:"count",
    7. count:store => store.count,
    8. doubleCount(store){
    9. return store.count * 2
    10. }
    11. }),
    12. ...mapWritableState(useCountStore,["count"])
    13. },
    14. methods:{
    15. updateClick(){
    16. this.count++
    17. }
    18. }
    19. }

    Getters

    Getter 完全等同于 Store 状态的计算值

    创建store仓库【src/store/count.js】

    1. import { defineStore } from "pinia"
    2. export const useCountStore = defineStore("count",{
    3. state:() =>{
    4. return{
    5. count:10
    6. }
    7. },
    8. getters:{
    9. getCount:(state) => "当前Count:"+ state.count
    10. }
    11. })

    访问 Getters

    组合式API

    1. <template>
    2. <p>{{ store.getCount }}</p>
    3. </template>
    4. <script setup>
    5. import { useCountStore } from "../store/count"
    6. const store = useCountStore();
    7. </script>

    选项式API

    1. <template>
    2. <p>{{ getCount }}</p>
    3. </template>
    4. <script setup>
    5. import { mapState } from "pinia"
    6. import { useCountStore } from "../store/count"
    7. export default {
    8. computed:{
    9. ...mapState(useCountStore,["getCount"])
    10. }
    11. }
    12. </script>

    访问其他 Getter

    1. getters:{
    2. getCount:(state) => "当前Count:"+ state.count,
    3. doubleCount(state){
    4. return this.getCount + state.count
    5. }
    6. }

    Actions

    Actions 相当于组件中的 methods。 它们可以使用 defineStore() 中的 actions 属性定义,并且它们非常适合定义业务逻辑

    创建store仓库【src/store/count.js】

    1. import { defineStore } from "pinia"
    2. export const useCountStore = defineStore("count", {
    3. state: () => {
    4. return {
    5. count: 10
    6. }
    7. },
    8. getters: {
    9. getCount: (state) => "当前Count:" + state.count,
    10. doubleCount(state) {
    11. return this.getCount + state.count
    12. }
    13. },
    14. actions: {
    15. increment() {
    16. this.count++
    17. },
    18. decrement() {
    19. this.count--
    20. }
    21. }
    22. })

    读取Actions

    组合式API

    1. <template>
    2. <h3>Pinia</h3>
    3. <p>Count1:{{ store.count }}</p>
    4. <button @click="addCountHandler">增加</button>
    5. <button @click="minCountHandler">减少</button>
    6. </template>
    7. <script setup>
    8. import { useCountStore } from "../store/count"
    9. const store = useCountStore();
    10. function addCountHandler(){
    11. store.increment()
    12. }
    13. function minCountHandler(){
    14. store.decrement()
    15. }
    16. </script>

    选项式API

    1. <template>
    2. <h3>Pinia</h3>
    3. <p>Count1:{{ store.count }}</p>
    4. <button @click="addCountHandler">增加</button>
    5. <button @click="minCountHandler">减少</button>
    6. </template>
    7. <script>
    8. import { mapState,mapActions } from "pinia"
    9. import { useCountStore } from "../store/count"
    10. export default {
    11. computed:{
    12. ...mapState(useCountStore,{
    13. myOwnName:"count",
    14. count:store => store.count,
    15. doubleCount(store){
    16. return store.count * 2
    17. }
    18. })
    19. },
    20. methods:{
    21. ...mapActions(useCountStore,["increment","decrement"]),
    22. addCountHandler(){
    23. this.increment()
    24. },
    25. minCountHandler(){
    26. this.decrement()
    27. }
    28. }
    29. }
    30. </script>

    异步操作

    actions 可以是异步的,这也是使用 actions 最大的原因

    1. import { defineStore } from "pinia"
    2. import axios from "axios"
    3. export const useBannerStore = defineStore("banner", {
    4. state: () => {
    5. return {
    6. banner:[]
    7. }
    8. },
    9. actions: {
    10. setBanner(url){
    11. axios.get(url)
    12. .then(res =>{
    13. this.banner = res.data.banner
    14. }).catch(error =>{
    15. console.log(error);
    16. })
    17. }
    18. }
    19. })
    20. <template>
    21. <h3>网络请求</h3>
    22. <ul>
    23. <li v-for="(item,index) in store.banner" :key="index">
    24. <h3>{{ item.title }}</h3>
    25. <p>{{ item.content }}</p>
    26. </li>
    27. </ul>
    28. </template>
    29. <script setup>
    30. import { onMounted } from "vue"
    31. import { useBannerStore } from "../store/banner"
    32. const store = useBannerStore();
    33. onMounted(() =>{
    34. store.setBanner("http://iwenwiki.com/api/blueberrypai/getIndexBanner.php")
    35. })
    36. </script>

    解构赋值响应式

    直接从 pinia 中解构赋值,操作的时候会发现,内容根本不会发生变化,因为直接从 pinia 中解构数据失去了响应式

    我们可以用 storeToRefs 来解决找个问题

    1. import { storeToRefs } from "pinia";
    2. import { useCountStore } from "../store/count";
    3. const store = useCountStore();
    4. const { count } = storeToRefs(store)
    5. function addCountHandler(){
    6. store.increment(5)
    7. }
    8. function minCountHandler(){
    9. store.decrement(5)
    10. }

    Pinia热更新

    pinia 支持热模块替换,因此你可以编辑store,并直接在您的应用程序中与它们交互,而无需重新加载页面,允许您保持现有的状态,添加,甚至删除state,action和getter

    1. import { defineStore, acceptHMRUpdate } from "pinia"
    2. import axios from "axios"
    3. export const useCountStore = defineStore("count", {
    4. state: () => {
    5. return {
    6. count: 10
    7. }
    8. },
    9. getters: {
    10. getCount: (state) => "当前Count:" + state.count
    11. }
    12. })
    13. if (import.meta.hot) {
    14. import.meta.hot.accept(acceptHMRUpdate(useCountStore, import.meta.hot))
    15. }

    数据持久化插件

    安装pinia数据持久化插件

    cnpm install --save pinia-plugin-persist

    main.js

    1. import piniaPersist from 'pinia-plugin-persist'
    2. pinia.use(piniaPersist)

    编写stores/loginStore.js

    1. import { defineStore } from "pinia"
    2. export const useLoginStore = defineStore("login", {
    3. state: () => {
    4. return {
    5. token:false,//登录的token
    6. username: "",//用户名
    7. permissions:''//用户权限
    8. }
    9. },
    10. //本地持久化(把数据存储到浏览器本地)
    11. persist: {
    12. enabled: true,//是否开启持久化
    13. strategies: [
    14. {
    15. key: 'login', //自定义Key值,存储到本地时的key
    16. storage: localStorage, // 选择存储方式:本地存储
    17. },
    18. ],
    19. }
    20. })

  • 相关阅读:
    如何报考PMP项目管理认证考试?
    用关系代数查找2014年五月30号从”昆明”出发的所有乘客姓名
    计算机毕业设计ssm+vue基本微信小程序的小学生兴趣延时班预约小程序
    国运线,A股长期上升趋势线
    Go-知识测试-子测试
    蓝桥杯每日一题——棋盘
    【云原生之k8s】kubeadm搭建k8s集群
    使用手机作为电脑的麦克风和摄像头外设
    docker从入门到熟悉
    2022年了还不懂JVM?一文带你深入解析
  • 原文地址:https://blog.csdn.net/m0_63040701/article/details/130905397