- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
温馨提示:本文以vue3+vite+ts举例,vite配置和ts语法侧重较少,比较适合有vuex或者vue基础的小伙伴们儿查阅.
yarn add pinia
npm install pinia
pnpm add pinia
main.ts
中直接引入pinia 在 src/main.ts 中引入pinia(根存储),并传递给应用程序.
import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
// 1-创建一个 pinia(根存储)
import { createPinia } from 'pinia'
const app = createApp(App)
// 2-告诉应用程序,我们将使用pinia
const pinia = createPinia();
// 以插件形式传递给app
app.use(pinia);
app.mount('#app');
.ts
文件引入pinia 在根目录下新建文件夹,这里我命名为 store ,再在文件夹下新建一个 index.ts 文件( src/store/index.ts ),用以配置和引入pinia.
// 1-创建一个 pinia(根存储)
import { createPinia } from 'pinia'
// 2-定义pinia实例
const pinia = createPinia();
// 3-暴露pinia实例
export default pinia;
然后在 src/main.ts 中使用.
......
import pinia from '@/store/index.ts'
app.use(pinia);
......
其实和方式一没啥区别,只是为了保持 main.ts 文件整洁,并且方便配置pinia.
pinia与vuex差不多,相比于vuex,少了 mutation 和 modules .
pinia创建仓库,有 选项式写法 和 组合式写法 .
在根目录下创建一个文件夹store ( src/store ),在store文件夹中可以创建你的仓库,比如下面我创建了一个名为user的仓库 ( src/store/user.ts ).
// 选项式写法
// 1-引入api
import { defineStore } from "pinia";
// 2-定义仓库
const store = defineStore('user', {
// 3-设置组件共享的状态,相当于组件的data
state: () => ({
userInfo: {
name: '老刘',
sex: '男',
age: 17,
isStudent: false
},
token: '5201314',
password: '123456',
}),
// 3-设置状态计算值,相当于组件的computed
getters: {
name: (state) => state.userInfo.name,
sex: (state) => state.userInfo.sex,
},
// 3-设置组件共享的方法,相当于组件的methods
actions: {
addAge() {
this.userInfo.age++;
}
}
});
// 最后别忘了把仓库暴露出去哦
export default store;
上面的仓库 ( src/store/user.ts )组合式写法如下:
// 组合式写法
// 1-引入pinia的api
import { defineStore } from "pinia";
// 2-引入vue3相关api
import { ref, reactive, computed } from 'vue';
// 3-定义仓库,注意第二个参数需要传入一个函数,函数需要返回一个对象!
const store = defineStore('user', () => {
// 4-在这里面可以像在组件中一样,使用vue3的API,定义响应式数据
const userInfo = reactive({
name: '老刘',
sex: '男',
age: 17,
isStudent: false
});
const token = ref('5201314');
const password = ref('123456');
// 这里computed的作用相当于getters
const name = computed(() => userInfo.name);
const sex = computed(() => userInfo.sex);
// 4-还可以定义方法
function addAge() {
userInfo.age++;
}
// 5-然后把需要共享的数据或方法,装进一个对象,return出去
return {
userInfo,
token,
password,
name,
sex,
addAge
}
});
// 最后别忘了把仓库暴露出去哦
export default store;
TIP 。
还可以在仓库中使用 watch 、 watchEffect 等vue3的API喔~.
import { ref, reactive, computed, watch } from 'vue'; const store = defineStore('user', () => { const userInfo = reactive({ age: 17, }); // 使用vue3的watch()函数,可以对仓库状态进行监听 watch(() => userInfo.age, (val) => { console.log(val); }); });
完成了上面的工作后,我们就可以在组件中愉快地使用pinia啦! 。
下面以 src/App.vue 作为示例.
<template>
</template>
<script setup lang="ts">
// 1-引入刚刚自定义的仓库,模块名store 可以自定义
import store from '@/store/user.ts';
// 2-使用仓库,仓库实例名userStore 可以自定义
const userStore = store();
</script>
state
和 getters
在模板和script中,state和getters可以看作仓库实例(如 userStore )的属性,直接加 . 访问即可.
<template>
<div>
<!-- 1-访问仓库的计算属性getters -->
<span>姓名:{{ userStore.name }}</span>
<span>性别:{{ userStore.sex }}</span>
<!-- 1-访问仓库的状态state -->
<span>年龄:{{ userStore.userInfo.age }}</span>
<span>是否学生:{{ userStore.userInfo.isStudent ? '是' : '否' }}</span>
</div>
</template>
<script setup lang="ts">
import store from '@/store/user.ts';
const userStore = store();
// 1-访问state和getters,类似于reactive响应式数据的访问
console.log('userStore', userStore);
console.log('姓名:', userStore.name);
console.log('性别:', userStore.sex);
console.log('年龄:', userStore.userInfo.age);
console.log('是否学生:', userStore.userInfo.isStudent ? '是' : '否');
</script>
userStore Proxy(Object) {$id: 'user', $onAction: ƒ, $patch: ƒ, $reset: ƒ, $subscribe: ƒ, …}[[Handler]]: Object[[Target]]: Object[[IsRevoked]]: false
姓名: 老刘
性别: 男
年龄: 17
是否学生: 否
actions
使用仓库方法与访问仓库state类似,仓库实例后直接加 . 调用即可.
<template>
<div>
<!-- 按钮点击,年龄+1 -->
<button @click="onAddAge">年龄+1</button>
<span>年龄:{{ userStore.userInfo.age }}</span>
</div>
</template>
<script setup lang="ts">
import store from '@/store/user.ts';
const userStore = store();
// 按钮点击触发
function onAddAge() {
// 1-使用仓库的actions
userStore.addAge();
}
</script>
state
与vuex不同,pinia支持在组件中直接修改 state .
<template>
<div>
<!-- 按钮点击,年龄+1 -->
<button @click="onAddAge">年龄+1</button>
<span>年龄:{{ userStore.userInfo.age }}</span>
</div>
</template>
<script setup lang="ts">
import store from '@/store/user.ts';
const userStore = store();
// 按钮点击触发
function onAddAge() {
// 1-直接修改state
userStore.userInfo.age++;
}
</script>
actions
进行修改 src/store/user.ts 。
......
const store = defineStore('user', () => {
......
// 1-定义方法
function addAge() {
userInfo.age++;
}
// 2-return出去
return {
addAge
}
});
// 3-导出仓库
export default store;
src/App.vue 。
<template>
<div>
<!-- 按钮点击,年龄+1 -->
<button @click="onAddAge">年龄+1</button>
<span>年龄:{{ userStore.userInfo.age }}</span>
</div>
</template>
<script setup lang="ts">
import store from '@/store/user.ts';
const userStore = store();
// 按钮点击触发
function onAddAge() {
// 4-使用仓库的方法
userStore.addAge();
}
</script>
通过仓库实例(如 userStore )的 $patch 方法,可以对 state 同时应用多个更改.
<script setup lang="ts">
......
function changeState() {
console.log(userStore.token); // '5201314'
console.log(userStore.password); // '123456'
// $patch()接收一个对象,对象内的属性是 需要变更的state
// 注意是变更,新增state是无效的!
userStore.$patch({
token: '1024',
password: '654321'
});
console.log(userStore.token); // '1024'
console.log(userStore.password); // '654321'
}
</script>
上面的方法每次进行批量修改都需要传入一个新对象,有时候使用起来并不方便。下面是另一种写法, $patch 接受一个函数来批量修改集合内部分对象。(推荐) 。
<script setup lang="ts">
......
function changeState() {
// 这里的any是typescript的类型标注,可以不用理会
// 回调函数的参数state就是 仓库目前的state
userStore.$patch((state: any) => {
state.token = '1024';
state.password = '654321';
});
}
</script>
通过仓库实例(如 userStore )的 $state 属性 ,来为新对象 替换 仓库的整个状态.
pinia官网提到整体替换state的方法,但并未说明是否保留数据响应式。经笔者实践,这种方法 会丢失数据的响应式 ,所以 不推荐使用 .
<script setup lang="ts">
......
function updateStore() {
userStore.$state = {
userInfo: {
name: '老王',
sex: '男',
age: 66,
isStudent: false
}
};
}
</script>
state
通过调用仓库实例上的 $reset() 方法将状态 重置 到其初始值.
<script setup lang="ts">
......
function resetStore() {
userStore.$reset();
}
</script>
$reset()
的坑 细心的你会发现,仓库 state 并没有重置,然后你打开你的的控制台,你会惊讶地发现它报了这么一个错误:
这时候请你不要慌,先冷静地看一下报错信息.
这里翻译一下: Store "user"是使用setup语法构建的,不实现$reset() 。(猜测是pinia的缺陷) 。
所以,根据报错信息,这里提供下面两种解决方案.
使用 选项式Options API编写pinia仓库 ,并且 在组件中不能用script setup语法,要使用setup函数进行开发.
src/store/user.ts 。
......
// 使用选项式Options API编写仓库
const store = defineStore('user', {
// 3-设置组件共享的状态,相当于组件的data
state: () => ({
userInfo: {
name: '老刘',
sex: '男',
age: 17,
isStudent: false
},
token: '5201314',
password: '123456',
}),
});
export default store;
src/App.vue 。
<!-- 这里不能用script setup,否则依然报错 -->
<script lang="ts">
import store from '@/store/user.ts';
export default {
setup() {
const userStore = store();
function resetStore() {
// 重置state
userStore.$reset();
}
// 把响应式数据或方法return出去
return {
userStore,
resetStore
}
},
}
</script>
$reset()
方法(推荐) 原理:自定义pinia插件(Plugins),利用 $patch() 重置整个 state .
在之前创建的pinia配置文件中修改( src/store/index.ts ).
import { createPinia } from 'pinia';
const pinia = createPinia();
// 1-使用pinia自定义插件
pinia.use(({ store }) => {
// 2-获取最开始的State
const initialState = JSON.parse(JSON.stringify(store.$state));
// 3-重写$reset()方法
store.$reset = () => {
// 4-利用$patch()批量变更state,达到重置state的目的
store.$patch(initialState);
}
});
export default pinia;
推荐使用这种方法,这样就可以在 script setup 中愉快地使用pinia啦! 。
src/store/index.ts 。
import { createPinia } from 'pinia';
const pinia = createPinia();
pinia.use(({ store }) => {
const initialState = JSON.parse(JSON.stringify(store.$state));
store.$reset = () => {
store.$patch(initialState);
}
});
export default pinia;
src/store/user.ts 。
// 组合式写法
import { defineStore } from "pinia";
import { ref, reactive, computed, watch } from 'vue';
const store = defineStore('user', () => {
const userInfo = reactive({
name: '老刘',
sex: '男',
age: 17,
isStudent: false
});
const token = ref('5201314');
const password = ref('123456');
const name = computed(() => userInfo.name);
const sex = computed(() => userInfo.sex);
watch(() => userInfo.age, (val) => {
console.log(val);
});
function addAge() {
userInfo.age++;
}
return {
userInfo,
token,
password,
name,
sex,
addAge
}
});
export default store;
src/App.vue 。
<template>
<div>
<button @click="resetStore">重置store</button>
<h1>我是父组件</h1>
<button @click="userStore.userInfo.age++">年龄+1</button>
<span class="marginLeft60">姓名:{{ userStore.name }}</span>
<span class="marginLeft60">性别:{{ userStore.sex }}</span>
<span class="marginLeft60 red">年龄:{{ userStore.userInfo.age }}</span>
<span class="marginLeft60 red">是否学生:{{ userStore.userInfo.isStudent ? '是' : '否' }}</span>
<hr>
<!-- 使用子组件A -->
<son-a />
<hr>
<!-- 使用子组件B -->
<son-b />
<hr>
</div>
</template>
<script setup lang="ts">
// 引入子组件
import SonA from './components/sonA.vue';
import SonB from './components/sonB.vue';
// 1-引入仓库
import store from '@/store/user.ts';
// 2-使用仓库
const userStore = store();
// 重置store
function resetStore() {
userStore.$reset();
}
</script>
<style>
.marginLeft60 {
margin-left: 60px;
}
.red {
color: red;
}
</style>
src/components/sonA.vue 。
<template>
<div>
<h2>我是子组件A</h2>
<button @click="userStore.userInfo.isStudent = true">入学</button>
<span class="marginLeft60">姓名:{{ userStore.name }}</span>
<span class="marginLeft60">性别:{{ userStore.sex }}</span>
<span class="marginLeft60 red">年龄:{{ userStore.userInfo.age }}</span>
<span class="marginLeft60 red">是否学生:{{ userStore.userInfo.isStudent ? '是' : '否' }}</span>
<grandson />
</div>
</template>
<script setup lang="ts">
import Grandson from './grandson.vue';
import store from '@/store/user.ts';
const userStore = store();
</script>
src/components/sonB.vue 。
<template>
<div>
<h2>我是子组件B</h2>
<button @click="userStore.userInfo.isStudent = false">毕业</button>
<span class="marginLeft60">姓名:{{ userStore.name }}</span>
<span class="marginLeft60">性别:{{ userStore.sex }}</span>
<span class="marginLeft60 red">年龄:{{ userStore.userInfo.age }}</span>
<span class="marginLeft60 red">是否学生:{{ userStore.userInfo.isStudent ? '是' : '否' }}</span>
</div>
</template>
<script setup lang="ts">
import store from '@/store/user.ts';
const userStore = store();
</script>
src/components/grandson.vue 。
<template>
<div>
<h3>我是孙组件</h3>
<span class="marginLeft60">姓名:{{ userStore.name }}</span>
<span class="marginLeft60">性别:{{ userStore.sex }}</span>
<span class="marginLeft60 red">年龄:{{ userStore.userInfo.age }}</span>
<span class="marginLeft60 red">是否学生:{{ userStore.userInfo.isStudent ? '是' : '否' }}</span>
</div>
</template>
<script setup lang="ts">
import store from '@/store/user.ts';
const userStore = store();
</script>
最后此篇关于vue3探索——5分钟快速上手大菠萝pinia的文章就讲到这里了,如果你想了解更多关于vue3探索——5分钟快速上手大菠萝pinia的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我在新的 Nuxt3 应用程序之上设置了 Pinia 并启动了开发服务器,并按顺序使用这些命令: npx nuxi init nuxt-app cd nuxt-app npm install npm
我正在从 vue 4.x 迁移到 pinia,我的一个文件需要来自商店的 api key 。但是即使我遵循 Pinia documentation 也无法让它工作.这是我如何使用 pinia //存储
我想弄清楚使用 Pinia 存储而不是仅使用纯 ts 可组合函数的优势是什么 const userName = ref('') export default function useUser() {
我在 main.js 中进行 session API 调用,并将响应中的值用作我的根存储的初始值。在 vuex 中,它是这样处理的, DataService.getSession() .then(
我正在使用 OptionsAPI 和 Pinia Store 构建一个 Vue 3 应用程序,但我经常遇到一个问题,指出我试图在 createPinia() 之前访问该商店叫做。 我一直在关注文档以在
Vue3 发布已经有一段时间了,它采用了新的响应式系统,而且构建了一套全新的 Composition API。Vue 的周边生态都在加紧适配这套新的系统,官方的状态管理库 Vuex 也在适配中,
我目前在一个 Vue 3 项目中工作。 使用 this.$router.push({}) 似乎在 Pinia 商店中不起作用。 我也尝试过导入 useRouter --> import { useRo
我目前在一个 Vue 3 项目中工作。 使用 this.$router.push({}) 似乎在 Pinia 商店中不起作用。 我也尝试过导入 useRouter --> import { useRo
项目代码以上传至码云,项目地址:https://gitee.com/breezefaith/vue-ts-scaffold 。 目录 前言 脚手架
我正在为 Quasar + Pinia 使用 Vue 3 + Vite 插件进行商店管理。我遵循了所有官方文档(Quasar、Pinia)。但是我收到了这个错误。 [Vue warn]: in
我试图了解可组合的目的。我有一个像这样的简单组合,并试图从 Pania 商店查看状态,其中 watch不触发: import { ref, watch, computed } from "vue";
我正在使用 pinia 和 vue-router 4.x ,但我在商店中使用它们时遇到问题。 每个人都独立工作,但不能一起工作。 如果我使用 import router from '../router
我目前正在开发我的第一个 vue 应用程序,目前正在构建登录逻辑。 对于国家管理,正在使用 pinia。我创建了一个 Pinia Store 来管理全局的“isLoggedIn”状态。 import
我有一个 pinia 商店,使用如下设置语法创建: defineStore('id', () => { const counter = ref(0) return { counter }
我有一个 pinia 商店,使用如下设置语法创建: defineStore('id', () => { const counter = ref(0) return { counter }
使用 Vite 快速搭建脚手架 命令行选项直接指定项目名称和想要使用的模板,Vite + Vue 项目,运行(推荐使用yarn) # npm 6.x npm init vite@latest my
我正在尝试使用包 pinia-plugin-persistedstate 在新的 Nuxt 3 应用程序中保留变量的状态。 我已经实现了 guide 中提供的步骤对于 nuxt 3: 创建了 /plu
我正在开发一个使用 vue 和 firebase 的网站。在身份验证部分之后,用户进入仪表板,其中有他的项目列表,这些项目是 firestore 中用户文档的子集合。 我创建了一个管理这些数据的 pi
我无法让访问同一商店的多个组件响应更新,直到我弄乱 dom 元素来触发新的渲染。 在我的 Pinia 商店中,我有一个数组和一个更新方法: let MyArray: IMyItem[] = [
我有一个 react 值,我想将其存储在 pinia 存储中。 const data = ref({}); async function loadData() { fetch("...")
我是一名优秀的程序员,十分优秀!