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/#/list
    history: createWebHistory(),     //这种方式基于浏览器 history API 的路由模式,url的样式是:http://localhost:5173/list
    routes, //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风格中的 state
    const obj = ref({
        name: 'Eduardo',
        age: 20,
        email: 'abc@qq.com',
        datalist: [],
    });
 
    // Setup Store风格写法:在defineStore的第二个参数中 申明的函数,就是 Option Store风格中的 actions
    const 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风格中的 getters
    const 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风格中的 state
    const name = ref("张三");
    const datalist = ref([]);

    // Setup Store风格写法:在defineStore的第二个参数中 申明的函数,就是 Option Store风格中的 actions
    const 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风格中的 getters
    const 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>

效果图

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Android修行手册 - 可变参数中星号什么作用(冷知识)

点击跳转>Unity3D特效百例点击跳转>案例项目实战源码点击跳转>游戏脚本-辅助自动化点击跳转>Android控件全解手册点击跳转>Scratch编程案例点击跳转>软考全系列 &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff0c;以及各种资源分享&…

Halcon WPF 开发学习笔记(2):Halcon导出c#脚本和WPF初步开发

文章目录 前言HalconC#教学简单说明如何二开机器视觉如何二次开发Halcon导出Halcon脚本新建WPF项目&#xff0c;导入Halcon脚本和Halcon命名空间 前言 我目前搜了一下我了解的机器视觉软件&#xff0c;有如下特点 优点缺点兼容性教学视频(B站前三播放量)OpenCV开源&#xff0…

TCSVT(IEEE Transactions on Circuits and Systems for Video Technology)期刊投稿指南

目录 TCSVT 期刊简介 TCSVT 期刊影响因子和分区​ 期刊官方网站 期刊投稿网址 投稿指南网址 稿件格式要求 稿件提交指南 A. 提交稿件 B. 手稿格式 C. 摘要指南 D. 提交图形的指南 E. 页面和彩色图形费用 TCSVT 期刊简介 IEEE Transactions on Circuits and Systems…

产品化的GPT,能否为“百模大战”照亮未来?

这两天&#xff0c;AI圈都处在一种莫名的震撼感当中。 北京时间 11月7日&#xff0c;OpenAI 举办了首次DevDay开发者日活动。活动现场发布了非常多内容&#xff0c;其中有一些按部就班的&#xff0c;比如技术上更新了最新版本的GPT-4 Turbo。也有一些让从业者目瞪口呆&#xff…

C语言数据结构-----双向链表增删查改的代码实现

文章目录 1.初始化双链表2.创建链表节点3.打印链表4.尾插5.尾删6.头插7.头删8.在pos之前插入8.1 在pos之前插入(改造头插)8.2 在pos之前插入(改造尾插) 9.删除pos位置9.1 删除pos位置(改造尾删)9.1 删除pos位置(改造头删) 10.查找11.毁灭 链接: 顺序表(动态顺序表增删查改的代码…

openGauss学习笔记-121 openGauss 数据库管理-设置密态等值查询-使用JDBC操作密态数据库

文章目录 openGauss学习笔记-121 openGauss 数据库管理-设置密态等值查询-使用JDBC操作密态数据库121.1 连接密态数据库121.2 调用isValid方法刷新缓存示例121.3 执行密态等值查询相关的创建密钥语句121.4 执行密态等值查询相关的创建加密表的语句121.5 执行加密表的预编译SQL语…

系列八、Mybatis一对多查询,只查询出了一条记录

一、Mybatis一对多查询&#xff0c;只查询出了一条记录 1.1、问题说明 典型的权限管理框架的数据库表中&#xff0c;一般会存在这样3种角色的表&#xff0c;即用户表、角色表、用户角色关联表&#xff0c;表设计好之后&#xff0c;往这三张表中初始化了一些测试数据&#xff0…

stm32超声波测距不准的解决方法(STM32 delay_us()产生1us)及stm32智能小车超声波测距代码(C语言版本)

首先要说明一下原理&#xff1a;使用stm32无法准确产生1us的时间&#xff0c;但是超声波测距一定要依赖时间&#xff0c;时间不准&#xff0c;距离一定不准&#xff0c;这是要肯定的&#xff0c;但是在不准确的情况下&#xff0c;要测量一个比较准确的时间&#xff0c;那么只能…

混沌系统在图像加密中的应用(基于哈密顿能量函数的混沌系统构造1.3)

混沌系统在图像加密中的应用&#xff08;基于哈密顿能量函数的混沌系统构造1.3&#xff09; 前言一类三维非哈密顿系统的构造与动态特性分析1.相关理论基础2.类Nos-Hoove系统构造的思路及实现3.基于哈密顿能量理论的Nos-Hoove系统的分析与仿真3.1 平衡点分析3.2 不同强度激励下…

C语言从入门到精通之【数据类型和关键字】

数据类型在程序使用之前已经预先设定好了&#xff0c;在整个程序的运行过程中没有变化&#xff0c;这些称为常量&#xff08;constant&#xff09;。其他数据类型在程序运行期间可能会改变或被赋值&#xff0c;这些称为变量&#xff08;variable&#xff09;。 变量类型有几种…

(二十七)ATP应用测试平台——基于mybatisplus和aop切面实现数据权限隔离的案例实战

前言 在实际项目开发中&#xff0c;我们经常会用到俩种权限&#xff0c;一种是功能权限&#xff0c;一种是数据权限。功能权限主要是用来限制用户的操作&#xff0c;而数据权限是限制用户能查看到哪些数据。功能权限我们可以使用流行的框架shiro或者spring-security实现&#…

C语言--求一个 3 X 3 的整型矩阵对角线元素之和

一.题目描述 求一个 3 X 3 的整型矩阵对角线元素之和 二.代码实现 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> int main() {int arr[3][3] { 0 };for (int i 0;i < 3;i){for (int j 0;j < 3;j){ printf("请输入数字&#xff1a;");scanf(&…

暴力递归转动态规划(十五)

题目 给定一个正数n&#xff0c;求n的裂开方法数&#xff0c; 规定&#xff1a;后面的数不能比前面的数小 比如4的裂开方法有&#xff1a; 1111、112、13、22、04 。 5种&#xff0c;所以返回5 暴力递归 用暴力递归方法进行尝试&#xff0c;整体思路是这样&#xff1a; 暴力递…

RcppRcppEigen学习材料推荐

目录 一Rcpp和RcppEigen包 二Rcpp学习材料来源 三Rcpp&RcppEigen学习材料汇总 一Rcpp和RcppEigen包 目前已有RcppEigen包&#xff0c;因此直接下载安装RcppEigen包即可&#xff0c;不需要在Eigen官网下载安装。即不需要安装任何关于C的软件&#xff0c;直接基于R进行C相…

Java入门篇 之 补 类与对象

本篇碎碎念&#xff1a;每个人的想法都不一样&#xff0c;不要强求&#xff0c;顺其自然&#xff0c;要相信&#xff0c;一切都在向好的方面前进&#xff01;&#xff01;&#xff01;&#xff01; 今日份励志文案:山海的浩瀚&#xff0c;宇宙的浪漫&#xff0c;都在我内心翻腾…

【编程语言发展史】Python的起源和发展历史

目录 Python的起源 Python的发展历史 Python的生态系统和应用领域 Python的社区和发展模式 Python的未来趋势和挑战 Python是一门广受欢迎的高级编程语言&#xff0c;其起源和发展历史自20世纪末至今&#xff0c;经历了多个版本的迭代和社区的广泛参与。以下是关于Python的…

电子工程师的焊接技法总结

基础学习视频如下&#xff1a; 1 老司机焊接纯干货分享&#xff0c;让你焊接不迷路&#xff0c;很适合零基础小白_哔哩哔哩_bilibili 焊接常用工具 1 焊锡丝 按照粗细来分的话&#xff0c;有粗焊锡&#xff0c;有细焊锡&#xff0c;细焊锡一般适合比较精细的焊接。 按照是否含铅…

在使用Vuex时,5个方法让你保证数据的更新及时性

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

Langchain-Chatchat环境安装

目录 一、简介 二、环境安装 三、使用Langchain-Chatchat 3.1、下载模型 3.2、设置配置文件 3.3、执行 一、简介 基于 ChatGLM 等大语言模型与 Langchain 等应用框架实现&#xff0c;开源、可离线部署的检索增强生成(RAG)大模型知识库项目。 &#x1f916;️ 一种利用 l…

数据结构:AVLTree的插入和删除的实现

个人主页 &#xff1a; 个人主页 个人专栏 &#xff1a; 《数据结构》 《C语言》《C》 文章目录 前言一、AVLTree二、AVLTree的插入插入新增节点调整平衡因子旋转左单旋(新增节点位于较高右子树的右侧)右单旋(新增节点位于较高左子树的左侧)右左双旋(新增节点在较高右子树的左子…