Pinia 状态管理器 菠萝

news2024/11/19 23:38:34

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组件单独使用的状态管理器模块

/*
    js文件的命名建议:use+组件名称+Store  举列:用于ListA组件的store 我的取名就是 useListAStore.js
*/

import { defineStore } from 'pinia'
import axios from 'axios'

//第一个参数是唯一的storeId
const useListAStore = defineStore("ListAStoreId", {
    // 为了完整类型推理,推荐使用箭头函数
    state: () => {
        return {
            // 所有这些属性都将自动推断出它们的类型
            name: 'Eduardo',
            age:20,
            email:'abc@qq.com',
            datalist: [],
        }
    },
    actions: {
        getDataList() {
            const result = 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'
                }
            }).then(res => {
                this.datalist = res.data.data.films
            })

        },
        async changeName(newname) {
            this.name = newname;
        }
    },
    getters: {
        filterDataList(state) {
            return (keyword) => {
                return state.datalist.filter(item => item.name.includes(keyword));
            }
        }
    },
})

export default useListAStore //导出

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

/*
    js文件的命名建议:use+组件名称+Store  举列:用于ListA组件的store 我的取名就是 useListAStore.js
*/

import { defineStore } from 'pinia'
import axios from 'axios'

//第一个参数是唯一的storeId
const useListBStore = defineStore("ListBStoreId", {
    // 为了完整类型推理,推荐使用箭头函数
    state: () => {
        return {
            // 所有这些属性都将自动推断出它们的类型
            name: '张三',
            datalist: [],
        }
    },
    actions: {
        async getDataList() {
            //异步
            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'
                }
            });
            this.datalist = result.data.data.cinemas
        },
        async changeName(newname) {
            this.name = newname;
        }
    },
    getters: {
        filterDataList(state) {
            return (type) => {               
                return state.datalist.filter(item => item.eTicketFlag == type)
            }
        }
    },
})

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();

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.name }}
        </div>
        <input type="text" v-model.lazy="keyword" placeholder="搜索">
        <ul>
            <!-- 从useListAStore.js模块下的Getters中取数:执行Getters中的filterDataList方法 -->
            <li v-for="item in store.datalist" :key="item.filmId">{{ item.name }}</li>
        </ul>
    </div>
</template>
<script setup>
// VCA中不支持辅助函数,因为辅助函数中是用this.$store,而VCA中没有绑定this的
import { useStore } from 'vuex'
import { ref, onMounted, onBeforeUnmount } from 'vue'
import useListAStore from '../store/useListAStore.js'

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"
// })


const keyword = ref("");
onMounted(() => {
    if (store.datalist.length === 0) {
        store.getDataList();  //执行useListAStore.js模块中Actions中的getDataList方法  
    }
})

onBeforeUnmount(() => {
    store.$reset() //对useListAStore.js模块下store里面state中的所有数据进行重置:注意是重置
})


</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.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, } 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.coloradmin.cn/o/1199688.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Leetcode—191.位1的个数【简单】

2023每日刷题&#xff08;二十七&#xff09; Leetcode—191.位1的个数 实现代码 int hammingWeight(uint32_t n) {int ans 0;for(int i 0; i < 32; i) {if(n & ((long long)1 << i)) {ans;}}return ans; }运行结果 翻转比特1思路 就解法一的代码实现来说&am…

基于Transformer架构的ChatGPT:三步带你了解它的工作原理

作者&#xff1a;Insist-- 个人主页&#xff1a;insist--个人主页 梦想从未散场&#xff0c;传奇永不落幕&#xff0c;博主会持续更新优质网络知识、Python知识、Linux知识以及各种小技巧&#xff0c;愿你我共同在CSDN进步 目录 一、Transformer架构 1. 自注意力层 2. 前馈神…

Django中简单的增删改查

用户列表展示 建立列表 views.py def userlist(request):return render(request,userlist.html) urls.py urlpatterns [path(admin/, admin.site.urls),path(userlist/, views.userlist), ]templates----userlist.html <!DOCTYPE html> <html lang"en">…

PCB知识补充

系列文章目录 文章目录 系列文章目录参考文献PCB知识互连线电阻过孔/铜箔电流能力铜箔载流能力过孔载流能力 热设计电磁兼容及部分要求 参考文献 [1]牛森,张敏娟,银子燕.高速PCB多板互联的电源完整性分析[J].单片机与嵌入式系统应用,2023,23(09). [2]陈之秀,刘洋,张涵舒等.高…

【Python】KDtree的调用

前言 查询点集中与目标点最近的k个点 from scipy.spatial import cKDTree import numpy as npdata np.array([[1,2],[1,3],[4,5]]) # 生成 100 个三维数据 tree cKDTree(data) # 创建 K-D Tree result tree.query(np.array([5, 5]), k2) # 查询与 [0.5, 0.5, 0.5] 最近的三…

(离散数学)命题及命题的真值

答案&#xff1a; &#xff08;5&#xff09;不是命题&#xff0c;因为真值不止一个 &#xff08;6&#xff09;不是命题&#xff0c;因为不是陈述句 &#xff08;7&#xff09;不是命题&#xff0c;因为不是陈述句 &#xff08;8&#xff09;不是命题&#xff0c;真值不唯一

NodeJs - 实现当前线程唯一的单例对象

NodeJs - 实现当前线程唯一的单例对象 一. 实现当前线程唯一的单例对象 一. 实现当前线程唯一的单例对象 Java 里面&#xff0c;一般都把这种和当前线程绑定的单例对象存储到ThreadLocal里面&#xff0c;但是Node里面没有这种存储&#xff0c;那咋办呢&#xff1f;直接上代码&…

Android---动态权限适配问题

在 Android6.0&#xff0c;即 API 23 之前&#xff0c;App 需要的权限都会在安装阶段向用户展示&#xff0c;而在 App 运行期间不需要动态判断权限是否已申请。从 6.0 之后的版本开始&#xff0c;Android 系统做了一次大的改动。对于部分权限&#xff0c;App 需要在代码中动态申…

No177.精选前端面试题,享受每天的挑战和学习

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云课上架的前后端实战课程《Vue.js 和 Egg.js 开发企业级健康管理项目》、《带你从入…

OpenAI 开发者大会亮相新一代AI

OpenAI 开发者大会于11月6日在旧金山举行&#xff0c;发布了一系列新模型及开发者产品的更新。 主要包括&#xff1a; GPT-4 Turbo&#xff1a;一种功能更强大的模型&#xff0c;具有128K的超大文本窗口&#xff0c;并以更低的成本提供服务。 Assistants API&#xff1a;新AP…

计算机msvcp140.dll重新安装的四个解决方法,专门解决dll文件丢失问题的方法

在我多年的电脑使用经历中&#xff0c;曾经遇到过一个非常棘手的问题&#xff0c;那就是电脑提示找不到msvcp140.dll文件。这个问题让我苦恼了很久&#xff0c;但最终还是找到了解决方法。今天&#xff0c;我就来分享一下我解决这个问题的四种方法&#xff0c;希望对大家有所帮…

cesium如何实现区域下钻

首先&#xff0c;这里讲一下数据源&#xff0c;数据源是拷贝的DataV.GroAtlas里的数据&#xff0c;这里整合了一下之前发的区域高亮的代码来实现的&#xff0c;单击左键使得区域高亮&#xff0c;每次点击都移除上一次点击的模块&#xff0c;双击左键&#xff0c;实现区域下钻并…

社会公益服务小程序的作用是什么

公益包含的项目比较广&#xff0c;包括助学、环保、关爱特殊群体等&#xff0c;市场中无论相关机构还是团队&#xff0c;都有不少&#xff0c;而在实际运作中&#xff0c;也有些一些难题&#xff1a; 首先就是信息展示方面&#xff0c;自身服务及案例难以展示&#xff0c;线上…

每天一点python——day66

#每天一点Python——66 #字符串的分隔 #如图&#xff1a; #方法①split()从左开始分隔&#xff0c;默认空格为分割字符&#xff0c;返回值是一个列表 shello world jisuanji#首先创建一个字符串 list1s.split() print(list1)#输出结果是&#xff1a;[hello, world, jisuanji]注…

AI 绘画 | Stable Diffusion精确控制ControlNet扩展插件

ControlNet ControlNet是一个用于控制AI图像生成的插件&#xff0c;通过使用Conditional Generative Adversarial Networks&#xff08;条件生成对抗网络&#xff09;的技术来生成图像。它允许用户对生成的图像进行更精细的控制&#xff0c;从而在许多应用场景中非常有用&#…

Reeds-Shepp曲线

汽车都有一个最小转向半径&#xff0c;Reeds-Shepp曲线由几段半径固定的圆弧和一段直线段拼接组成&#xff0c;而且圆弧的半径就是汽车的最小转向半径。从起始点到目标点的路径长度是指汽车中心运动轨迹的长度&#xff0c;也就是所有圆弧的弧长和直线段的长度之和。 当环境中…

STM32F4X定时器之通用定时器

一、STM32通用定时器概述 通用定时器包括一个16位或32位自动重载计数器&#xff0c;可通过可编程预分频器进行驱动。定时器可以实现多种功能&#xff0c;包括测量输入信号的脉冲宽度和生成输出波形&#xff0c;通过使用定时器预分频器和RCC时钟控制器预分频器&#xff0c;可以…

深度学习之基于Pytorch框架的MNIST手写数字识别

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 MNIST是一个手写数字识别的数据集&#xff0c;是深度学习中最常用的数据集之一。基于Pytorch框架的MNIST手写数字识…

牛客网刷题笔记231112 最小k位数+二叉树层序遍历+SQL异常邮件概率

算法题牛客网NC119 最小的k个数 题目&#xff1a; 用了一下python列表的便利&#xff0c;不知道在面试时允许用不。当然最简单的方法其实是直接sort()一下取前k位数即可。本次写的思路如下&#xff1a; 用一个最大容量为k的列表存储结果&#xff0c;遍历n个元素&#xff0c;当…

Python基础入门例程52-NP52 累加数与平均值(循环语句)

最近的博文&#xff1a; Python基础入门例程51-NP51 列表的最大与最小(循环语句)-CSDN博客 Python基础入门例程50-NP50 程序员节&#xff08;循环语句&#xff09;-CSDN博客 Python基础入门例程49-NP49 字符列表的长度-CSDN博客 目录 最近的博文&#xff1a; 描述 输入描…