Vue3--Vite和Pinia
一、PNPM
pnpm是 Node.js 的替代包管理器。它是 npm 的直接替代品,但速度更快、效率更高。
为什么效率更高 ? 当您安装软件包时, 我们会将其保存在您机器上的全局存储中,然后我们会从中创建一个硬链接(pnpm 通过硬链接的方式保证了相同的包不会被重复下载,比如说我们已经在 A 中下载过一次 xxx@4.17.1 版本,那我们后续在 B 中安装 xxx@4.17.1 的时候是会被复用的,具体就是 A 中的 xxx 中的文件和 B 中的 xx 中的文件指向的是同一个 )
PNPM不是进行复制。对于模块的每个版本,磁盘上只保留一个副本。例如,当使用 npm 或 yarn 时,如果您有 100 个使用的包,则磁盘上将有 100 个 lodash 副本。pnpm 可让您节省数 GB 的磁盘空间!
安装:npm install -g pnpm
二、vite
原来咱们学习v3的时候 使用的是vue/cli脚手架(实质上是帮助我们封装好了webpack来帮助我们构建与编译项目)
Vite 是 vue 的作者尤雨溪在开发 vue3.0的时候开发的一个 web 开发构建工具。其本人在后来对 vue3 的宣传中对自己的新作品 Vite 赞不绝口,并表示自己 ”再也回不去 webpack 了“ 。那么 Vite 究竟有什么魅力
2.1、Vite 和 Webpack 区别
Vite 优势:
1.vite 开发服务器启动速度比 webpack 快 webpack 会先打包,然后启动开发服务器,请求服务器时直接给予打包结果。 vite 在启动开发服务器时不需要打包,也就意味着不需要分析模块的依赖、不需要编译,因此启动速度非常快。当浏览器请求某个模块时,再根据需要对模块内容进行编译。这种按需动态编译的方式,极大的缩减了编译时间,项目越复杂、模块越多,vite的优势越明显。
2.vite 热更新比 webpack 快 当改动了一个模块后,vite仅需让浏览器重新请求该模块即可,不像webpack那样需要把该模块的相关依赖模块全部编译一次,效率更高。
3.vite 构建速度快,比 webpack 的 nodejs,快 10-100 倍。
Vite 劣势:
1.生态不及webpack,加载器、插件不够丰富
2.项目的开发浏览器要支持 ES Module,而且不能识别 CommonJS 语法
2.2、搭建一个Vite项目
pnpm create vite
在创建出的文件夹下下载依赖cnpm i:然后pnpm run dev即可
vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from 'path'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
'@': resolve(__dirname, './src')
}
}
})
2.3、路由使用
1.创建文件夹用来容纳 页面views与路由规则router
2. 新建路由页面
3.配置路由规则--与下载路由
pnpm install --save vue-router@4
如果报错===》下载时不用携带后面的@4
4 设置路由出口
在app.vue中设置 router-view
5 注入路由
在main.js中引用使用路由
import router from './router'
createApp(App).use(router).mount('#app')
2.4、vuex
1.下载:pnpm install --save vuex
2.创建对应容纳文件夹 store
3.编写vuex相关内容
在store/index.js中创建
import { createStore } from 'vuex'
export default createStore({
state: {
},
getters: {
},
mutations: {
},
actions: {
},
modules: {
}
})
4.在项目中配置vuex
import store from './store'
createApp(App).use(store).use(router).mount('#app')
三、pinia
pinia是一个用于vue的状态管理库,类似于vuex,是vue的另一种状态管理工具
Pinia意为菠萝,表示与菠萝一样,由很多小块组成。在pinia中,每个store都是单独存在,一同进行状态管理。 很多人也将pinia称为vuex5,因为pinia将作为vue3推荐的状态管理库,而vuex将不再迭代。
3.1、与vuex有什么不同
与 Vuex 相比,Pinia 提供了一个更简单的 API,具有更少的规范,提供了 Composition-API 风格的 API,最重要的是,在与 TypeScript 一起使用时具有可靠的类型推断支持。
1.mutations 不再存在。
2.无需创建自定义复杂包装器来支持 TypeScript,所有内容都是类型化的,并且 API 的设计方式尽可能利用 TS 类型推断。
3.不再需要注入、导入函数、调用函数、享受自动完成功能!
4.无需动态添加 Store,默认情况下它们都是动态的
5.不再有 modules 的嵌套结构
安装(仅限于vue3)
通过你喜欢的包管理器安装
pnpm install pinia yarn add pinia npm install --save pinia
3.2、pinia基本使用
1.创建pinia实例并挂载
在main.ts中
import App from './App.vue'
// 引用
import {createPinia } from 'pinia'
// 创建Pinia实例
const Pinia = createPinia()
// 挂载pinia
createApp(App).use(Pinia).mount('#app')
2.在src目录下新建一个stroe文件夹,在文件夹中新建一个index.ts
3.通过import将下载好的pinia引入到index.ts中并导出 并且使用defineStore创建store对象
import { defineStore } from 'pinia'
// 第一个参数是应用程序中 store 的唯一 id
export const useStore = defineStore('main', {
})
3.3、pinia--state
state 是 store 的核心部分。 我们通常从定义应用程序的状态开始。 在 Pinia 中,状态被定义为返回初始状态的函数。 Pinia 在服务器端和客户端都可以工作。
1.创建state
import { defineStore } from 'pinia'
// useStore 可以是 useUser、useCart 之类的任何东西
// 第一个参数是应用程序中 store 的唯一 id
export const useStore = defineStore('main', {
state:()=>{//创建状态
return {
text:"我是pinia的一个状态变量"
}
}
})
2.组件中使用
<template>
<div>
<!-- 3.使用 -->
我是测试pinia的组件--{{store.text}}
</div>
</template>
<script lang="ts" setup>
// 1.引用
import {useStore} from "../store/index"
// 2.创建
let store=useStore()
</script>
3.4、pinia--修改--action
修改方式1
1.组件内创建触发
调用修改方法 store.你在pinia中actions中创建的修改函数
<template>
<div>
我是测试pinia的组件--{{store.text}}
<button @click="update()">点我修改</button>
</div>
</template>
<script lang="ts" setup>
import {useStore} from "../store/index"
let store=useStore()
let update=()=>{
// 调用修改方法 store.你在pinia中actions中创建的修改函数
store.updatetext()
}
</script>
2.pinia中创建修改方法
import { defineStore } from 'pinia'
export const useStore = defineStore('main', {
state:()=>{
return {
text:"我是pinia的一个状态变量"
}
},
actions:{
updatetext(){//修改方法
this.text="我变了"
}
}
})
修改方式2--$patch
$patch是pinia的内置方法 通过该方法可以直接修改state的数据
方式1:在组件内调用$parch 便可直接修改数据
let update=()=>{
store.$patch({
//你要修改state的数据: 你要修改的value值
text:"我是$patch直接修改"
})
}
方式2
let update=()=>{
store.$patch((state)=>{
console.log(state)
state.text="你又被改了"
})
}
pinia--修改常见问题
<template>
<div>
我是测试pinia的组件--{{text}}
<button @click="update()">点我修改</button>
</div>
</template>
<script lang="ts" setup>
import {useStore} from "../store/index"
import {storeToRefs} from "pinia"
let store=useStore()
// 解构取值
// let {text}=store
// storeToRefs 让数据快去取出 并且不丢失响应式
let {text}=storeToRefs(store)
let update=()=>{
// 调用修改方法 store.你在pinia中actions中创建的修改函数
store.updatetext()
}
</script>
3.5、pinia--重置数据--$reset
顾名思义就是让数据恢复成state的初始值
<template>
<div>
我是测试pinia的组件--{{store.text}}
<button @click="update()">点我修改</button>
<button @click="reset()">点我恢复初始值</button>
</div>
</template>
<script lang="ts" setup>
import {useStore} from "../store/index"
let store=useStore()
let update=()=>{
store.updatetext()
}
let reset=()=>{
// $reset
store.$reset()
}
</script>
3.6、pinia--监听数据修改--$subscribe
$subscribe 监听store数据修改 当数据改变了 那么subscribe也会触发
<template>
<div>
我是测试pinia的组件--{{store.text}}
<button @click="update()">点我修改</button>
</div>
</template>
<script lang="ts" setup>
import {useStore} from "../store/index"
let store=useStore()
let update=()=>{
store.updatetext()
}
// 监听store数据修改
let sub=store.$subscribe((params,state)=>{
console.log("params",params);
console.log("state",state);
})
</script>
3.7、pinia--处理异步操作--action
在pinia中acition不但能处理同步操作 同样也可以处理异步操作
使用方式和之前一致
<template>
<div>
我是测试pinia的组件--{{store.text}}
<button @click="demoAxios()">点我获取异步数据</button>
</div>
</template>
<script lang="ts" setup>
import {useStore} from "../store/index"
let store=useStore()
let demoAxios=()=>{
store.link()
}
</script>
import { defineStore } from 'pinia'
import $http from "axios"
export const useStore = defineStore('main', {
state:()=>{
return {
text:"我是pinia的一个状态变量"
}
},
actions:{
async link(){
try {
let data= await $http({
url:"http://localhost:8888/userlist/demoget",
method:"get"
})
console.log(data.data.data.name)
this.text=data.data.data.name
} catch (error) {
console.log("失败")
}
}
}
})
3.8、pinia--getters
import { defineStore } from 'pinia'
export const useStoreb = defineStore('mainb', {
state:()=>{
return {
text:"abcdefg"
}
},
actions:{
},
getters:{
newtext():any{
return this.text.toUpperCase()
}
}
})
3.9、pinia--模块化
pinia中定义模块 只需要定义多个store即可 因为pinia没有单一数据源这个概念 在其中可以定义多个store对象
<template>
<div>
我是测试pinia的组件--{{storeone.text}}---{{storetwo.text}}
</div>
</template>
<script lang="ts" setup>
// 引用第一个store
import {useStore} from "../store/index"
// 引用第2个store
import {useStoreb} from "../store/indexb"
let storeone=useStore()
let storetwo=useStoreb()
</script>