vue3 使用的 Pinia

news2024/10/7 8:20:32

文章目录

  • 一、Pinia API与Vuex s4 有很大不同
  • 二、使用步骤
    • 1.安装
    • 2.使用
    • 3、组件中应用
    • 案例

在这里插入图片描述

官网:https://pinia.web3doc.top/


一、Pinia API与Vuex s4 有很大不同

  • 没有 mutations。mutations 被认为是非常几长的。最初带来了 devtools 集成,但这不再是问题
  • 不再有模块的嵌套结构您仍然可以通过在另一个 store 中导入和使用 store 来隐式嵌套 store,但 Pinia 通过设计提供扁平结构,同时仍然支持 store 之间的交叉组合方式。您甚至可以拥有 store 的循环依赖关系。
  • 更好 typescript 支持。无需创建自定义的复杂包装器来支持 TpeScript,所有内容都是类型化的,并且 AP 的设计方式尽可能地利用 TS 类型推断。
  • 不再需要注入、导入函数、调用它们,享受自动补全!
  • 无需动态添加 stores,默认情况下它们都是动态的,您甚至不会注意到。请注意,您仍然可以随时手动使用 store 来注册它,但因为它是自动的,所以您无需担心。
  • 没有命名空间模块。鉴于 store 的扁平架构,"命名空间"stre 是其定义方式所固有的,您可以说所有 stores 都是命名空间的.

Pinia 就是更好的 Vuex,建议在你的项目中可以直接使用它了,尤其是使用了TypeScript 的项目。

二、使用步骤

1.安装

yarn add pinia
// 或者使用 npm
npm install pinia 

2.使用

在main.ts里面映入

import { createApp ] from 'vue'
import App from './App.vue'
import { createPinia } from 'pinia'
// 创建
const pinia = createpinia()
const app = createApp(App)
// 挂载到 Vue 根实例
app.use(pinia)
app.mount('#app')

新建store文件夹。在文件夹下面新建index.ts。

import { defineStore } from 'pinia'
// 1.定义并导出容器
// 参数1: 容器的 ID,必须唯一,将来 Pinia 会把所以的容器挂载到根容器
// 参数2: 选项对象
export const useMainStore = defineStore( 'main',{
    // 类似于组件的 data,用来存储全局状态的
    // 1、state必须是函数: 这样是为了在服务端染的时避免交叉请求导致的数据状态污染
    // 2、必须是箭头函数,这是为了更好的 TS 类型推导
	state: (){
		return {};
	},
	// 类似于组件的 computed,用来封装计算属性,有缓存的功能
	getters: {
		count10 (state) {  // state可选参数
			console.log('count10 调用了')
			return state.count + 10
		}
	},
	// 类似于组件的 methods,封装业务逻辑,修改 state
	actions: {
		changestate (num:number) {
			this.count+=num
		}
	}
})
// 2.使用容器中的 state
// 3.修改 state
// 4.容器中的 action 的使用	

3、组件中应用

<template>
	<div> {{mainStore.count }} </div>
	<div> {{count }} </div>
	<button @click="handleChangeState">修改数据</button>
	
	<div>{{ mainStore.count10 }}</div>
	<div>{{ mainStore.count10 }}</div>
</template>
<script lang="ts" setup>
	import {useMainStore } from ' .. /store'
	import { storeToRefs } from 'pinia'
	const mainStore = useMainStore( )
	console.log(mainStore.count )
	const { count] = storeToRefs(mainStore)
	//修改数据
	const handleChangestate = ()=>  {
		//  方式一: 最简单的方式就是这样
		mainStore.count++;
		// 方式二: 如果需要修改多个数据,建议使用 $patch 批量更新
		mainStore.$patch({
			count: mainStore.count + 1,
		})
		// 方式三:使用$patch 传递一个函数,也是批量更新
		mainStore.$patch( state=>{
			state.count++})
		// 方式四: 逻辑比较多的时候可以封装到 actions 做处理
		 mainStore.changeState(10)
	}
</script>

如果在组件中把mainStore数据解构出来,那么数据不是响应式的了,需要使用storeToRefs 去解构。实质是将解构出来的数据做ref代理处理。

多个数据批量修改有利于性能优化,因为一个一个改数据会触发一次又一次的视图更新,批量修改只会触发一个视图更新。

注意:不能使用箭头函数定义 action,因为箭头函数绑定外部 this


案例

商品列表
。展示商品列表、添加到购物车
购物车
。展示购物车商品列表、展示总价格、订单结算、展示结算状态。

效果如下图:
在这里插入图片描述

新建商品组件 ProductList.vue

<template>
    <ul>
        <li v-for="item in productsStore.all">
            {{ item.title }} - {{ item.price }}
            ---
            <button :disabled="item.inventory <= 0" @click="cartStore.addProductToCart(item)">添加到点物车</button>
        </li>


    </ul>
</template>

<script setup lang="ts">
import { useCartStore } from '../store/cart';
import { useProductsStore } from '../store/products';
const productsStore = useProductsStore()
const cartStore = useCartStore()

// 加载数据
productsStore.loadAllProducts()
</script>

新建购物车 Shoppingcart.vue

<template>
    <div class="cart">
        <h2>你的购物车</h2>
        <p>
            <i>请添加一些商品到购物车.</i>
        </p>
        <ul>
            <li v-for="item in cartStore.cartProducts">{{ item.title }} - {{ item.price }} x {{ item.quantity }}</li>

        </ul>
        <p>商品总价: {{ cartStore.totalPrice }}</p>
        <p>
            <button @click="cartStore.checkout()">结算</button>
        </p>
        <p v-show="cartStore.checkStatus">结算 {{ cartStore.checkStatus }}</p>
    </div>
</template>
<script setup Tang="ts">
import { useCartStore } from '../store/cart';
const cartStore = useCartStore()
</script>

在api文件下 新建 shops.ts 文件,用于模拟调用数据接口

export interface IProduct {
    id: number
    title: string
    price: number
    inventory: number // 库存
}
const _products: IProduct[] = [
    { id: 1, title: 'iPad 4 Mini', price: 500.01, inventory: 2 },
    { id: 2, title: 'HEM T-Shirt white', price: 10.99, inventory: 10 },
    { id: 3, title: 'Charli XCX - Sucker cD', price: 19.99, inventory: 5 },
]

export const getproducts = async () => {
    await wait(100)
    return _products

}

export const buyProducts = async () => {
    await wait(100)
    return Math.random() > 0.5
}
async function wait(delay: number) {
    return new Promise((resolve) => setTimeout(resolve, delay))
}

在src目录下新建store 文件,下面新建cart.ts和 products.ts
products.ts 代码如下:

import { defineStore } from 'pinia'
import {getproducts,IProduct} from "../test/api/shops"
export const useProductsStore = defineStore('products', {
    state: () => {
        return {
            all:[] as IProduct[] // 所以商品列表
        }
    },

    getters: {},
    actions: {
        async loadAllProducts () {
            const ret = await getproducts()
            this.all = ret
        },
        // 减库存
        decrementProduct(product:IProduct){
           const ret = this.all.find(item=> item.id === product.id) 
           if(ret){
            ret.inventory--
           }
        }
    }
})

cart.ts 代码如下:

import { defineStore } from "pinia";
import { IProduct, buyProducts } from "../test/api/shops";
import { useProductsStore } from "./products"
type CartProduct = {
    quantity: number
} & Omit<IProduct, "inventory"> // 合并IProduct类型数据,Omit 合并IProduct的时候,去除inventory库存这个属性
// IProduct

export const useCartStore = defineStore("cart", {
    state: () => {
        return {
            cartProducts: [] as CartProduct[],   // 购物车商品列表
            checkStatus: null as null | string,
        }
    },
    getters: {
        totalPrice(state) { // 计算总价
            return state.cartProducts.reduce((total, item) => {
                return total + item.price * item.quantity
            }, 0) // 初始为0
        }
    },
    actions: {

        addProductToCart(product: IProduct) {
            console.log(product)
            // 看商品有没有库存
            if (product.inventory < 1) {
                return
            }
            // 检查购物车中是否已有该商品
            const cartItem = this.cartProducts.find(item => item.id === product.id)
            // 如果有则让商品的数量 + 1
            if (cartItem) {
                cartItem.quantity++
            } else {
                // 如果没有则添加到购物车列表中
                this.cartProducts.push({
                    id: product.id,
                    title: product.title,
                    price: product.price,
                    quantity: 1 // 第一次添加数量是1 
                })
            }
            // 更新库存
            const prostore = useProductsStore()
            prostore.decrementProduct(product)
        },

        async checkout() {
            const res = await buyProducts()
            this.checkStatus = res ? '成功' : '失败'
        }

    }
})

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

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

相关文章

成功解决windows下将.pyx文件编译成.pyd文件

在linux上正常跑通的算法&#xff0c;搬到windows下使用就报错了 原来是其中涉及到.pyx文件的编译 在linux下.pyx会被编译成.so的文件&#xff0c;但是在windows下是无法使用.so文件的 需要重新编译成windows下的.pyd格式的才可以直接将python模块成功导入到算法中 所以需要解…

vue3到vue2组件重构方法笔记

这两天的任务是把一批做好的vue3组件放在vue2项目中使用&#xff0c;将组合式api分散开有一些零散的技巧&#xff0c;所以写一篇转化笔记以供大家参考 先上vue3一个组件的示例代码 <template><div ref"GForms" :style"{background: props.background…

27 # node 基本概念

node 基本概念 1、node 是什么&#xff1f; node.js 是一个基于 chrome v8 引擎的 JavaScript 运行环境&#xff08;runtime&#xff09;&#xff0c;node 不是一门语言&#xff0c;是让 js 运行在后端的运行时&#xff0c; 并且不包括 JavaScript 全集&#xff0c;因为在服务…

Collections工具类(java)

Collections工具类 java.util.Collections; 是集合的工具类作用&#xff1a;Collections不是集合&#xff0c;而是集合的工具类 Collections常用的API 方法名称说明public static <T> boolean addAll(Collection<T> c,T... elements)批量添加元素public static …

MySQL秘籍:让你的表操作炉火纯青

&#x1f495;每个人都有自己的一生&#xff0c;不要和别人去比较。比较只会让你感到沮丧和不满足。关注自己的成长和进步&#xff0c;并享受属于自己的旅程。 &#x1f495; &#x1f43c;作者&#xff1a;不能再留遗憾了&#x1f43c; &#x1f386;专栏&#xff1a;MySQL学习…

【LeetCode】11,盛最多水的容器。 难度等级:中等。双指针解法值得深入学习。

文章目录 一、题目二、我的解法&#xff1a;双重for循环&#xff0c;超出时间限制三、最优解法&#xff1a;双指针从两侧开始遍历 【LeetCode】11&#xff0c;盛最多水的容器。 难度等级&#xff1a;中等。 一、题目 给定一个长度为 n 的整数数组 height 。有 n 条垂线&#x…

小米、华为、海尔竞争中,全屋智能「崛起」2023

智能家居进入下半场&#xff0c;互联网大厂凭借着自身的流量红利收割了一部分市场份额&#xff1b;家电企业在向家装企业转型的过程中&#xff0c;也有其自带的流量优势和渠道优势&#xff1b;通信厂商借着“链接”优势&#xff0c;三大阵营在智能家居行业都各占鳌头。 作者|思…

NPM 制作命令行工具 - 进阶辅助库

一、简介 通过 NPM 制作命令行工具 - 入门案例 已经基本知道如何制作命令行工具了&#xff0c;现在就是内部命令处理。 如果不使用第三方插件辅助&#xff0c;那就只能对传入的参数进行一个一个判断处理&#xff0c;添加注释&#xff0c;这是很麻烦的&#xff0c;所以&#xf…

移动端开发之基础知识:视口、三倍图、移动端开发选择、移动端技术解决方案、移动端常见布局

移动端开发之流式布局 移动端基础浏览器现状手机屏幕现状移动端调试方法 视口布局视口视觉视口理想视口总结&#xff1a; meta视口标签标准的viewport设置 三倍图物理像素&物理像素比多倍图背景缩放 background-size背景图三倍图 多倍图切图 cutterman 移动端开发选择移动端…

基于JavaWeb的私人牙科诊所管理系统

目录 1、项目背景 2、项目目标 3、项目功能 4、系统架构 5、项目源码 6、论文目录&#xff08;16000字&#xff09; 1、项目背景 在当前社会医疗水平的高速发展下&#xff0c;口腔方面的医疗在社会上不断发展壮大。私人化牙科诊所呈现蓬勃发展的趋势&#xff0c;各方面的…

【JavaSE】方法的使用--05

目录 一、方法的概念与使用 1.1 什么是方法 1.2 方法的定义 1.3 方法调用的执行过程 1.4 实参和形参的关系&#xff08;重要&#xff09; 1.5 有无返回值的方法 二、方法的重载 2.1 方法重载的概念 2.2 方法重载的要求 2.3 方法签名 前言&#xff1a; 之前很久没写这…

python基础----01-----环境搭建

一 python介绍 1.1 Python 特点 Python 是完全面向对象的语言。函数、模块、数宁、宁符串都是对象&#xff0c;在 Python 中一切皆对象。完全支持继承、重载、多重继承。支持重载运算符&#xff0c;也支持泛型设计。Python 拥有一个强大的标准库&#xff0c;Python 语言的核心…

谷云科技受邀出席2023华南CIO大会-应用与数据集成专家

2023年6月10-11日&#xff0c;我们将于中国珠海国际会展中心迎来第6届 S-CIO 2023华南CIO大会暨信息技术交易会 。大会将邀请近1000位来自广东、广西、福建、海南等地的企业IT高管及行业专家深入探讨企业数字化运营的关键问题&#xff0c;以“ 千人论坛-生态展区-专业分论坛-华…

2023年成人高考标准拿证流程(入学前入学后)

很多小伙伴对成人高考“报名→学习→毕业”的流程还是很陌生哈&#xff0c;下面给大家整理了一份详细的报考流程和攻略。 大家可以收藏起来&#xff0c;仔细看看。 成考全流程—入学前 5月—8月 联系报名机构老师预报名&#xff0c;选定自己要报考院校专业&#xff0c;了解报…

36 KVM管理设备-配置虚拟串口

文章目录 36 KVM管理设备-配置虚拟串口36.1 概述36.2 操作步骤 36 KVM管理设备-配置虚拟串口 36.1 概述 在虚拟化环境下&#xff0c;由于管理和业务的需求&#xff0c;虚拟机与宿主机需要互相通信。但在云管理系统复杂的网络架构下&#xff0c;运行在管理平面的服务与运行在业…

Servlet简介和环境设置

目录 Servlet 简介 Servlet 环境设置 导入jar包 web.xml文件配置 WebServlet注解配置 web.xml文件的方式和WebServlet区别 Servlet 简介 Servlet 是运行在 Web 服务器或应用服务器上的程序&#xff0c;它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上…

对csv文件,又get了新的认知(二)

背景 最近在做数据处理时&#xff0c;发现别人给的 csv 文件用 txt 打开后&#xff0c;发现里面的所有字段都是带双引号&#xff0c;与自己之前见过的 csv 文件有点不一样&#xff0c;自己脑海里面隐约也见过 python 有相关的设置参数&#xff0c;于是就查看 python 官方文档中…

Linux 常用开发工具(上)(yum、vim)知识点+完整思维导图+实图例子+深入细节+通俗易懂建议收藏

绪论 耐心是一切聪明才智的基础。—— 柏拉图。本章进入到Linux下的一些常用的工具&#xff0c;这些工具能帮助我们去更好的使用Linux操作系统。 话不多说安全带系好&#xff0c;发车啦&#xff08;建议电脑观看&#xff09;。 附&#xff1a;红色&#xff0c;部分为重点部分&a…

一个无标记点面捕头盔,如何实现高精度面部表情捕捉?

在影视、动画、 游戏、虚拟直播应用中 虚拟数字人 可以犹如真人般实时驱动 背后少不了面部捕捉技术 随着面部捕捉技术不断革新&#xff0c;从有标记点到无标记点发展&#xff0c;再到如今佩戴一个面捕头盔就可以轻松做到精准面捕。 广州虚拟动力多年沉淀经验&#xff0c;根…

eslint导致的报错解决

当你利用脚手架在创建vue项目时&#xff0c;无脑创建下默认一定会安装eslint代码检测工具。那么你的噩梦就来了。eslint作为代码规范检测&#xff0c;不得不承认它的强大&#xff0c;但是绝对是会逼死一众强迫症患者。 比如你只是简简单单运行一个vue项目&#xff0c;报错一大堆…