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

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.rhkb.cn/news/274565.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PaddlePaddle----基于paddlehub的OCR识别

Paddlehub介绍 PaddleHub是一个基于PaddlePaddle深度学习框架开发的预训练模型库和工具集&#xff0c;提供了丰富的功能和模型&#xff0c;包括但不限于以下几种&#xff1a; 1.文本相关功能&#xff1a;包括文本分类、情感分析、文本生成、文本相似度计算等预训练模型和工具。…

【力扣hot100】刷题笔记Day25

前言 这几天搞工作处理数据真是类似我也&#xff0c;还被老板打电话push压力有点大的&#xff0c;还好搞的差不多了&#xff0c;明天再汇报&#xff0c;赶紧偷闲再刷几道题&#xff08;可恶&#xff0c;被打破连更记录了&#xff09;这几天刷的是动态规划&#xff0c;由于很成…

共基法律考点大默写

法是由国家制定或认可的&#xff0c;&#xff0c;能够反应统治阶级意志&#xff0c;反映着被一定物质生活条件决定的统治阶级&#xff08;在社会主义社会是工人阶级为首的广大人民&#xff09;的意志。 指引作用。法律为人们提供既定的行为模式&#xff0c;指引人们在法律范围内…

Qt插件之输入法插件的构建和使用(一)

文章目录 输入法概述输入法插件实现及调用输入键盘搭建定义样式自定义按钮实现自定义可拖动标签数字符号键盘候选显示控件滑动控件手绘输入控件输入法概述 常见的输入法有三种形式: 1.系统级输入法 2.普通程序输入法 3.程序自带的输入法 系统级输入法就是咱们通常意义上的输入…

Vue3全家桶 - Vue3 - 【8】模板引用【ref】(访问模板引用 + v-for中的模板引用 + 组件上的ref)

模板引用【ref】 Vue3官网-模板引用&#xff1b;如果我们需要直接访问组件中的底层DOM元素&#xff0c;可使用vue提供特殊的ref属性来访问&#xff1b; 一、 访问模板引用 在视图元素上采用ref属性来设置需要访问的DOM元素&#xff1a; 该 ref 属性可采用 字符串 值的执行设…

蝙蝠避障:我生活中的一道光

盲人的世界&#xff0c;是无尽的黑暗。看不见光&#xff0c;看不见色彩&#xff0c;甚至看不见自己的手。但在这个黑暗的世界里&#xff0c;我找到了一个光明的出口&#xff1a;一款可以障碍物实时检测的名为蝙蝠避障的盲人软件。 这款软件就像是我的一双眼睛。它通过先进的激光…

第五十六回 徐宁教使钩镰枪 宋江大破连环马-飞桨图像分类套件PaddleClas初探

宋江等人学会了钩镰枪&#xff0c;大胜呼延灼。呼延灼损失了很多人马&#xff0c;不敢回京&#xff0c;一个人去青州找慕容知府。一天在路上住店&#xff0c;马被桃花山的人偷走了&#xff0c;于是到了青州&#xff0c;带领官兵去打莲花山。 莲花山的周通打不过呼延灼&#xf…

【日常记录】【工具】随机生成图片的网站 Lorem Picsum

文章目录 1、介绍2、获取固定宽高的图片3、处理图片缓存4、 Emmet 缩写语法 1、介绍 Lorem Picsum 是一个免费的图片占位符服务&#xff0c;可以用于网站、应用程序或任何需要占位符图片的地方。它提供了一个简单的 API&#xff0c;可以通过 HTTP 请求获取随机图片&#xff0c;…

安信可IDE(AiThinker_IDE)编译ESP8266工程方法

0 工具准备 AiThinker_IDE.exe ESP8266工程源码 1 安信可IDE&#xff08;AiThinker_IDE&#xff09;编译ESP8266工程方法 1.1 解压ESP8266工程文件夹 我们这里使用的是NON-OS_SDK&#xff0c;将NON-OS_SDK中的1_UART文件夹解压到工作目录即可 我这里解压到了桌面&#xff0c…

软考73-上午题-【面向对象技术2-UML】-UML中的图4

一、构件图&#xff08;组件图&#xff09; 1-1、构件图的定义 展现了&#xff0c;一组构件之间的组织和依赖。 构件图专注于系统的静态实现图。 构件图与类图相关&#xff0c;通常把构件映射为一个、多个类、接口、协作。 【回顾】&#xff1a; 类图展示了一组对象、接口、…

加速 Webpack 构建:提升效率的秘诀

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

详解DSLS达索许可管理器的安装与配置

DSLS的安装与配置 一、DSLS下载二、安装DLS三、使用DSLS四、更改计算机ID五、部分常见DSLS相关问题 一、DSLS下载 下载地址&#xff1a;https://software.3ds.com/?ticketST-5190987-dUM0dflc6zfjf04F5EXx-cas 注意&#xff1a;需要一个注册了的达索账号才能登录进去下载 一…

内网渗透-跨域环境渗透-1

目录 smbclient工具 mimikatz工具 Kerbers协议 NTLM认证 hash传递攻击&#xff08;PTH攻击&#xff09; 黄金票据攻击 白银票据 MS14-068 smbclient工具 在linux里面连接远程windows共享目录&#xff0c;可以使用这个工具 ​ 第一种连接方式&#xff1a;smbclient -L 目…

git - 笔记

为什么要学习Git 为什么要学习Git软件 为什么学习 因为在主流开发中&#xff0c;基于互联网软件开发的项目都会使用Git软件来进行项目开发过程中的资源管理 比如人力资源 代码资源 比如前端资源 .html .java等代码资源 文档资源 像项目开发中涉及到的需求文档等 这种项目中管理…

在文件夹下快速创建vue项目搭建vue框架详细步骤

一、首先在你的电脑目录下新建一个文件夹 进入该文件夹并打开控制台&#xff08;输入cmd指令&#xff09; 进入控制台后输入 vue create springboot_vue (自己指定名称) 如果出现这类报错如&#xff1a;npm install 的报错npm ERR! network request to http://registry.cnp…

Centos7安装postgresql14步骤

1、进入网址 https://www.postgresql.org/download/ 2、按步骤执行 # Install the repository RPM: sudo yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm# Install PostgreSQL: sudo yum install -y…

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

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

删除数据表

oracle从入门到总裁:​​​​​​https://blog.csdn.net/weixin_67859959/article/details/135209645 删除数据表属于数据库对象的操作 drop table 表名称; 删除 emp30 表 SQL> drop table emp30;表已删除。 上面这个语句运行后&#xff0c;就会把数据表 emp30 删除 在…

东京工业大学最新!一种具有多周期特征描述的精确ORB提取器

作者&#xff1a;小柠檬 | 来源&#xff1a;3DCV 在公众号「3DCV」后台&#xff0c;回复「原论文」可获取论文pdf 添加微信&#xff1a;dddvision&#xff0c;备注&#xff1a;3D高斯&#xff0c;拉你入群。文末附行业细分群 详细内容请关注3DCV 3D视觉精品课程&#xff1a;…

数据结构 第2章:线性表

文章目录 2.1 线性表的定义和操作2.1.1 线性表的基本概念2.1.2 线性表的基本操作 2.2. 顺序表2.2.1. 顺序表的基本概念2.2.2. 顺序表的实现2.2.3. 顺序表的基本操作 2.3 链表2.3.1 单链表的基本概念2.3.2 单链表的实现2.3.3 单链表的插入2.3.4. 单链表的删除2.3.5. 单链表的查找…