Vue3.0 状态管理库Pinia的核心属性

关于Pinia

如果你之前使用过Vue2.0的状态管理Vuex,那么上手Pinia将会变的十分简单

核心部分 Store

  1. store是一个保存状态和业务逻辑的实体,它并不与你的组件树绑定;换句话说,它承载着全局状态;它有点像一个永远存在的组件,每个组件都可以读取和写入它
  2. store它有三个概念,stategettersactions,我们可以l理解成组件中的datacomputedmethods
  3. 在项目中的src\store文件夹下不同的store.js文件
  4. store是用defineStore(name, function | options)定义的,建议其函数返回的值命名为use…Store方便理解
    a. 参数name:名字,必填值且唯一
    b. 参数function|options:可以是对象或函数形式
    ■ 对象形式【选项模式】,其中配置state、getters和actions选项
    ■ 函数形式【组合模式,类似组件组合式API的书写方式】,定义响应式变量和方法,并且return对应的变量和方法;ref()相当于state,computed()相当于getters,function()相当于actions

Store中的State

state是store的核心部分,主要存储的是共享的数据

  • . store采用的是选项式模式时,state选项为函数返回的对象,在其定义共享的数据
  • . store采用的是组合式模式时,在其函数内定义的ref变量,最终return出去来提供共享的数据
// 这里举例都用组合式api
import {defineStore} from "pinia";
import {ref} from "vue";

export const useUserStore = defineStore('user', () => {
    const age = ref(27)
    const level = ref(5)
    const account = ref('SD77842')
    const nickname = ref('二十四桥明月夜')
    
    return { age, level, account, nickname } // 将数据暴露出去,共享给需要的组件
})

组件中访问State

  1. 在选项式 API 组件中,可以使用mapState(storeObj, array | object)帮助器将状态属性映射为只读计算属性
    a. storeObj引入的store对象
    b. array | object:字符串数组形式或者对象形式
    ■ 【字符串数组形式】直接将store中state的数据映射为当前组件的计算属性,但是不能自定义名称
    ■ 【对象形式时】key为自定义当前组件的计算属性名,value字符串形式,是store中state的共享数据
    提示:mapState()函数映射到组件中的计算属性是只读的,如果想在组件中响应式修改state的数据,则应该选择mapWritableState()函数来映射计算属性
  2. 在组合式 API 组件中,直接引入对应的store,通过store对象直接获取和修改state
    提示:
    如果想在组件中自定义变量来接收store中的state中共享的数据,我们可以这样做:
    ● 使用computed(() => store.dataName),具有响应式,但是只读形式
    ● 使用storeToRefs(store)从store解构想要的state,具有响应式,可直接修改,可自定义名称
<script setup>
import { useUserStore } from "@/stores/counter.js";
import { storeToRefs } from "pinia";
import { computed } from "vue";
import UserVue from '@/components/User.vue'

// 获取 UserStore 实例
const user_store = useUserStore();

// 通过computed()将store中state映射到当前计算属性,具有响应性,但是是只读的
const user_age = computed(() => user_state.age);
const user_level = computed(() => user_state.level);
const user_account = computed(() => user_state.account);
const user_nickname = computed(() => user_state.nickname);

// storeToRefs 将store中state解构为组件的数据,具有响应式,还可以响应式修改
const {
  age,
  level,
  account: userAccount,
  nickname: userNickname,
} = storeToRefs(user_store);
</script>

Store中的Getters

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

  1. store采用的是选项式模式时,getters选项中声明的函数即为计算属性
    a. 在其函数内可通过this关键字来获取store实例,也可通过方法的第一个参数得到store实例
    b. 如果采用的是箭头函数的话,无法使用this关键字,为了更方便使用store中实例,可为其箭头函数设置第一个参数来获取store实例
  2. store采用的是组合式模式时,可通过computed()函数通过计算得到新的数据,再将其return暴露出去即可
import { defineStore } from "pinia"
import { computed, ref } from "vue"

export const useUserStore = defineStore('user', () => {
    const birthday = ref('1992-12-27')
    const age = ref(30)

    // 声明通过计算得到的共享数据,是只读的,如果依赖的数据发生变化则会重新计算
    const month = computed(() => {
        return birthday.value.split('-')[1]
    })

    const ageStage = computed(() => {
        if (age.value < 18) return '未成年'
        if (age.value < 35) return '青年'
        if (age.value < 50) return '中年'
        if (age.value >= 50) return '老年'
    })

    return { birthday, age, month, ageStage }

})

在组件中使用Getters

  1. 选项式API的组件中,访问store中的getters和访问state类似,同样可使用mapState()帮助器将getters属性映射为只读计算属性
    注意:如果采用mapWritableState()帮助器将store中的getters映射为组件内部的计算属性,依旧可以具有响应式,一旦对其进行修改则会报错
  2. 在组合式API组件中,访问store中的getters和访问state类似,直接引入对应的store,通过store对象直接获取getters,但是如果对其进行修改则会报错
    提示:
    如果想将store中的getter中共享的数据映射为本地组件的计算属性,我们可以这样做:
    ● 使用computed(() => store.getterName),具有响应式,但是只读形式
    ● 使用storeToRefs(store)从store解构getter依旧
<script setup>
import { storeToRefs } from "pinia";
import { computed } from "vue";
import { useUserStore } from "@/stores/counter.js";

// store实例,可以直接通过store获取getters,但是是只读的,如果一旦修改则会报错
const user_store = useUserStore();

// 通过computed将getters映射为自己的计算属性,但是是只读的,如果一旦修改则会警告
const birthday_month = computed(() => user_store.month);
const user_age_stage = computed(() => user_store.ageStage);

// 通过storeToRefs将getters解构为自己的计算属性,但是是只读的,如果一旦修改则会警告
const { month, ageStage: userAgeStage } = storeToRefs(user_store);

// 将 state 解构为自己的数据
const { birthday, age } = storeToRefs(user_store);
</script>

Store中的Actions

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

  1. store采用的是选项式模式时,actions选项中声明的函数即可共享其函数,在其函数内可通过this来获取整个store实例
  2. store采用的是组合式模式时,可通过声明函数,再将其return暴露出去即可共享其函数
import {defineStore} from "pinia"
import {ref} from "vue";

export const useUserStore = defineStore('user', () => {
    const nickname = ref('自古风流')
    const age = ref(20)

    // 定义函数(注意:形参不要和 ref 名冲突)
    function setUserInfo(user_nickname, user_age) {
        nickname.value = user_nickname
        age.value = user_age
    }

    function setUserInfoByObject(user) {
        // 可通过 `this` 来获取当前 store 实例
        nickname.value = user.nickname
        age.value = user.age
    }

    return {nickname, age, setUserInfo, setUserInfoByObject} // 暴露函数即可共享函数
})

组件中访问Actions

  1. 在选项式 API 组件中,可以使用mapActions(storeObj, array | object)帮助器将actions映射为当前组件的函数
    a. storeObj引入的store对象
    b. array | object:字符串数组形式或者对象形式
    ■ 【字符串数组形式】直接将store中actions的函数映射为当前组件的函数,但是不能自定义名称
    ■ 【对象形式时】key为自定义当前组件的函数名,value字符串形式,是store中actions的函数名
  2. 在组合式API组件中,直接引入对应的store,通过store对象直接获取actions
    提示:如果想将store中的actions中函数映射为本地组件的函数,可将store解构出对应的函数即可,也可自定应函数名,此处不可通过storeToRefs(store)函数
<script setup>
import { useUserStore } from "@/stores/counter.js";
import { storeToRefs } from "pinia";

// 可直接使用 store 执行 actions
const user_store = useUserStore();
const { nickname, age } = storeToRefs(user_store);

// 可将 store 中的 actions 映射为自己的函数,可自定映射的函数名(不可使用 storeToRes 函数)
const { setUserInfo, setUserInfoByObject: set_user_info_object } = user_store;
</script>

文章总结

本文总结了Vue3.0 状态管理库Pinia的一些核心属性,
如果你想更多的了解Pinia可以看我之前的文章: Vue3.0 状态管理库Pinia的前世今生
希望本文能对你有所帮助。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是搭建 Vue 3.0 + Vite + Pinia + TypeScript 的步骤: 1. 安装 Node.js,推荐使用 LTS 版本。 2. 安装 Vite: ``` npm init vite-app my-project ``` 这里我们使用 Vite 初始化一个新项目,名称为 my-project。 3. 安装依赖: ``` cd my-project npm install ``` 4. 安装 Vue 3.0: ``` npm install vue@next ``` 5. 安装 Pinia: ``` npm install pinia ``` 6. 安装 TypeScript: ``` npm install --save-dev typescript ``` 7. 配置 TypeScript: 在项目根目录下创建 `tsconfig.json` 文件,内容如下: ```json { "compilerOptions": { "target": "esnext", "module": "esnext", "strict": true, "jsx": "preserve", "sourceMap": true, "moduleResolution": "node", "esModuleInterop": true, "experimentalDecorators": true, "emitDecoratorMetadata": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true }, "include": ["src/**/*.ts", "src/**/*.tsx", "tests/**/*.ts", "tests/**/*.tsx"], "exclude": ["node_modules"] } ``` 8. 安装 Pinia Devtools(可选): ``` npm install @pinia/devtools --save-dev ``` 9. 在 `main.ts` 中进行配置: ```typescript import { createApp } from 'vue' import { createPinia } from 'pinia' import App from './App.vue' const app = createApp(App) // 创建 Pinia 实例 const pinia = createPinia() // 将 Pinia 实例挂载到 app 上 app.use(pinia) app.mount('#app') ``` 10. 编写组件: 在 `src` 目录下创建一个 `components` 目录,然后创建一个 `HelloWorld.vue` 组件: ```vue <template> <div> <h1>Hello, {{ name }}</h1> <button @click="increase">Increase</button> <p>{{ count }}</p> </div> </template> <script lang="ts"> import { defineComponent } from 'vue' import { useStore } from 'pinia' export default defineComponent({ name: 'HelloWorld', setup() { const store = useStore() const name = store.getters.getName const count = store.state.count const increase = () => { store.commit('increase') } return { name, count, increase } }, }) </script> ``` 11. 在 `App.vue` 中使用组件: ```vue <template> <HelloWorld /> </template> <script lang="ts"> import { defineComponent } from 'vue' import HelloWorld from './components/HelloWorld.vue' export default defineComponent({ name: 'App', components: { HelloWorld, }, }) </script> ``` 12. 运行项目: ``` npm run dev ``` 至此,我们已经成功搭建了 Vue 3.0 + Vite + Pinia + TypeScript 的项目。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值