Pinia 状态管理器 菠萝:Setup Store风格

Pinia介绍:

Pinia 是 Vue 的专属状态管理库,它允许你跨组件或页面共享状态。

Pinia 大小只有 1kb 左右,超轻量级,你甚至可能忘记它的存在!

相比 Vuex,Pinia 的优点:

  • 更贴合 Vue 3 的 Composition API 风格,学习成本更低
  • 不需要像Vuex中要区分 Mutation 和 Action,Pinia统一使用 Actions 操作状态
  • 支持 TypeScript,可以充分利用 TS 的静态类型系统
  • 模块化管理 States, 每个模块是一个 Store
  • 直观的 Devtools,可以看到每个 State 的变化

安装:

npm install pinia

# 或者

yarn add pinia

案列:

/src/router/index.js 路由器

import { createRouter, createWebHashHistory,createWebHistory } from "vue-router"; //导入vue-router路由模块,createWebHashHistor函数
//import Home from "../views/Home.vue" //异步加载的组件,这里不需要
//import List from "../views/List.vue" //异步加载的组件,这里不需要进行导入,所以要注释掉const routes = [{path: "/",  //路径:        redirect: {name: "ListA" //重定向到路由名称为mylist的路由中,这样当浏览器输入的是:http://localhost:5173/ 则会重定向跳转到 http://localhost:5173/list}},{path: "/lista",  //路径//当路由被触发时,该组件才会被异步加载,举列:打开页面就不会加载所有的组件,而是根据当前页面需要的组件进行异步加载//这样可以减少初始加载时间,提升用户体验,同时也节省了不必要的资源消耗。name:"ListA",component: () => import("../views/ListA.vue")},{path: "/listb",  //路径//当路由被触发时,该组件才会被异步加载,举列:打开页面就不会加载所有的组件,而是根据当前页面需要的组件进行异步加载//这样可以减少初始加载时间,提升用户体验,同时也节省了不必要的资源消耗。name:"ListB",component: () => import("../views/ListB.vue")}  
]//创建路由对象
const router = createRouter({//history:createWebHashHistory()   这种方式是按照hash路由模式来路由导航,这种路由模式的url地址会存在 /#/ 样式是:http://localhost:5173/#/listhistory: createWebHistory(),     //这种方式基于浏览器 history API 的路由模式,url的样式是:http://localhost:5173/listroutes, //routes:routes的缩写})export default router //导出router路由对象//导出router路由对象

Pinia状态管理器:模块

/src/store/useListAStore.js  ListA.vue组件“单独”使用的状态管理器模块

这里的“单独”的意思是:此模块一般情况下用在ListA.vue组件中,但是其他组件需要此模块的数据共享也可以引入使用的。比如我们的App.vue也用了useListAStore.js这个模块中的数据

/*js文件的命名建议:use+组件名称+Store  举列:用于ListA组件的store 我的取名就是 useListAStore.js
*/import { defineStore } from 'pinia'
import axios from 'axios'
import { ref, onMounted, computed } from 'vue'// Setup Store风格案列演示:如下//第一个参数是唯一的storeId,注意别与其它模块的storeId重名(其实这个storeId我们开发人员一般用不到)
//第二个参数是一个匿名函数
const useListAStore = defineStore("ListAStoreId", () => {// Setup Store风格写法:在defineStore第二个参数中用ref包装的对象,就是 Option Store风格中的 stateconst obj = ref({name: 'Eduardo',age: 20,email: 'abc@qq.com',datalist: [],});// Setup Store风格写法:在defineStore的第二个参数中 申明的函数,就是 Option Store风格中的 actionsconst getDataList = async () => {const result = await axios({url: "https://m.maizuo.com/gateway?cityId=110100&pageNum=1&pageSize=10&type=1&k=7069698",headers: {'X-Client-Info': '{"a":"3000","ch":"1002","v":"5.2.1","e":"16992764191480200349024257"}','X-Host': 'mall.film-ticket.film.list'}})obj.value.datalist = result.data.data.films}const changeName = (newname) => {obj.value.name = newname;}// Setup Store风格写法:在defineStore的第二个参数中 计算属性computed,就是 Option Store风格中的 gettersconst filterDataList = computed(() => {//返回的是匿名函数return (keyword) => {return obj.value.datalist.filter(item => item.name.includes(keyword))}})//注意:此处需要根据业务需要:返回你的数据对象,函数,计算属性return {obj,getDataList,changeName,filterDataList}
})export default useListAStore //导出

/src/store/useListBStore.js    ListB.vue组件“单独”使用的状态管理器模块

这里的“单独”的意思是:此模块一般情况下用在ListB.vue组件中,但是其它组件需要此模块的数据共享也可以引入使用的

/*js文件的命名建议:use+组件名称+Store  举列:用于ListA组件的store 我的取名就是 useListAStore.js
*/import { defineStore } from 'pinia'
import axios from 'axios'
import { computed, ref } from 'vue'// Setup Store风格案列演示//第一个参数是唯一的storeId,注意别与其它模块的storeId重名(其实这个storeId我们开发人员一般用不到)
//第二个参数是一个匿名函数
const useListBStore = defineStore("ListBStoreId", () => {// Setup Store风格写法:在defineStore第二个参数中用ref包装的对象,就是 Option Store风格中的 stateconst name = ref("张三");const datalist = ref([]);// Setup Store风格写法:在defineStore的第二个参数中 申明的函数,就是 Option Store风格中的 actionsconst getDataList = async () => {const result = await axios({url: "https://m.maizuo.com/gateway?cityId=110100&ticketFlag=1&k=3777796",headers: {'X-Client-Info': '{"a":"3000","ch":"1002","v":"5.2.1","e":"16992764191480200349024257","bc":"110100"}','X-Host': 'mall.film-ticket.cinema.list'}});datalist.value = result.data.data.cinemas;};// Setup Store风格写法:在defineStore的第二个参数中 计算属性computed,就是 Option Store风格中的 gettersconst filterDataList = computed(() => {return (type) => {return datalist.value.filter(item => item.eTicketFlag == type)}})// 注意:此处需要根据业务需要:返回你的数据对象,函数,计算属性return {name,datalist,getDataList,filterDataList,}
})export default useListBStore //导出

注册:路由器 和 状态管理器

import { createApp } from 'vue'
import './style.css'
import App from './App.vue'import router from "../src/router/index.js" //导入状态管理器js 
import store from "../src/store/index.js" //导入状态管理器js import { createPinia } from 'pinia' //导入状态管理器js 
const pinia = createPinia();//在Pinia中的Setup Store风格中 不支持$reset() 状态重置。所以我们可以写一个扩展方法,可以实现Option Store风格中的store.$reset功能
pinia.use(({ store }) => {const initialState = JSON.parse(JSON.stringify(store.$state));store.$reset = () => {store.$patch(initialState);}
})var app = createApp(App)
app.use(router);
app.use(pinia); //注册pinia状态管理器 菠萝app.use(store)  //注册vuex插件:状态管理器app.mount("#app")

使用:

ListA.vue组件:电影列表

<template><div><div><!-- 从useListAStore.js模块下的state中取数:获取useListAStore.js模块下state中的name -->姓名: {{ store.obj.name }}</div><input type="text" v-model.lazy="keyword" placeholder="搜索"><ul><!-- 从useListAStore.js模块下的Getters中取数:执行Getters中的filterDataList方法 --><li v-for="item in store.filterDataList(keyword)" :key="item.filmId">{{ item.name }}</li></ul></div>
</template>
<script setup>
// VCA中不支持辅助函数,因为辅助函数中是用this.$store,而VCA中没有绑定this的import { ref, onMounted, onBeforeUnmount } from 'vue'
import useListAStore from '../store/useListAStore.js'const keyword = ref("");const store = useListAStore();store.changeName("王五");//$patch的用法:// store.name="张三";
// store.age=30;
// store.email="123@qq.com";
// 上面三条数据的修改,可以用store.$patch方法统一修改:如下:
// store.$patch({
//     name:"张三",
//     age:30,
//     email:"123@qq.ccom"
// })onMounted(() => {if (store.obj.datalist.length === 0) {store.getDataList();  //执行useListAStore.js模块中Actions中的getDataList方法  }
})onBeforeUnmount(() => {//对useListAStore.js模块下store里面state中的所有数据进行重置:注意是重置//注意:在Pinia中的Setup Store风格中 不支持$reset() 状态重置。所以我们在main.js中对pinia对象添加了一个扩展方法,可以实现Option Store风格中的store.$reset()重置数据功能store.$reset() 
})</script>
<style scoped>
li {padding: 10px;
}
</style>

ListB.vue组件:影院列表

<template><div><!-- 从store中的state中取数:获取useListBStore.js模块state中的name --><div> 姓名:{{ store.name }}</div><select v-model="type"><option :value="0">APP订票</option><option :value="1">前台兑换</option></select><ul><!-- 从store中的Getters中取数:执行useListBStore.js模块Getters中的filterDataList方法 --><li v-for="item in store.filterDataList(type)" :key="item.cinemaId"> {{ item.name }}</li></ul></div>
</template>
<script setup>
// VCA中不支持辅助函数,因为辅助函数中是用this.$store,而VCA中没有绑定this的import { ref, onMounted } from 'vue'
import useListBStore from '../store/useListBStore.js' 
const store = useListBStore();const type = ref(0);
onMounted(() => {if (store.datalist.length === 0) {store.getDataList(); //执行useListBStore.js模块中Actions中的getDataList方法}
})
</script>

App.vue根组件

<template><div><div>{{store.obj.name}}</div><ul class="nvabar"><RouterLink custom to="/ListA" v-slot="{ isActive, navigate }"><li @click="navigate"><span :class="isActive ? 'highlighter' : ''">电影列表</span></li></RouterLink><RouterLink custom to="/ListB" v-slot="{ isActive, navigate }"><li @click="navigate"><span :class="isActive ? 'highlighter' : ''">影院列表</span></li></RouterLink></ul><router-view></router-view></div>
</template>
<script setup>
import { ref,onMounted } from 'vue';import ListA from "./views/ListA.vue" //导入Home组件:
import ListB from "./views/ListB.vue" //导入List组件:import useListAStore from './store/useListAStore.js'const store=useListAStore();</script>
<style scoped>
.nvabar {/*固定定位:元素的位置相对于浏览器窗口是固定位置。即使窗口是滚动的它也不会移动*//* position: fixed; *//*显示在底部*//* bottom: 0; */display: flex;/* width: 100%; */height: 50px;line-height: 50px;text-align: center;
}.nvabar li {flex: 1;list-style-type: none;
}.highlighter {/* 高亮 */color: red;border-bottom: 3px solid red;padding-bottom: 7px;}
</style>

效果图

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

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

相关文章

深度学习 python opencv 火焰检测识别 计算机竞赛

文章目录 0 前言1 基于YOLO的火焰检测与识别2 课题背景3 卷积神经网络3.1 卷积层3.2 池化层3.3 激活函数&#xff1a;3.4 全连接层3.5 使用tensorflow中keras模块实现卷积神经网络 4 YOLOV54.1 网络架构图4.2 输入端4.3 基准网络4.4 Neck网络4.5 Head输出层 5 数据集准备5.1 数…

Vant 移动端UI 组件自动引入

Vue项目中安装Vant # Vue 3 项目&#xff0c;安装最新版 Vant npm i vant 组件按需引入配置 Vant按需引入- - -安装&#xff1a;unplugin-vue-components 插件 unplugin-vue-components 插件可以在Vue文件中自动引入组件&#xff08;包括项目自身的组件和各种组件库中的组件&…

第2关:还原键盘输入(list)

题目&#xff1a; 知识点&#xff1a; 列表list相较于数组&#xff1a; 优势&#xff1a;可在任意指定位置插入或者删除元素而不影响列表其他地方 。 劣势&#xff1a;无法直接进行下标索引&#xff0c;需要迭代器it逐个遍历。 代码&#xff1a; #include <iostream>…

Linux--gcc/g++

一、gcc/g是什么 gcc的全称是GNU Compiler Collection&#xff0c;它是一个能够编译多种语言的编译器。最开始gcc是作为C语言的编译器&#xff08;GNU C Compiler&#xff09;&#xff0c;现在除了c语言&#xff0c;还支持C、java、Pascal等语言。gcc支持多种硬件平台 二、gc…

leetcode(力扣) 51. N 皇后 (回溯,纸老虎题)

文章目录 题目描述思路分析对于问题1对于问题2 完整代码 题目描述 按照国际象棋的规则&#xff0c;皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。 n 皇后问题 研究的是如何将 n 个皇后放置在 nn 的棋盘上&#xff0c;并且使皇后彼此之间不能相互攻击。 给你一个整数…

基于SSM的数据结构课程网络学习平台

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;Vue 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是 目录…

链表OJ题(4)

目录 10.链表的回文结构 11.随机链表的复制 &#x1f642;找中间节点一定要考虑偶数个和奇数个的问题。 &#x1f642;指针指向的前中后。 &#x1f642;链表节点的位置个数/链表的节点中的数字。&#x1f197;&#x1f197; 今天最后两道链表OJ题目。 10.链表的回文结构…

Java,多线程,线程安全的懒汉式、死锁、ReentrantLock的使用以及一些知识点补充

关于线程安全地懒汉式有以下几种方式&#xff1a; /*** 实现线程安全的懒汉式*/ public class BankTest {Bank b1 null;Bank b2 null;public static void main(String[] args){BankTest bb new BankTest();Thread t1 new Thread(){Overridepublic void run(){bb.b1 Bank.…

物联网AI MicroPython学习之语法 network网络配置模块

学物联网&#xff0c;来万物简单IoT物联网&#xff01;&#xff01; network介绍 模块功能&#xff1a; 用于管理Wi-Fi和以太网的网络模块参考用法&#xff1a; import network import time nic network.WLAN(network.STA_IF) nic.active(True) if not nic.isconnected():…

.net在使用存储过程中IN参数的拼接方案,使用Join()方法

有时候拼接SQL语句时&#xff0c;可能会需要将list中的元素都加上单引号&#xff0c;并以逗号分开&#xff0c;但是Join只能简单的分开&#xff0c;没有有单引号&#xff01; 1.第一种拼接方案 List<string> arrIds new List<string>(); arrIds.Add("aa&qu…

nginx https 如何将部分路径转移到 http

nginx https 如何将部分路径转移到 http 我有一个自己的网站&#xff0c;默认是走的 https&#xff0c;其中有一个路径需要走 http。 实现 在 nginx 的配置文件 https 中添加这个路径&#xff0c;并添加一个 rewrite 的指令。 比如我需要将 tools/iphone 的路径转成 http&am…

开源:特殊的垄断

免责声明&#xff1a;本博客旨在分享我对开源策略的理解和体会&#xff0c;不代表任何组织或机构的立场或观点&#xff0c;也不构成任何商业或投资的建议或担保。本博客的内容可能存在错误或遗漏&#xff0c;也可能随着时间的推移而变得过时或不适用。请在使用或依赖本博客的内…