Vue3探索编辑部——关于Pinia(1)

目录

什么是Pinia?

Vue3中的Pinia

创建项目

数据准备和引入Pinia

使用Pinia

采用action修改数据

总结


什么是Pinia?

       Pinia是Vue3的专属的状态管理工具,什么是状态呢?其实我们可以把状态理解为数据,或者一个业务逻辑实体,都可以为状态。Pinia是Vue3的状态管理工具,这是Vuex的替代工具,不过它比Vuex简单直接很多,省去了很多语法。Vue3的一个重要思想就是数据为尊,加之Vue3是在之前的Vue的基础上的优化升级,所以简洁明了了很多 Pinia的引入,成功的解决了当组件繁多,不同组件之间有很多数据嵌套,包含的情况的时候,我们写代码繁重,逻辑不清晰的问题 #几大特点

  • 提供了更加简单的API,去掉了mutation

  • 提供更加贴近组合式API的新语法,并且和Vue3的其他语法统一

  • 去掉了modules的概念,每个store都是一个独立的模块

  • 对于TypeScript更加友好,类型推断更加可靠

  • 对于插件的支持更加好,我们可以根据项目的特定需求来自定义状态管理 #代码演示

Vue3中的Pinia

创建项目

       首先我们创建一个Vue3的项目,来专门演练一下Pinia。首先就是按照Vue3官方网站的步骤,创建项目,然后在选项工具这一步的时候,选择Pinia工具的时候,选上Yes,语言你可以用JavaScript,也可以是TypeScript都行。

npm create vue@latest
✔ Project name: … <your-project-name> 
✔ Add TypeScript? … No / Yes ✔ Add JSX Support? … No / Yes 
✔ Add Vue Router for Single Page Application development? … No / Yes 
✔ Add Pinia for state management? … No / Yes 
✔ Add Vitest for Unit testing? … No / Yes 
✔ Add an End-to-End Testing Solution? … No / Cypress / Playwright 
✔ Add ESLint for code quality? … No / Yes 
✔ Add Prettier for code formatting? … No / Yes Scaffolding project in ./<your-project-name>... Done

数据准备和引入Pinia

       下面我们来到代码部分,我用的是Webstorm,其他编辑器也是一样,文件目录都是这样,我们可以看到src文件目录下的stores文件,里面有个js文件movie.js,这个就是我们引入Pinia的地方。由于我们在创建项目的时候,选择了引入Pinia,那么在stores文件下,就会有一个counter.js文件,这里我重命名为了movie.js,下面的代码是这个js文件原本的样子。

       下面的代码分别是movie.js文件和main.js文件,我们都按照官方的写法去一步一步地引入,写代码按照官方规范。

import { ref, computed } from 'vue'  
import { defineStore } from 'pinia'  
  
//我们还想完成什么样的功能,在这里写功能代码,然后在其他组件引入就可以直接使用了  
export const useCounterStore = defineStore('counter', () => {  
  const count = ref(0)  
  const doubleCount = computed(() => count.value * 2)  
  function increment() {  
    count.value++  
  }  
  
  return { count, doubleCount, increment }  
})
import { createApp } from 'vue'
//第一步:引入pinia
import { createPinia } from 'pinia'
import App from './App.vue'
import router from './router'
​
//第二步:创建pinia
const app = createApp(App)
​
//第三步:安装pinia
app.use(createPinia())
​
app.use(router)
app.mount('#app')
​

       下面我们就可以在组件中使用Pinia工具了,当然,把其他所有的.vue的组件和相应的引入全都删掉,我们就只看Pinia所要完成的功能,我们在components文件夹下新建一个.vue组件,叫Movies.vue,我们在这个组件内编写功能。

<script setup name="Movies">  
import {reactive} from "vue";  
  
//数据  
let movieList = reactive([  
  {id:1,title:'火星救援'},  
  {id:2,title:'搏击俱乐部'},  
  {id:3,title:'流浪地球2'}  
])  
  
//要完成的功能  
async function getMovie(){  
  //发送请求,连续解构赋值,然后再重命名  
}  
</script>  
  
<template>  
  <div class="movie">  
    <button @click="getMovie">获取一部电影</button>  
    <ul>      
    <li v-for="movie in movieList" :key="movie.id">{{movie.title}}</li>  
    </ul>  
  </div>  
</template>  
  
<style scoped>  
.movie {  
  background-color: orange;  
  padding: 10px;  
  border-radius: 10px;  
  box-shadow: 0 0 10px;  
}  
</style>

       我们在Movies.vue组件中,写一些基本的功能,三个对象形式的数据,用reactive包裹,采用v-for遍历这个对象数组,并且在App.vue中引入Movies这个组件。

<script setup>  
import Movies from "@/components/Movies.vue";  
</script>  
  
<template>  
  <div>  
    <h2>  
      我是App.vue  
    </h2>  
  </div>  
  <Movies>  
  </Movies>
</template>  
  
<style scoped>  
  
</style>

       启动项目,不管你是用npm,yarn还是pnpm,都是一样的,我们打开浏览器就能看到这样的效果。

       接下来,我们引入axios,发送一个请求,这里我就直接用一个现成的网站了,https://api.uomg.com/api/rand.qinghua?format=json,这是尚硅谷的一个服务器网站。

       在Movies.vue组件中写下这样的代码,读者可以先不必纠结这一部分,我们的重点不是这里,这里都是一些铺垫工作,总之这里的async部分是一个功能。

<script setup name="Movies">  
import {reactive} from "vue";  
import axios from "axios";  
import {nanoid} from 'nanoid'  
  
//数据  
let movieList = reactive([  
  {id:1,title:'火星救援'},  
  {id:2,title:'搏击俱乐部'},  
  {id:3,title:'流浪地球2'}  
])  
  
//要完成的功能  
async function getMovie(){  
  //发送请求,连续解构赋值,然后再重命名  
  let {data:{content:title}} = await axios.get('https://api.uomg.com/api/rand.qinghua?format=json')  
  //把请求回来的字符串,处理成一个对象  
  let obj = {id:nanoid(),title}  
  //再放到数组中  
  movieList.unshift(obj)  
}  
</script>  
  
<template>  
  <div class="movie">  
    <button @click="getMovie">获取一部电影</button>  
    <ul>      
    <li v-for="movie in movieList" :key="movie.id">{{movie.title}}</li>  
    </ul>  
  </div>  
</template>  
  
<style scoped>  
.movie {  
  background-color: orange;  
  padding: 10px;  
  border-radius: 10px;  
  box-shadow: 0 0 10px;  
}  
</style>

使用Pinia

       我们会看到Vue开发者工具中就有了Pinia,stores文件夹就是Pinia的一个具体体现,我们就把store下的movie.js想象成一个仓库,我们在这里完成功能代码,来处理刚才的Movies.vue。stores文件夹下的js代码,里面就存有,Pinia要管理的状态,可以是数据,也可也是方法

import { defineStore } from 'pinia'  
  
//我们还想完成什么样的功能,在这里写功能代码,然后在其他组件引入就可以直接使用了  
export const useMovieStore = defineStore('movie',{  
  //数据真正存储的地方  
  state(){  
    return {  
      movieList:[  
          {id:1,title:'火星救援'},  
          {id:2,title:'搏击俱乐部'},  
          {id:3,title:'流浪地球2'}  
      ]  
    }  
  }  
})

       然后回到Movies.vue中,我们可以去掉之前写的数据了,即movieList,因为数据已经存放到stores下的movie.js下,使用Pinia管理了,可以先把getMovie()中的代码注释一下,我们只需要在这里import引入useMovieStore,再声明一个变量movieStore,就可以使用数据了,数据存储在movie.js,而在Movie.vue组件中使用。

<script setup name="Movies">  
import {reactive} from "vue";  
import axios from "axios";  
import {nanoid} from 'nanoid'  
import {useMovieStore} from "@/stores/counter.js";  
  
//数据  
// let movieList = reactive([  
//   {id:1,title:'火星救援'},  
//   {id:2,title:'搏击俱乐部'},  
//   {id:3,title:'流浪地球2'}  
// ])  
  
//使用pinia后,我们就这样使用数据了  
const MovieStore = useMovieStore()  
  
//要完成的功能  
async function getMovie(){  
  //发送请求,连续解构赋值,然后再重命名  
  //let {data:{content:title}} = await axios.get('https://api.uomg.com/api/rand.qinghua?format=json')  
  //把请求回来的字符串,处理成一个对象  
  //let obj = {id:nanoid(),title}  
  //再放到数组中  
  //movieList.unshift(obj)  
}  
</script>  
  
<template>  
  <div class="movie">  
    <button @click="getMovie">获取一部电影</button>  
    <ul>      <li v-for="movie in MovieStore.movieList" :key="movie.id">{{movie.title}}</li>  
    </ul>  
  </div>  
</template>  
  
<style scoped>  
.movie {  
  background-color: orange;  
  padding: 10px;  
  border-radius: 10px;  
  box-shadow: 0 0 10px;  
}  
</style>

       这是打开开发者工具的效果,这就是存储数据的过程,先引入Pinia,再在stores下的movie.js下,存入数据。

采用action修改数据

       数据存放好了,如果我们要对数据做改动,或者围绕数据要写一些方法,我们要采用Action,Action相当于组件中的method,它们可以通过defineStore()中的actions属性来定义。回到movie.js文件中,把之前的函数体弄到这里来,之前在Movies.vue的函数中的相应部分我们就可以删除了,功能写在这里,这样movieList数据和其相关的方法都在这一份代码中,简洁高效,思路清晰。

import { defineStore } from 'pinia'
import axios from "axios";
import {nanoid} from "nanoid";
​
//我们还想完成什么样的功能,在这里写功能代码,然后在其他组件引入就可以直接使用了
export const useMovieStore = defineStore('movie',{
    //要完成什么样的逻辑,我们就在actions里面写
    actions:{
         async getMovies(){
            //发送请求,连续解构赋值,然后再重命名
            let {data:{content:title}} = await axios.get('https://api.uomg.com/api/rand.qinghua?format=json')
            //把请求回来的字符串,处理成一个对象
            let obj = {id:nanoid(),title}
            //再放到数组中
            this.movieList.unshift(obj)
        }
    },
    //数据真正存储的地方
    state(){
        return {
          movieList:[
              {id:1,title:'火星救援'},
              {id:2,title:'搏击俱乐部'},
              {id:3,title:'流浪地球2'}
          ]
        }
  }
})

       同时,如果我们想要在Vue组件中保持对Pinia存储中的响应式状态的直接引用,具体到这里,就是要让movieList具有响应式特性,就要使用storeToRefs来包裹movieList。

<script setup name="Movies">
import {useMovieStore} from "@/stores/movie.js";
import { storeToRefs } from "pinia";
//数据
// let movieList = reactive([
//   {id:1,title:'火星救援'},
//   {id:2,title:'搏击俱乐部'},
//   {id:3,title:'流浪地球2'}
// ])
​
//使用pinia后,我们就这样使用数据了
const MovieStore = useMovieStore()
//我们要用storeToRefs包裹,storeToRefs只会关注store中的数据,不会对方法进行ref包裹
const { movieList } = storeToRefs(MovieStore)
​
function getMovie(){
  MovieStore.getMovies()
}
​
</script>
​
<template>
  <div class="movie">
    <button @click="getMovie">获取一部电影</button>
    <ul>
      <li v-for="movie in movieList" :key="movie.id">{{movie.title}}</li>
    </ul>
  </div>
</template>
​
<style scoped>
.movie {
  background-color: orange;
  padding: 10px;
  border-radius: 10px;
  box-shadow: 0 0 10px;
}
</style>

总结

       Pinia 是 Vue 3 的状态管理库,用于简化和集中管理应用的状态和逻辑。它提供了简洁的 API 和良好的 TypeScript 支持。在以上的代码中,Pinia 用于存储和管理电影列表数据,通过 defineStore 创建 store,使用 actions 处理异步获取电影数据的逻辑。通过 storeToRefs,可以在 Vue 组件中保持对 Pinia store 中状态的响应式引用,确保当 store 中的状态更新时,组件能够实时反映这些变化。

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

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

相关文章

INFINI Labs 产品更新 | 统一版本号 1.22.0

INFINI Labs 产品又更新啦~&#xff0c;包括 Console&#xff0c;Gateway&#xff0c;Loadgen&#xff0c;Agent 1.22.0。为了避免版本不同带来的困扰&#xff0c;以后发布均统一版本号&#xff0c;此次版本重点修复历史遗留 Bug 、优化内存占用等。以下是本次更新的详细说明。…

Python中Numba库装饰器

一、运行速度是Python天生的短板 1.1 编译型语言&#xff1a;C 对于编译型语言&#xff0c;开发完成以后需要将所有的源代码都转换成可执行程序&#xff0c;比如 Windows 下的.exe文件&#xff0c;可执行程序里面包含的就是机器码。只要我们拥有可执行程序&#xff0c;就可以随…

通讯录小项目(上)

Start And Stick 通讯录的实现有很多种方式&#xff0c;今天我们将用结构体实现简单的通讯录项目功能。包括通讯录的增、删、查、改等功能。 思路&#xff1a; 此次代码文件分别为&#xff1a; 文件名用途sqlist.h用于函数和结构体的声明sqlist.c用于函数的实现test.c用于通讯…

【JaveWeb教程】(38)SpringBootWeb案例之《智能学习辅助系统》的详细实现步骤与代码示例(11)过滤器Filter讲解

目录 SpringBootWeb案例10 过滤器Filter2.4 过滤器Filter2.4.1 快速入门2.4.2 Filter详解2.4.2.1 执行流程2.4.2.2 拦截路径2.4.2.3 过滤器链 2.4.3 登录校验-Filter2.4.3.1 分析2.4.3.2 具体流程2.4.3.3 代码实现 SpringBootWeb案例10 过滤器Filter 2.4 过滤器Filter 刚才通…

VBA技术资料MF111:将表对象转换为正常范围

我给VBA的定义&#xff1a;VBA是个人小型自动化处理的有效工具。利用好了&#xff0c;可以大大提高自己的工作效率&#xff0c;而且可以提高数据的准确度。我的教程一共九套&#xff0c;分为初级、中级、高级三大部分。是对VBA的系统讲解&#xff0c;从简单的入门&#xff0c;到…

大数据期望最大化(EM)算法:从理论到实战全解析

文章目录 大数据期望最大化&#xff08;EM&#xff09;算法&#xff1a;从理论到实战全解析一、引言概率模型与隐变量极大似然估计&#xff08;MLE&#xff09;Jensen不等式 二、基础数学原理条件概率与联合概率似然函数Kullback-Leibler散度贝叶斯推断 三、EM算法的核心思想期…

【JAVA】提交任务时,线程池队列已满,这时会发生什么

&#x1f34e;个人博客&#xff1a;个人主页 &#x1f3c6;个人专栏&#xff1a;JAVA ⛳️ 功不唐捐&#xff0c;玉汝于成 目录 前言 正文 抛出异常&#xff1a; 阻塞等待&#xff1a; 丢弃任务&#xff1a; 调整线程池参数&#xff1a; 使用拒绝策略&#xff1a; 结…

数字图像处理(实践篇)二十七 Python-OpenCV 滑动条的使用

目录 1 涉及的函数 2 实践 1 涉及的函数 ⒈ setWindowProperty()用于设置GUI应用程序的属性 cv2.setWindowProperty(windowsName, prop_id, prop_value) 参数: ①

张维迎《博弈与社会》笔记(4)导论:社会最优与帕累托标准

本节我们将从社会的角度来评判人类行为&#xff1a;一个社会应该采取什么样的标准来判断个人行为&#xff1f;具体地讲&#xff0c;我们需要知道&#xff0c;从社会的角度来评判&#xff0c;什么样的行为是正当的&#xff0c;什么样的行为是不正当的&#xff1b;什么样的行为应…

小电影网站上线之nginx配置不带www域名301重定向到www域名+接入腾讯云安全防护edgeone

背景 写了个电影网站&#xff08;纯粹搞着玩的&#xff09;&#xff0c;准备买个域名然后上线&#xff0c;但是看日志经常被一些恶意IP进行攻击&#xff0c;这里准备接入腾讯云的安全以及加速产品edgeone&#xff0c;记录下当时的步骤。 一、nginx配置重定向以及日志格式 ng…

C++ 隐式转换构造函数和explicit 关键字学习

据说在内核代码中,多个地方使用了explicit 关键字;下面看一下; 在 C++ 中,隐式转换构造函数指的是当我们将一种类型的值赋给该类对象时,编译器会自动调用相应的构造函数进行类型转换。这样可以使得不同类型之间能够互相赋值或者传参。 具体来说,当一个类有多个构造函数…

【归并排序】【图论】【动态规划】【 深度游戏搜索】1569将子数组重新排序得到同一个二叉搜索树的方案数

本文涉及知识点 动态规划汇总 图论 深度游戏搜索 归并排序 组合 LeetCoce1569将子数组重新排序得到同一个二叉搜索树的方案数 给你一个数组 nums 表示 1 到 n 的一个排列。我们按照元素在 nums 中的顺序依次插入一个初始为空的二叉搜索树&#xff08;BST&#xff09;。请你统…

瑞萨RL78G12系列单片机使用IAR软件进行仿真设置及与E2接线

目录 一、单片机与仿真器连接 二、IAR软件在线仿真使用手册 一、单片机与仿真器连接 E1引脚接线图 RL78系列单片机的GND接仿真器的pin2、pin12、pin14 RL78系列单片机的VDD接仿真器的pin8 RL78系列单片机的Tool0接仿真器的pin5 RL78系列单片机的Reset接仿真器的pin10、pin…

【计算机网络】深入掌握计算机网络的核心要点

写在前面 前言四层模型网络地址管理Linux下设置ipARP请求包总结 前言 计算机网络是指将分散的计算机设备通过通信线路连接起来&#xff0c;形成一个统一的网络。为了使得各个计算机之间能够相互通信&#xff0c;需要遵循一定的协议和规范。OSI参考模型和TCP/IP参考模型是计算机…

免费SSL数字证书申请,免费数字证书使用教程

为什么要使用SSL数字证书&#xff1f; 1. 数据加密&#xff08;SSL数字证书通过使用加密算法对传输的数据进行加密&#xff0c;保证数据在传输过程中不被篡改。&#xff09; 2. 使用了SSL数字证书&#xff0c;浏览器中不会显示不安全&#xff0c;小程序开通&#xff0c;给你的…

Java基础知识-异常

资料来自黑马程序员 异常 异常&#xff0c;就是不正常的意思。在生活中:医生说,你的身体某个部位有异常,该部位和正常相比有点不同,该部位的功能将受影响.在程序中的意思就是&#xff1a; 异常 &#xff1a;指的是程序在执行过程中&#xff0c;出现的非正常的情况&#xff0c;…

Pandas.DataFrame.mode() 众数 详解 含代码 含测试数据集 随Pandas版本持续更新

关于Pandas版本&#xff1a; 本文基于 pandas2.2.0 编写。 关于本文内容更新&#xff1a; 随着pandas的stable版本更迭&#xff0c;本文持续更新&#xff0c;不断完善补充。 传送门&#xff1a; Pandas API参考目录 传送门&#xff1a; Pandas 版本更新及新特性 传送门&…

452. 用最少数量的箭引爆气球 - 力扣(LeetCode)

题目描述 有一些球形气球贴在一堵用 XY 平面表示的墙面上。墙面上的气球记录在整数数组 points &#xff0c;其中points[i] [xstart, xend] 表示水平直径在 xstart 和 xend之间的气球。你不知道气球的确切 y 坐标。 一支弓箭可以沿着 x 轴从不同点 完全垂直 地射出。在坐标 …

34.基于51单片机的智能停车位计时收费系统设计

一、系统功能介绍&#xff1a; 本设计基于 RFID智能识别和高速的视频图像和存储比较相结合&#xff0c;通过计算机的图像处理和自动识别&#xff0c;对车辆进出停车场的收费、车牌识别和车位诱导等&#xff0c;以实现停车场全方位智能管理。 本设计是以AT89C51 型单片机为主控芯…

flutter-相关个人记录

1、flutter 安卓打包打包报错 flutter build apk -v --no-tree-shake-icons 2、获取华为指纹证书命令 keytool -list -v -keystore ***.jks 3、IOS项目中私有方法查找隐藏文件中 1、cd 项目目录地址 2、grep -r xerbla. "xerbla"为需要查找的关键字 3…