导言
不得不说前端是真的卷,Vue-cli 的核心开发者这又出了一个新的 cli,create-vue,基于 Vite2 和 Vue3 的脚手架工具。目前虽然还只是在开发中,很多功能都不太完善,但可以想象到未来 create-vue 大概率会逐渐替代掉 vue-cli 的...
一、create-vue
1. 安装
安装很简单,只需要一行 npm 语句,不过需要注意下,create-vue 只能安装在非中文路径、中文名称的文件夹下。
npm init vue@next
一些配置:
- 项目名称
- 是否安装 TS
- 是否安装 JSX
- 是否安装 router
- 是否安装 vuex
- 是否安装 Cypress 测试
文件目录配置也没有太大区别
进入文件夹后首先安装配置文件
npm install
运行
npm run dev
2. 简单体验
其实使用上与 Vue-cli+Vue3 没区别,只是这个脚手架组件页面的 template、script、style 三者标签顺序有改变。
App.vue
嵌套路由
页面展示
二、Pinia
官网:
Pinia 是 Vuex 团队成员新开发的一个 Vue 的状态管理方案。
在 Pinia 中减去了 mutations 以及 module 两个概念,转而使用 actions 代替 mutations 完成同异步方法。
同时 Pinia 中的每个 store 都拥有自己的 id,是互相独立的状态库,且在 store 中可以通过 id 直接导入其它的 store 使用。
其优点:
- 完整的 TypeScript 支持。
- 及其轻巧(体积大约 1kb)
- Store 中的 Actions 配置项既可以直行同步方法也可以支持异步方法。
- 模块不需要嵌套,可以声明多个 Store。
- 支持 Vue DevTools、SSR 和 Webpack 代码拆分。
**Tips:**Pinia 不是用来代替 Vuex 的,它们的应用场景不同。
Pinia 该什么时候使用?
- Pinia 是轻量级的,体积小,更加适合中小型项目,如果是大型项目还是更加适合 Vuex。
- Pinia 中无论同步还是异步改变 state,都用 Actions,如果在 Vuex 中分辨不清 mutations 和 Actions 的概念可以使用 Pinia。
- Pinia 中完整支持 TypeScript,不会给 Vuex 添加 TypeScript,就用 Pinia。
1. 安装和配置 Pinia
- 安装:
npm i pinia@next
- 在入口文件中挂载 Pinia
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
// 引入 Pinia
import { createPinia } from 'Pinia'
const app = createApp(App)
// 使用 Pinia
app.use(createPinia())
app.use(router)
app.mount('#app')
- 在 src/stores/index.js 文件夹中声明 store。
Pinia 通过 defineStore 定义 store,这个 API 拥有两个参数,第一个参数是它的唯一性 id,通过这个唯一性 id,我们可以在其它仓库去引用它。
第二个参数就是常规的 store、getters、actions 可选项。
defineStore('id', {options})
// 引入 Pinia 定义
import { defineStore } from 'pinia'
// 定义
export const useUserStore = defineStore('user', {
state: () => {
return {
name: 'achens'
}
}
})
- 在组件页面引入并使用
<script setup>
// 引入 useUserStore
import { useUserStore } from './stores';
// 使用 useUserStore
const store = useUserStore()
// 输出:achens
console.log(store.name)
</script>
2. state 与 getters 的使用
1.使用 storeToRefs 引入 state
使用 Pinia 中的 storeToRefs 去解构引入的 store。
storeToRefs 会将 store 中的 state、getters、actions 转换为 ref 响应式对象。
// 引入 storeToRefs
import { storeToRefs } from 'pinia'
// 引入 useUserStore
import { useUserStore } from './stores';
// 使用 storeToRefs 解构式拿出 useUserStore 中的 state
const { name } = storeToRefs(useUserStore())
// 输出: ref 对象
console.log(name)
// 输出:张三
console.log(name.value)
将其放到页面中也是直接使用
<template>
<h1>Hello achens!</h1>
<!-- <p>直接使用 store:{{ store.name }}</p> -->
<p>使用 storeToRefs:{{ name }}</p>
<router-link to="/home">首页</router-link>
<router-link to="/about">关于页</router-link>
<router-view></router-view>
</template>
2. Pinia 中的 Getters
1. 简单使用 Getters
定义 getters 与 Vuex 没有什么太大的区别。
import { defineStore } from 'pinia'
export const useUserStore = defineStore('user', {
state: () => {
return {
name: '张三',
count: 5
}
},
getters:{
// 以箭头函数的方式声明一个 getters,使 state.count 的值永远乘以2。
// getters 的第一个参数永远是 state,这点与 Vuex 相比没有区别。
doubleCount: state => state.count * 2
}
})
<template>
<h1>Hello achens!</h1>
<!-- <p>直接使用 store:{{ store.name }}</p> -->
<p>使用 storeToRefs:{{ name }}</p>
// 使用 getters
<p>{{ count }} -- {{ doubleCount }}</p>
<router-link to="/home">首页</router-link>
<router-link to="/about">关于页</router-link>
<router-view></router-view>
</template>
2. 访问自己 store 中的其它 Getters
如果想要在 getters 中互相访问,就必须得将箭头函数改为普通函数的形式,在通过 this 调用相同 store 中的其它 getters。
import { defineStore } from 'pinia'
export const useUserStore = defineStore('user', {
state: () => {
return {
name: '张三',
count: 5
}
},
getters:{
doubleCount(state){
return state.count * 2
},
// 在 getters 中使用其它 getters
doubleCountPlus(state){
return this.doubleCount + 1
}
})
<template>
<h1>Hello achens!</h1>
<!-- <p>直接使用 store:{{ store.name }}</p> -->
<p>使用 storeToRefs:{{ name }}</p>
<p>{{ count }} -- {{ doubleCount }} -- {{ doubleCountPlus }}</p>
<router-link to="/home">首页</router-link>
<router-link to="/about">关于页</router-link>
<router-view></router-view>
</template>
3. 给 Getters 传递参数
想要给 getters 传参,稍微有那么点麻烦,如果传了参数,则必须在其内部用箭头函数接收并使用它,最后将其返回出去。
// ...多余代码不粘贴了
doubleCountPlus(state, a){
// 使用箭头函数拿到这个参数并在使用完后返回
return a => {
return this.doubleCount + a
}
}
<!-- 多余代码不粘贴了 -->
<p>{{ count }} -- {{ doubleCount }} -- {{ doubleCountPlus(5) }}</p>
4. 访问其它 store 中的 Getters
在 src/store 下新建 default.js 文件夹声明一个新的 store。
import { defineStore } from 'pinia'
export const useDefaultStore = defineStore('default', {
state: () => {
return {
time: 2
}
},
getters:{
calcTime(state){
return state.time + 2
}
},
})
在 index.js 中引用 default.js 中的 useDefaultStore。
import { defineStore } from 'pinia'
// 引入同文件夹下的 useDefaultStore
import { useDefaultStore } from './default'
export const useUserStore = defineStore('user', {
state: () => {
return {
name: '张三',
count: 5
}
},
getters:{
doubleCount(state){
return state.count * 2
},
doubleCountPlus(state, a){
return a => {
return this.doubleCount + a
}
},
addDefault(state){
// 拿到 useDefaultStore
const defaultStore = useDefaultStore()
return state.count + defaultStore.calcTime
}
}
})
<p>{{ count }} -- {{ doubleCount }} -- {{ doubleCountPlus(5) }}</p>
<p>{{ addDefault }}</p>
3. 使用 actions 处理同异步任务
1. 处理同步任务
在 actions 中如果要修改 state 中的值的话,得使用 this.xxx 来获取 state 中的数据并进行修改。
// ... 其它代码省略
actions:{
addCount(num){
this.count += num
}
}
而且不能使用 storeToRefs 引用 actions 方法。
// 在 useUserStore 中拿出方法
const { addCount } = useUserStore()
页面中也如正常方式一样使用就可以。
<p>{{ count }}</p>
<button @click="addCount(2)">点击</button>
2. 处理异步任务
添加定时器设置为异步任务也没有任何问题。
actions:{
addCount(num){
setTimeout(() => {
this.count += num
}, 1000)
}
}
4. 品牌管理案例
1. 渲染数据
v-for 渲染使用 storeToRefs 结构出来的 state(brandList)。
2. 添加数据
v-model 双向绑定 state 中的数据对象(brand)。 v-on 绑定 actions 点击事件 addBrand(),将 brand 值加入(使用 push) brandList 中。并清空 brand 的值。
3. 删除数据
v-on 绑定 actions 点击事件 delBrand(id),并在点击时将本行 brand 的 id 传入。然后通过 id 删除(filter)指定 brand。 this.brandList = this.brandList.filter(item => itme.id ! == id)
- id 不等于就返回
- id 等于就不返回
4. 搜索数据
在 state 中添加一个 keywords 搜索字段,并使用 v-model 与其对应的 input 进行双向绑定。 在之后定义一个 searchResult 计算属性,并对 brandList 中的每一项品牌名称都进行一遍过滤,返回包好关键字的每一项。 state.brandList.filter(item => item.name.includes(state.keywords)) 最后将 v-for 中的 brandLIst 替换成 searchResult。
三、结语
总的来说 create-vue 与 Vue-cli 使用并无大异,只是说一个是用 Webpack5 作为打包工具,一个则是使用 Vite2 打包工具。且 Vue-cli 可选 Vue2、3 的版本,而 Create-vue 则是默认 Vite2 + Vue3 +
四、坑
1. 坑一,create-vue 安装路径不能有中文。
2. 坑二,项目配置名称中不能带加号
如图必须是:create-vue-pinia。
而不能是:create-vue+pinia。
否则就会报错:
原文地址:www.yuque.com/docs/share/…