Vue3全家桶 - Pinia - 【1】(安装与使用 + Store + State + Getters + Actions)

news2024/11/26 22:50:49

Pinia

  • piniaVue 的专属状态管理库,它允许你跨组件或跨页面共享状态;

一、 安装与使用 pinia

  • 安装语法:
    yarn add pinia
    npm install pinia
    
  • 创建一个 pinia (根存储)并将其传递给应用程序:
    • 目标文件:main.js
      import { createApp } from 'vue'
      import App from './App.vue'
      
      // 导入 createPinia 函数
      import { createPinia } from 'pinia'
      
      const app = createApp(App)
      
      // 使用 createPinia() 来创建 Pinia(根存储),并应用到整个程序中
      app.use(createPinia())
      
      app.mount('#app')
      

二、Store

  • store 是一个 保存状态业务逻辑实体,它并不与你的组件树绑定;换句话说,它 承载着全局状态;它有点像一个永远存在的组件,每个组件都可以读取和写入它;

  • store 它有三个概念,stategettersactions,我们可以理解成组件的 datacomputedmethods

  • 🔺创建store

    • 在项目中 src/store 文件夹下新建 store.js
    • store 是用 defineStore(name, fucntion | options) 定义的,建议其函数返回值命名为 use...Store 方便理解;
    • 参数:
      • name
        • 当前这个 store 名字,必填唯一
      • function | options
        • 函数 或 对象 形式;
        • 函数组合模式,类似组件组合式API的书写方式】:定义响应式变量和方法,并且 return 对应的 变量方法ref() 相当于 statecomputed() 相当于 gettersfunction() 相当于 actions
        • 对象选项模式】:其中配置stategettersactions选项;
    • 示例展示:
      import { defineStore } from 'pinia';
      
      // TODO 选项式API
      /**
       * 参数1 - store的名称,保证在整个应用中是唯一的
       * 参数2:
       *    对象形式 - 选项式API:
       *        state - 函数
       *        getters - 对象
       *        actions - 对象
       */
      const userStore = defineStore('main', {
        //  共享数据
        state: () => ({}),
        // 共享通过计算得到的数据
        getters: {},
        // 共享函数
        actions: {}
      });
      
      // TODO 组合式API
      /**
       * 参数1 - store的名称,保证在整个应用中是唯一的
       * 参数2:
       *    函数形式 - 组合式API:
       *        state -> ref() - 共享数据
       *        getters -> computed() - 共享计算得到的数据
       *        actions -> function() - 共享方法
       * 注意:最后 必须 return 出去 才会 生效
       */
      const userStore = defineStore('main', () => {
        // 最后必须返回组件需要的变量、计算属性、函数
        return ({});
      });
      
      export default userStore;
      

三、State

  • statestore 的核心部分,主要存储的是共享的数据;

3.1 定义 state

  • store 采用的是 选项模式
    • state 选项 为 函数返回的对象,在其定义共享的数据;
  • store 采用的是 组合式模式
    • 在其函数内定义的 ref变量,最终 return 出去来提供共享的数据;
  • 示例展示:
    • 组合式:
      import { defineStore } from 'pinia';
      import { ref } from 'vue';
      
      // TODO 组合式API
      const useUserStore = defineStore('user', () => {
        // 1. 声明 ref 变量
        const userName = ref('禁止摆烂_才浅')
        const age = ref(22)
        const gender = ref('男')
        const city = ref('兰州')
        const work = ref('初级前端开发工程师')
      
        // 最后必须 return 出去
        return ({
          userName,
          age,
          gender,
          city,
          work
        })
      });
      
      export default useUserStore;
      
    • 选项式:
      import { defineStore } from 'pinia';
      
      // TODO 选项式API
      const useUserStore = defineStore('user', {
        // 定义共享数据
        state: () => ({
          userName: '禁止摆烂_才浅',
          age: 22,
          gender: '男',
          city: '兰州',
          work: '初级前端开发工程师'
        }),
        getters: {},
        actions: {}
      });
      
      export default useUserStore;
      

3.2 组件中访问 state

  • 组合式API
    • 直接引入对应的 store ,通过 state 对象直接获取和修改 state
    • 注意
      • 如果想在组件中 自定义变量名 来接收 store 中的 state 中 共享的数据,我们可以这样做:
        • 使用 computed(() => store.dataName),具有 响应式,但是 只读形式
        • ✅ 使用 storeToRefs(store)store 解构想要的 state,具有 响应式,可 直接修改,可 自定义名称
    • 示例展示:
      <script setup>
      import { ref, reactive, computed, onMounted } from 'vue';
      import useUserStore from '@/store/useUserStore'
      import { storeToRefs } from 'pinia';
      
      // TODO 获取 useUserStore 示例
      const user_store = useUserStore()
      
      // TODO 将 store 中 state 的数据映射为当前组件的计算属性 - 具有响应式,但是是只读
      const user_userName = computed(() => user_store.userName)
      const user_age = computed(() => user_store.age)
      const user_work = computed(() => user_store.work)
      
      // TODO 使用 storeToRefs() 从 store 解构想要的 state,具有响应式,可直接修改,可自定义名称
      const { userName: myName, age: myAge } = storeToRefs(user_store)
      
      onMounted(() => {});
      </script>
      
      <template>
        <h2>组合式API</h2>
        <hr>
        <h4>从 store 直接获取 state,具有响应式,可修改</h4>
        <ul>
          <li>{{user_store.userName}}</li>
          <li>{{user_store.age}}</li>
          <li>{{user_store.gender}}</li>
          <li>{{user_store.city}}</li>
          <li>{{user_store.work}}</li>
        </ul>
        <hr>
        <button @click="user_store.age = 23">修改 - user_store.age</button> | 
        <button @click="user_store.city = '北京 / 上海 / 武汉 / 杭州 / 深圳'">修改 - user_store.city</button>
        <hr>
        <br>
      
        <h4>通过 computed 将 store 中的 state 数据,映射为当前组件中的计算属性 - 具有响应式,但是是只读</h4>
        <ul>
          <li>{{user_userName}}</li>
          <li>{{user_age}}</li>
          <li>{{user_work}}</li>
        </ul>
        <hr>
        <button @click="user_work = '中级前端开发工程师'">修改 - user_city</button>
        <button @click="user_age = 23">修改 - user_age</button> | 
        <hr>
        <br>
      
        <h4>使用 storeToRefs() 从 store 解构想要的 state 为当前组件的数据,具有响应式,可直接修改,可自定义名称</h4>
        <ul>
          <li>{{myName}}</li>
          <li>{{myAge}}</li>
        </ul>
        <hr>
        <button @click="myAge = 23"> 修改 - myAge </button>
      </template>
      
    • 运行展示:
      image.png
  • 选项式API
    • 可以使用 mapState(storeObj, array | object) 辅助函数将状态属性映射为 只读计算属性
    • 要映射到 computed 中;
    • storeObj 引入的 store 对象;
    • array | object字符串数组形式 或 对象形式;
      • 【字符串数组形式】:
        • 直接将 storestate 的数据映射为当前组件的 计算属性,但是 不能自定义名称
      • 【对象形式】:
        • key 为自定义当前组件的 计算属性名value 字符串形式,是 storestate 的共享数据
    • 🔺注意
      • mapState() 函数映射到组件中的计算属性是 只读的,如果想在组件中 响应式修改 state 的数据,则应该选择 mapWritableState() 函数 来映射计算属性;
      • 在导入mapState后,保存的时候可能会报错:
        image.png
        • 原因:
          • Piniavue 版本不匹配导致的;
          • Pinia 2.1.0 及以上版本需要引入 vue3.3 及以上版本;
        • 解决方法:
          • 升级vue版本:
            • vue 升级到 3.3 及以上版本,将 pinia 升级到 2.1.0 及以上版本;
          • 指定Pinia版本:
            • 如果无法升级到 3.3 及以上版本,可以锁定 pinia 的版本为 2.0.36
    • 示例展示:
      <script>
      /**
       * 选项式API 使用 Pinia
       * 1. 导入 mapState 函数(mapState 函数需要写在 计算属性中)
       * 2. 导入 对应的 store 对象,作为 mapState 的第一个参数
       */
      import { mapState, mapWritableState } from 'pinia';
      import useUserStore from '@/store/useUserStore.js';
      
      export default {
        name: 'App',
        component: {},
        props: {},
        data () {
          return {}
        },
        computed: {
          /**
           * mapState - 有两个参数:
           *    参数1:导入的 store 对象
           *    参数2:array(字符串数组) / object
           *        array(字符串数组):
           *            将当前组件需要用到的数据(字符串形式)放到这个数组中;
           *            不能进行重命名
           *        object:
           *            可以重命名,key 就是行变量名, value 就是旧名
           * 注意:
           *    mapState 将 store 的 state 映射为当前组件的计算属性
           *    具有响应式(修改store中的state,当前组件中的数据也会发生变化),但是是只读的(不能修改)
           */
          ...mapState(useUserStore, ['userName', 'age']),
          ...mapState(useUserStore, {
            u_gender: 'gender',
            u_work: 'work',
            u_city: 'city'
          }),
          ...mapWritableState(useUserStore, {
            user_age: 'age',
            user_city: 'city'
          })
        },
        methods: {},
        watch: {}
      };
      </script>
      
      <template>
        <h2> 使用 mapState 访问 state - 映射为计算属性 - 具有响应式,但是是只读</h2>
        <ul>
          <li> {{ userName }} </li>
          <li> {{ age }} </li>
          <li> {{ u_gender }} </li>
          <li> {{ u_city }} </li>
          <li> {{ u_work }} </li>
        </ul>
        <hr>
        <button @click="age++">修改 - age</button>
      
        <h2> 使用 mapWritableState 访问 state - 映射为计算属性 - 具有响应式,可修改</h2>
        <ul>
          <li>{{ user_age }}</li>
          <li>{{ user_city }}</li>
        </ul>
        <button @click="user_age = 23">修改 - user_age</button>
        <button @click="user_city = '武汉 / 北京 / 上海 / 杭州'">修改 - user_city</button>
      </template>
      
    • 运行展示:
      image.png
      • 修改 mapState 映射的数据:
        • 修改不成功,会在控制台报警告;
          image.png
      • 修改 mapWritableState 映射的数据:
        • 修改成功;
          image.png

四、Getters

  • getters 是计算得到的新的共享数据,当 依赖 发生变化 时 则 重新计算,所以其他组件包括 store 自己不要直接对其修改;

4.1 定义 getters

  • 组合式store
    • 可通过 computed() 函数通过计算得到新的数据,再将其 return 暴露出去即可;
    • 🔺 注意
      • getters 中访问 state中的数据,需要添加后缀 .value
    • 示例展示:
    import { defineStore } from 'pinia';  
    import {computed, ref} from 'vue';  
    
    // TODO 组合式API  
    const useUserStore = defineStore('user', () => {  
        // 1. 声明 state,使用 ref() 函数  
        const userName = ref('禁止摆烂_才浅')  
        const age = ref(22)  
        const gender = ref('男')  
        const city = ref('兰州')  
        const work = ref('初级前端开发工程师')  
        const birthday = ref('2000-01-01')  
    
        // 2.声明 getters ,使用 computed() 函数
        // 只读 - 如果依赖的数据发生该改变,对应的 getters 也会重新计算
        const month = computed( () => birthday.value.split('-')[1] )  
        const ageStage = computed( () => age.value >= 18 ? '成年' : '未成年')  
    
        // 最后必须 return 出去  
        return ({  
            // state  
            userName,  
            age,  
            gender,  
            city,  
            work,  
            birthday,  
            // getters  
            month,  
            ageStage  
        })  
    });  
    
    export default useUserStore;
    
  • 选项式store
    • getters 选项中 声明的 函数 即为 计算属性
    • 在其函数内可通过 this 关键字获取 store实例this.state中的变量名】,也可通过 方法第一个参数 得到 store实例
    • 如果采用的是箭头函数的话,无法使用this关键字,为了更方便使用store中实例,可为其箭头函数设置第一个参数来获取store实例;
    • 示例展示:
    import { defineStore } from 'pinia';  
    
    // TODO 选项式API  
    const useUserStore = defineStore('user', {  
        // 定义共享数据  
        state: () => ({  
            userName: '禁止摆烂_才浅',  
            age: 22,  
            gender: '男',  
            city: '兰州',  
            work: '初级前端开发工程师',  
            birthday: '2000-1-1'  
        }),  
        // 通过计算属性得到的新的共享数据,只读,不能修改,只有当依赖发生变化的时候,getters中的数据才会重i性能计算  
        getters: {  
            // 非箭头函数 - 通过 this 访问 store 实例  
            month () {  
                return this.birthday.split('-')[1]  
            },  
            // 箭头函数 - 函数的第一个参数,为 store 实例  
            ageStage: store => {  
                if (store.age < 18) return '未成年'  
                return '成年'  
            }  
        },  
        actions: {}  
    });  
    
    export default useUserStore;
    

4.2 在组件中使用 getters

  • 组合式API

    • 访问 store 中的 getters 和访问 state 类似,直接引入对应的 store,通过 store对象直接获取 getters,但是如果 对其 进行修改会报错
      • 注意
        • 如果想将 store 中的 getters 中共享的数据映射为本地组件的计算属性,我们可以这样做:
          • 使用 computed(() => store.gettersName)具有响应式,但是 只读形式
          • 使用 storeToRefs(store)store 解构 getters 依旧是计算属性,所以是 只读的,一旦 对其 进行修改 会 报错,但是 具有响应式可自定义名称
    • 示例展示:
      <script setup>  
      import { ref, reactive, computed, onMounted } from 'vue';  
      import useUserStore from '@/store/useUserStore'  
      import { storeToRefs } from 'pinia';  
      
      // TODO 获取 useUserStore 示例  
      const user_store = useUserStore()  
      
      // TODO 使用 computed 将 store 中 getters 的数据映射为当前组件的计算属性,只读 - 不能修改,一旦修改就会在控制台打印警告  
      const month = computed(() => user_store.month )  
      const ageStage = computed(() => user_store.ageStage)  
      
      // TODO 使用 storeToRefs() 将 store 中的 getters 的数据 解构 为 当前组件 的 计算属性,具有响应式,可重命名,只读 - 一旦修改,就会报错  
      const { month: bir_month, ageStage: age_stage } = storeToRefs(user_store)  
      
      onMounted(() => {});  
      </script>  
      
      <template> 
          <h4>通过 store 直接获取 getters,具有响应式,只读 - 不能修改(修改会报错)</h4>  
          <ul>  
              <li>月份:{{ user_store.month }}</li>  
              <li>是否成年:{{ user_store.ageStage }}</li>  
          </ul>  
          <hr>  
          <button @click="(user_store.month)++">修改 - month</button>  
          <button @click="user_store.ageStage = '嘻嘻哈哈'">修改 - age - 改变 ageStage</button>  
          <hr>  
          <br>  
      
          <h4>通过 computed 将 store 中的 getters 映射为 当前组件 的 计算属性,具有响应式,只读 - 修改会在控制台打印警告</h4>  
          <ul>  
              <li>月份:{{ month }}</li>  
              <li>是否成年:{{ ageStage }}</li>  
          </ul>  
          <button @click="month++">修改 - month</button>  
          <button @click="ageStage = '嘻嘻哈哈'">修改 - ageStage</button>  
          <hr>  
          <br>  
      
          <h4>通过 storeToRefs() 将 store 中的 getters 映射为 当前组件 的 计算属性,只读 - 修改会报错</h4>  
          <ul>  
              <li>月份:{{ bir_month }}</li>  
              <li>是否成年:{{ age_stage }}</li>  
          </ul>  
          <button @click="bir_month++">修改 - month</button>  
          <button @click="age_stage = '嘻嘻哈哈'">修改 - ageStage</button>  
      </template>
      
    • 运行展示:
      • 对 直接从 store 获取的 getters 进行修改:
        image.png
      • 对 通过 computed 映射的 getters 进行修改:
        image.png
      • 对 通过 storeToRefs 解构的 getters 进行修改:
        image.png
  • 选项式API

    • 访问 store 中的 getters 和 访问 state 类似,同样可使用 mapState() 辅助函数将 getters 属性映射为 只读属性
    • 🔺注意
      • 如果采用 mapWritableState() 辅助函数 将 store 中的 getters 映射为 组件内部的计算属性,依旧可以 具有响应式一旦对其进行修改则会报错
    • 示例展示:
      <script> 
      import { mapState, mapWritableState } from 'pinia';  
      import useUserStore from '@/store/useUserStore.js';  
      
      export default {  
      name: 'App',  
      component: {},  
      props: {},  
      data () {  
      return {}  
      },  
      computed: { 
          // 从 store 取 getters 和 取 state 用法相同,都可以使用 mapState  
          // 具有响应式,但是不能修改  
          // 映射 getters(数组 + 对象)  
          ...mapState(useUserStore, ['month']),  
          ...mapState(useUserStore, {  
              age_Stage: 'ageStage'  
          }),  
          // 使用 mapWritableState 解构  
          ...mapWritableState(useUserStore, ['ageStage']),  
          ...mapWritableState(useUserStore, {  
              bir_month: 'month'  
          })  
      },  
      methods: {},  
      watch: {}  
      };  
      </script>  
      
      <template>
          <h2> 使用 mapState 解构 getters - 映射为计算属性 - 不能修改</h2>  
          <ul>  
              <li>月份:{{ month }}</li>  
              <li>是否成年:{{ age_Stage }}</li>  
          </ul>  
          <hr>  
          <button @click="month++">修改 - month</button>  
          <hr>  
          <br>  
      
          <h2> 使用 mapWritableState 解构 getters - 映射 getters 为当前组件的计算属性 - 具有响应式,一修改就会报错</h2>  
          <ul>  
              <li>月份:{{ bir_month }}</li>  
              <li>是否成年:{{ ageStage }}</li>  
          </ul>  
          <hr>  
          <button @click="bir_month++">修改 - month</button>  
      </template> 
      

五、Actions

  • actions 一般情况下是对 state 中的 数据进行修改 的 业务逻辑 函数actions 也可以是异步的,可以在其中 await任何API调用 甚至 其他操作;

5.1 定义actions

  • 组合式store

    • 可通过声明函数,再将其return暴露出去即可共享其函数;
    • 示例展示:
      import { defineStore } from 'pinia';  
      import {computed, ref} from 'vue';  
      
      // TODO 组合式API  
      const useUserStore = defineStore('user', () => {  
          // 1. 声明 state,使用 ref() 函数  
          const userName = ref('禁止摆烂_才浅')  
          const age = ref(22)  
          const gender = ref('男')  
          const city = ref('兰州')  
          const work = ref('初级前端开发工程师')  
          const birthday = ref('2000-01-01')  
      
          // 2.声明 getters ,使用 computed() 函数  
          // 只读 - 如果依赖的数据发生该改变,对应的 getters 也会重新计算  
          const month = computed( () => birthday.value.split('-')[1] )  
          const ageStage = computed( () => age.value >= 18 ? '成年' : '未成年')  
      
          // 3.声明 actions - 声明函数  
          const setUserInfo = (username, ageStage) => {  
              userName.value = username  
              age.value = ageStage  
          }  
      
          // 最后必须 return 出去  
          return ({  
              // state  
              userName,  
              age,  
              gender,  
              city,  
              work,  
              birthday,  
              // getters  
              month,  
              ageStage,  
              // actions  
              setUserInfo  
          })  
      });  
      
      export default useUserStore;
      
  • 选项式store

    • actions 选项中声明的函数即可共享函数,在其函数内可通过this来获取整个store实例;
    • 示例展示:
      import { defineStore } from 'pinia';  
      
      // TODO 选项式API  
      const useUserStore = defineStore('user', {  
          // 定义共享数据  
          state: () => ({  
              userName: '禁止摆烂_才浅',  
              age: 22,  
              gender: '男',  
              city: '兰州',  
              work: '初级前端开发工程师',  
              birthday: '2000-1-1'  
          }),  
          // 通过计算属性得到的新的共享数据,只读,不能修改,只有当依赖发生变化的时候,getters中的数据才会重i性能计算  
          getters: {  
              // 非箭头函数 - 通过 this 访问 store 实例  
              month () {  
                  return this.birthday.split('-')[1]  
              },  
              // 箭头函数 - 函数的第一个参数,为 store 实例  
              ageStage: store => {  
                  if (store.age < 18) return '未成年'  
                  return '成年'  
              }  
          },  
          // 定义共享的函数(可以是异步的),其主要作用是:修改 state 中的数据  
          actions: {  
              setUserInfo (username, age) {  
                  // this -> 当前 store 的实例对象  
                  this.userName = username  
                  this.age = age  
              }  
          }  
      });  
      
      export default useUserStore;
      

5.2 组件中访问actions

  • 组合式API
    • 直接引入对应的 store,通过 store 对象直接获取 actions
    • 🔺 注意
      • 如果想将 store 中的 actions 中函数 映射为 本地组件 的 函数,可将 store 解构 出 对应的 函数即可,也可自定义函数名,此处不能通过storeToRefs(store)函数
    • 示例展示:
      <script setup>  
      import { ref, reactive, computed, onMounted } from 'vue';  
      import useUserStore from '@/store/useUserStore'  
      import { storeToRefs } from 'pinia';  
      
      const userInfo = reactive({  
          username: '邵秋华',  
          age: 22.5  
      })  
      
      // TODO 获取 useUserStore 示例  
      const user_store = useUserStore()  
      
      // TODO 将 store 中 state 的数据映射为当前组件的计算属性 - 具有响应式,但是是只读  
      const user_userName = computed(() => user_store.userName)  
      const user_age = computed(() => user_store.age)  
      const user_work = computed(() => user_store.work)  
      
      // TODO 使用 storeToRefs() 从 store 解构想要的 state,具有响应式,可直接修改,可自定义名称  
      const { userName: myName, age: myAge } = storeToRefs(user_store)  
      
      // TODO 使用 computed 将 store 中 getters 的数据映射为当前组件的计算属性,只读 - 不能修改,一旦修改就会在控制台打印警告  
      const month = computed(() => user_store.month )  
      const ageStage = computed(() => user_store.ageStage)  
      
      // TODO 使用 storeToRefs() 将 store 中的 getters 的数据 解构 为 当前组件 的 计算属性,具有响应式,可重命名,只读 - 一旦修改,就会报错  
      const { month: bir_month, ageStage: age_stage } = storeToRefs(user_store)  
      
      // TODO 直接对 store 进行解构,得到 actions,可以进行重命名  
      const { setUserInfo: setStateData } = user_store  
      
      onMounted(() => {});  
      </script>  
      
      <template>  
          <h2>组合式API</h2>  
          <hr>  
          <h4>从 store 直接获取 state,具有响应式,可修改</h4>  
          <ul>  
              <li>{{user_store.userName}}</li>  
              <li>{{user_store.age}}</li>  
              <li>{{user_store.gender}}</li>  
              <li>{{user_store.city}}</li>  
              <li>{{user_store.work}}</li>  
          </ul>  
          <hr>  
          <button @click="user_store.age = 23">修改 - user_store.age</button> |  
          <button @click="user_store.city = '北京 / 上海 / 武汉 / 杭州 / 深圳'">修改 - user_store.city</button>  
          <hr>  
          <br>  
      
          <h4>通过 computed 将 store 中的 state 数据,映射为当前组件中的计算属性 - 具有响应式,但是是只读</h4>  
          <ul>  
              <li>{{user_userName}}</li>  
              <li>{{user_age}}</li>  
              <li>{{user_work}}</li>  
          </ul>  
          <hr>  
          <button @click="user_work = '中级前端开发工程师'">修改 - user_city</button>  
          <button @click="user_age = 23">修改 - user_age</button> |  
          <hr>  
          <br>  
      
          <h4>使用 storeToRefs() 从 store 解构想要的 state 为当前组件的数据,具有响应式,可直接修改,可自定义名称</h4>  
          <ul>  
              <li>{{myName}}</li>  
              <li>{{myAge}}</li>  
          </ul>  
          <hr>  
          <button @click="myAge = 23"> 修改 - myAge </button>  
          <br>  
          <hr>  
      
          <h4>通过 store 直接获取 getters,具有响应式,只读 - 不能修改(修改会报错)</h4>  
          <ul>  
              <li>月份:{{ user_store.month }}</li>  
              <li>是否成年:{{ user_store.ageStage }}</li>  
          </ul>  
          <hr>  
          <button @click="(user_store.month)++">修改 - month</button>  
          <button @click="user_store.ageStage = '嘻嘻哈哈'">修改 - age - 改变 ageStage</button>  
          <hr>  
          <br>  
      
          <h4>通过 computed 将 store 中的 getters 映射为 当前组件 的 计算属性,具有响应式,只读 - 修改会在控制台打印警告</h4>  
          <ul>  
              <li>月份:{{ month }}</li>  
              <li>是否成年:{{ ageStage }}</li>  
          </ul>  
          <button @click="month++">修改 - month</button>  
          <button @click="ageStage = '嘻嘻哈哈'">修改 - ageStage</button>  
          <hr>  
          <br>  
      
          <h4>通过 storeToRefs() 将 store 中的 getters 映射为 当前组件 的 计算属性,只读 - 修改会报错</h4>  
          <ul>  
              <li>月份:{{ bir_month }}</li>  
              <li>是否成年:{{ age_stage }}</li>  
          </ul>  
          <button @click="bir_month++">修改 - month</button>  
          <button @click="age_stage = '嘻嘻哈哈'">修改 - ageStage</button>  
          <br>  
      
          <h4>通过 store 直接读取 actions</h4>  
          <button @click="user_store.setUserInfo(userInfo.username, userInfo.age)">通过 store 直接读取的 actions 修改 state 中的数据</button>  
          <br>  
          <hr>  
      
          <h4>通过 storeToRefs() 将 store 中的 actions 解构 为 当前组件 的 function</h4>  
          <button @click="setStateData('张三', '32')">直接对 store 进行解构,得到 actions</button>  
      </template>
      
  • 选项式API
    • 可以使用 mapActions(storeObj, array | object) 辅助函数将 actions 映射为当前组件的函数;
      • 映射在 methods 中;
      • storeObj: 引入的 store
      • array | object:字符串数组形式 或 对象形式;
        • 【对象】:
          • key 为自定义当前组件的函数名,value字符串形式,是storeactions的函数名;
        • 【字符串数组】:
          • 直接将storeactions的函数映射为当前组件的函数,但是不能自定义名称;
    • 示例展示:
      <script>  
      /**  
      * 选项式API 使用 Pinia  
      * 1. 导入 mapState 函数(mapState 函数需要写在 计算属性中)  
      * 2. 导入 对应的 store 对象,作为 mapState 的第一个参数  
      */  
      import {mapActions, mapState, mapWritableState} from 'pinia';  
      import useUserStore from '@/store/useUserStore.js';  
      
      export default {  
      name: 'App',  
      component: {},  
      props: {},  
      data () {  
          return {  
              userInfo: {  
                  username: '邵秋华',  
                  age: 22.5  
              }  
          }  
      },  
      computed: {  
          /**  
          * mapState - 有两个参数:  
          * 参数1:导入的 store 对象  
          * 参数2:array(字符串数组) / object  
          * array(字符串数组):  
          * 将当前组件需要用到的数据(字符串形式)放到这个数组中;  
          * 不能进行重命名  
          * object:  
          * 可以重命名,key 就是行变量名, value 就是旧名  
          * 注意:  
          * mapState 将 store 的 state 映射为当前组件的计算属性  
          * 具有响应式(修改store中的state,当前组件中的数据也会发生变化),但是是只读的(不能修改)  
          */  
          ...mapState(useUserStore, ['userName', 'age']),  
          ...mapState(useUserStore, {  
              u_gender: 'gender',  
              u_work: 'work',  
              u_city: 'city'  
          }),  
          ...mapWritableState(useUserStore, {  
              user_age: 'age',  
              user_city: 'city'  
          }),  
          // 从 store 取 getters 和 取 state 用法相同,都可以使用 mapState  
          // 具有响应式,但是不能修改  
          // 映射 getters(数组 + 对象)  
          ...mapState(useUserStore, ['month']),  
          ...mapState(useUserStore, {  
              age_Stage: 'ageStage'  
          }),  
          // 使用 mapWritableState 解构  
          ...mapWritableState(useUserStore, ['ageStage']),  
          ...mapWritableState(useUserStore, {  
              bir_month: 'month'  
          })  
      },  
      methods: {  
          // 映射 actions 有两种方式,数组 + 对象(可以自定义名称接收)  
          // 数组形式  
          ...mapActions(useUserStore, ['setUserInfo']),  
          // 对象形式  
          ...mapActions(useUserStore, {  
              setStateData: 'setUserInfo'  
          })  
      },  
      watch: {}  
      };  
      </script>  
      
      <template>  
      <h2> 使用 mapState 访问 state - 映射为计算属性 - 具有响应式,但是是只读</h2>  
      <ul>  
          <li> {{ userName }} </li>  
          <li> {{ age }} </li>  
          <li> {{ u_gender }} </li>  
          <li> {{ u_city }} </li>  
          <li> {{ u_work }} </li>  
      </ul>  
      <hr>  
      <button @click="age++">修改 - age</button>  
      
      <h2> 使用 mapWritableState 访问 state - 映射为计算属性 - 具有响应式,可修改</h2>  
      <ul>  
          <li>{{ user_age }}</li>  
          <li>{{ user_city }}</li>  
      </ul>  
      <button @click="user_age = 23">修改 - user_age</button>  
      <button @click="user_city = '武汉 / 北京 / 上海 / 杭州'">修改 - user_city</button>  
      <hr>  
      <br>  
      
      <h2> 使用 mapState 解构 getters - 映射为计算属性 - 不能修改</h2>  
      <ul>  
          <li>月份:{{ month }}</li>  
          <li>是否成年:{{ age_Stage }}</li>  
      </ul>  
      <hr>  
      <button @click="month++">修改 - month</button>  
      <hr>  
      <br>  
      
      <h2> 使用 mapWritableState 解构 getters - 映射 getters 为当前组件的计算属性 - 具有响应式,一修改就会报错</h2>  
      <ul>  
          <li>月份:{{ bir_month }}</li>  
          <li>是否成年:{{ ageStage }}</li>  
      </ul>  
      <hr>  
      <button @click="bir_month++">修改 - month</button>  
      <br>  
      
      <button class="setUserInfo" @click="setUserInfo(userInfo.username, userInfo.age)">修改 state 中的数据(数组形式映射)</button>  
      <br>  
      <button class="setUserInfo" @click="setStateData(userInfo.username, userInfo.age)">修改 state 中的数据(对象形式映射)</button>  
      </template>  
      
      <style scoped>  
          .setUserInfo {  
          margin-top: 10px;  
          background-color: #00ffe3;  
          }  
      </style>
      

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1511507.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[C语言] 数据存储

类型意义&#xff1a; 1.类型决定内存空间大小&#xff08;大小决定了使用范围&#xff09; 2.如何看待内存空间的视角 类型分类 整形 类型大小(字节)short2int4long4long8 浮点型 类型大小(字节)float4double8long double12 构造类型 数组结构性struct联合union枚举enum 指…

七个项目掌握freertos

1、闪烁LED&#xff1a; 最基本的示例项目&#xff0c;涉及到创建一个简单的任务&#xff0c;用于控制LED的闪烁。这个项目会教你如何初始化FreeRTOS并创建任务。 #include "FreeRTOS.h" #include "task.h" #define LED_PIN (某个GPIO引脚)void vBlinkTas…

BUGKU-WEB cookies

题目描述 题目截图如下&#xff1a; 进入场景看看&#xff1a; 解题思路 看源码看F12&#xff1a;看请求链接看提示&#xff1a;cookies欺骗 相关工具 插件&#xff1a;ModHeader或者hackbarbase64解密 解题步骤 看源码 就是rfrgrggggggoaihegfdiofi48ty598whrefeoia…

2000-2023年7月全国各省专利侵权结案案件数量数据

2000-2023年7月全国各省专利侵权结案案件数量数据 1、时间&#xff1a;2000-2023年7月 2、指标&#xff1a;地区、年份、专利侵权纠纷行政案件-结案数目 3、范围&#xff1a;31省 4、来源&#xff1a;国家知识产权局&#xff0c;并由该局每个月公布的数据汇总而成 5、指标…

STM32CubeIDE基础学习-STM32CubeIDE软件代码编写格式问题

STM32CubeIDE基础学习-STM32CubeIDE软件代码编写格式问题 前言 代码编写最好就是规定一个格式&#xff0c;或者建立一个偏好&#xff0c;这样写出来的代码就方便自己管理了&#xff0c;不然代码乱放下次打开工程就很难找到具体位置&#xff0c;如果规定了格式&#xff0c;那么…

LeetCode中的returnSize和returnColumnSize

今天这篇比较水&#xff0c;不过本文要讲的内容是我曾经遇到过的问题&#xff0c;也可能是大部分人在初次接触力扣时的一些疑问。当时遇到这个问题也是上网找了许久没有找到满意的答案&#xff0c;现在自己明白了&#xff0c;也希望能够帮助还抱有疑惑的各位解答。 如果我说的…

认证授权与JWT

认证授权与JWT 1、认证授权概念介绍1.1 什么是认证1.2 什么是授权 2、权限数据模型3、RBAC权限模型3.1 介绍3.2 基于角色访问控制3.3 基于资源访问控制 4、常见认证方式4.1 Cookie-Session4.2 jwt令牌无状态认证 5 常见技术实现6.Jwt介绍6.1 JWT简介6.2.Jwt组成 7、JWT使用7.1 …

2024-3-12尾盘一致转分歧

安彩高科开一字符合预期&#xff0c;昨天风光储锂电大涨&#xff0c;理应给大溢价&#xff0c;超预期是 艾艾精工 高开秒板&#xff0c;立航科技高开分歧反核承接良好回封一致&#xff0c;带动了低空经济板块高潮&#xff0c;低空经济开始往 碳纤维 方向扩散。盘中我说了 三晖…

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的火焰检测系统(Python+PySide6界面+训练代码)

摘要&#xff1a;本研究详述了一种采用深度学习技术的火焰检测系统&#xff0c;该系统集成了最新的YOLOv8算法&#xff0c;并与YOLOv7、YOLOv6、YOLOv5等早期算法进行了性能评估对比。该系统能够在各种媒介——包括图像、视频文件、实时视频流及批量文件中——准确地识别火焰目…

蓝桥杯真题讲解:子矩阵(二维滑动窗口)

蓝桥杯真题讲解&#xff1a;子矩阵&#xff08;二维滑动窗口&#xff09; 一、视频讲解二、正解代码 一、视频讲解 蓝桥杯真题讲解&#xff1a;子矩阵&#xff08;二维滑动窗口&#xff09; 二、正解代码 //二维单调队列 #include<bits/stdc.h> #define endl \n #def…

Midjourney绘图欣赏系列(十一)

Midjourney介绍 Midjourney 是生成式人工智能的一个很好的例子&#xff0c;它根据文本提示创建图像。它与 Dall-E 和 Stable Diffusion 一起成为最流行的 AI 艺术创作工具之一。与竞争对手不同&#xff0c;Midjourney 是自筹资金且闭源的&#xff0c;因此确切了解其幕后内容尚不…

(二)运行自己的stable-diffusion

前面的步骤如https://datawhaler.feishu.cn/docx/BwjzdQPJRonFh8xeiSOcRUI3n8b所示 拷贝、解压文件后&#xff0c;进入到stable-diffusion-webui的文件夹中&#xff0c;文件如下&#xff1a; 启动&#xff1a; 运行效果&#xff1a; 由于生成了好几个图&#xff0c;所以…

布隆过滤器(做筛选器索引)

什么是布隆过滤器 布隆过滤器&#xff08;Bloom Filter&#xff09;是1970年由布隆提出的。它实际上是一个很长的二进制向量和一系列随机映射函数。布隆过滤器可以用于检索一个元素是否在一个集合中。 它的优点是空间效率和查询时间都比一般的算法要好的多&#xff0c;缺点是…

学习vue3第四节(ref以及ref相关api)

主要记录以下api&#xff1a;ref()、isRef()、unref()、 shallowRef()、triggerRef()、customRef() 1、ref() 定义 接受一个内部值&#xff0c;返回一个响应式的、可更改的 ref 对象&#xff0c;此对象只有一个指向其内部值的属性 .value&#xff0c;.value属性用于追踪并且存…

I2C驱动AT24C02

文章目录 一、硬件电路设备地址 二、使用步骤字节写:页写入:任意写:任意读: 一、硬件电路 设备地址 设备需要一个8位的设备地址字&#xff0c;后面跟着一个启动条件&#xff0c;以使芯片能够进行读或写操作 设备地址字由一个强制的1,0序列的前四个最有效的位&#xff0c;如所示…

简单使用国产数据库—达梦

达梦数据库是一款由中国的达梦软件公司开发的关系数据库管理系统&#xff08;RDBMS&#xff09;&#xff0c;它在业界以其高性能、可扩展性和安全性而著称。该系统广泛应用于各种应用程序的数据存储和管理&#xff0c;满足用户对于数据处理和管理的多样化需求。 安装好的达梦数…

容联云孙昌勋:聚焦“营销服”数智化转型,构筑金融业增长引擎

在每日经济新闻2024全国两会特别报道中&#xff0c;容联云创始人兼CEO孙昌勋针对“人工智能”在具体行业如何开展时表示&#xff1a;“随着泛金融行业用户渠道与体验发生变化&#xff0c;金融业对营销、销售、服务等场景的数智化改造有巨大的需求&#xff0c;人工智能等科技投入…

Qt/QML编程之路:openglwidget和倒车影像的切换(43)

关于如何实现一个基于OpenGL的3d 图形,这个有很多专门的介绍,我在开发中遇到了这么一个问题: 如何实现一个倒车影像的video显示与一个3D物体显示的切换,因为开窗在同样的一个位置,如果车子倒车启动,则需要将原本显示3D的地方切换为视频图像的显示。 class testOpenGl : …

docker容器镜像管理+compose容器编排(持续更新中)

目录 一、 Docker的基本组成 二、 容器和镜像的关系 2.1 面向对象角度 2.2 从镜像容器角度 三、 容器命令 3.1 使用Ubuntu 3.1.1 下载镜像 3.1.2 新建和启动容器 run 3.1.3交互式 compose编排与部署 1. docker-compose部署 2. docker-compose.yml模板 …

鸿蒙Harmony应用开发—ArkTS声明式开发(基础手势:PluginComponent)

提供外部应用组件嵌入式显示功能&#xff0c;即外部应用提供的UI可在本应用内显示。 说明&#xff1a; 该组件从API Version 9开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。本组件为系统接口。 子组件 无 接口 PluginComponent(value:…