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

news2024/11/20 8:35:14

目录

什么是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 中的状态更新时,组件能够实时反映这些变化。

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

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

相关文章

(七)for循环控制

文章目录 用法while的用法for的用法两者之间的联系可以相互等价用for改写while示例for和while的死循环怎么写for循环见怪不怪表达式1省略第一.三个表达式省略&#xff08;for 改 while&#xff09;全省略即死循环&#xff08;上面已介绍&#xff09; 用法 类比学习while语句 …

Linux:命名管道及其实现原理

文章目录 命名管道指令级命名管道代码级命名管道 本篇要引入的内容是命名管道 命名管道 前面的总结中已经搞定了匿名管道&#xff0c;但是匿名管道有一个很严重的问题&#xff0c;它只允许具有血缘关系的进程进行通信&#xff0c;那如果是两个不相关的进程进行通信&#xff0…

C#,计算几何,二维贝塞尔拟合曲线(Bézier Curve)参数点的计算代码

Pierre Bzier Bzier 算法用于曲线的拟合与插值。 插值是一个或一组函数计算的数值完全经过给定的点。 拟合是一个或一组函数计算的数值尽量路过给定的点。 这里给出 二维 Bzier 曲线拟合的参数点计算代码。 区别于另外一种读音接近的贝塞耳插值算法&#xff08;Bessels int…

市场复盘总结 20240123

仅用于记录当天的市场情况&#xff0c;用于统计交易策略的适用情况&#xff0c;以便程序回测 短线核心&#xff1a;不参与任何级别的调整&#xff0c;采用龙空龙模式 一支股票&#xff0c;只有10%的时间是可以操作&#xff0c;90%的时候都应该空仓 昨日主题投资 连板进级率 7/1…

前端实现转盘抽奖 - 使用 lucky-canvas 插件

目录 需求背景需求实现实现过程图片示意实现代码 页面效果lucky-canvas 插件官方文档 需求背景 要求实现转盘转动抽奖的功能&#xff1a; 只有正确率大于等于 80% 才可以进行抽奖&#xff1b;“谢谢参与”概率为 90%&#xff0c;“恭喜中奖”概率为 10%&#xff1b; 需求实现 实…

鸿蒙入门学习的一些总结

前言 刚开始接触鸿蒙是从2023年开始的&#xff0c;当时公司在调研鸿蒙开发板能否在实际项目中使用。我们当时使用的是OpenHarmony的&#xff0c;基于DAYU/rk3568开发板&#xff0c;最开始系统是3.2的&#xff0c;API最高是API9&#xff0c;DevecoStudio 版本3.1的。 鸿…

国考省考行测:分析推理,形式逻辑,所有有的分析

国考省考行测&#xff1a; 2022找工作是学历、能力和运气的超强结合体! 公务员特招重点就是专业技能&#xff0c;附带行测和申论&#xff0c;而常规国考省考最重要的还是申论和行测&#xff0c;所以大家认真准备吧&#xff0c;我讲一起屡屡申论和行测的重要知识点 遇到寒冬&am…

2024三掌柜赠书活动第七期:一本书读懂AIGC:探索AI商业化新时代

目录 前言AI商业化的背景和挑战关于《一本书读懂AIGC&#xff1a;探索AI商业化新时代》编辑推荐内容简介作者简介图书目录书中前言/序言《一本书读懂AIGC&#xff1a;探索AI商业化新时代》全书速览结束语 前言 不用多讲&#xff0c;想必大家也都知道&#xff0c;人工智能在过…

LLM大语言模型(五):用streamlit开发LLM应用

目录 背景准备工作切记streamlit开发LLM demo开一个新页面初始化session先渲染历史消息接收用户输入模拟调用LLM 参考 背景 Streamlit是一个开源Python库&#xff0c;可以轻松创建和共享用于机器学习和数据科学的漂亮的自定义web应用程序&#xff0c;用户可以在几分钟内构建一…

optee编译调试

编译运行 使用的是 ubuntu22.04 需要提前设置好网络 optee运行环境搭建&#xff1a;https://optee.readthedocs.io/en/latest/building/prerequisites.html 安装必要的库 sudo apt install -y \adb \acpica-tools \autoconf \automake \bc \bison \build-essential \ccach…

MySQL十部曲之六:数据操作语句(DML)

文章目录 前言语法约定DELETEINSERTSELECT查询列表SELECT 选项子句FROMWHEREORDER BYGROUP BYHAVINGWINDOWLIMITFOR SELECT ... INTO连接查询CROSS JOIN和INNER JOINON和USINGOUTER JOINNATURE JOIN 子查询标量子查询使用子查询进行比较带有ANY、IN或SOME的子查询带有ALL的子查…

C++ //练习 3.5 编写一段程序从标准输入中读入多个字符串并将它们连接在一起,输出连接成的大字符串。然后修改上述程序,用空格把输入的多个字符串分隔开来。

C Primer&#xff08;第5版&#xff09; 练习 3.5 练习 3.5 编写一段程序从标准输入中读入多个字符串并将它们连接在一起&#xff0c;输出连接成的大字符串。然后修改上述程序&#xff0c;用空格把输入的多个字符串分隔开来。 环境&#xff1a;Linux Ubuntu&#xff08;云服务…

网络安全B模块(笔记详解)- 越权与下载

1.使用渗透机场景kali中工具扫描服务器场景&#xff0c;将web端口号当作Flag提交&#xff1b; 2.使用渗透机场景windows7访问服务器场景mingling.php,将页面中的Flag提交&#xff1b; 3.使用渗透机场景windows7访问服务器场景mingling.php&#xff0c;分析页面内容&#xff0…

SpringBoot引入 liteflow 规则引擎,yyds!

1前言 在日常的开发过程中&#xff0c;经常会遇到一些串行或者并行的业务流程问题&#xff0c;而业务之间不必存在相关性。 在这样的场景下&#xff0c;使用策略和模板模式的结合可以很好的解决这个问题&#xff0c;但是使用编码的方式会使得文件太多,在业务的部分环节可以这…

Apache Shiro <= 1.2.4反序列化漏洞攻击 CVE-2016-4437 已亲自复现

Apache Shiro < 1.2.4反序列化漏洞攻击 CVE-2016-4437 已亲自复现 漏洞名称漏洞描述影响版本 漏洞复现环境搭建漏洞利用 修复建议总结 漏洞名称 漏洞描述 在 1.2.5 之前的 Apache Shiro 中&#xff0c;当未为“记住我”功能配置密钥时&#xff0c;远程攻击者可以通过未指定…

去创造,不要消费

最近&#xff0c;想必许多人的社交圈&#xff0c;都被B站的五四视频《后浪》刷屏了。 如果你没看过&#xff0c;也没关系&#xff0c;因为我并不打算讲它。 &#xff08;熟悉我的老读者会知道&#xff0c;我文章最开头的东西一般只是个引子&#xff0c;并不重要&#xff09; 言…

Peter算法小课堂—二叉堆(优先队列)

课前小视频&#xff1a;(7 封私信 / 62 条消息) 看动画&#xff0c;学算法&#xff0c;C实现建立二叉堆&#xff0c;优先队列和堆排序的基础 - 知乎 (zhihu.com) 二叉堆&#xff08;优先队列&#xff09; 大家想想&#xff0c;什么数据结构能做到插入&#xff08;删除&#x…

mysql8安装基础操作(一)

一、下载mysql8.0 1.查看系统glibc版本 这里可以看到glibc版本为2.17&#xff0c;所以下载mysql8.0的版本时候尽量和glibc版本对应 [rootnode2 ~]# rpm -qa |grep -w glibc glibc-2.17-222.el7.x86_64 glibc-devel-2.17-222.el7.x86_64 glibc-common-2.17-222.el7.x86_64 gl…

C++爱好者的科目四易错点总结

科目四易错点总结 在科目四考试中&#xff0c;一部分内容是可以通过刷题快速掌握的&#xff0c;一部分内容缺因易混淆而降低我们的准确率&#xff0c;本文主要对后者进行总结&#xff0c;期待大家补充与指正。 注&#xff1a; 本文不是全部的知识点总结处 本文不是权威机构 本文…

Linux:利用匿名管道构建进程池

文章目录 进程池实现进程池创建信道和进程发送任务释放资源 进程池代码总结 本篇的主题是借助前面所学的基础管道实现一个进程池&#xff0c;那么在实现进程池前先了解进程池是什么&#xff0c;进程池有什么意义&#xff0c;进而对于进程池有一个基本的把握 进程池 给定一个进…