使用场景
比如,后台管理类的项目;
常见的功能就是表格的增删改查, 里边有很多重复的逻辑代码;
是否可以用es6的class把公共功能提取封装,页面中store用继承方式减少重复代码;
兼容版本
- vue2.7以上
- vue3
示例代码
1、简单示例
- view/demo/store/index.js
import { computed, ref } from "vue";
class Store {
/* 响应式数据 */
num = ref(0)
/* 计算属性 */
sum = computed(()=>{
return this.num.value + 10
})
/* 函数,可改成异步函数 */
addNum = () => {
this.num.value++
}
}
/* 抛出单例,否则多组件不共享状态 */
export default new Store()
- view/demo/index.vue
<template>
<div @click="addNum">
<p>{{ num }}</p>
<p>{{ sum }}</p>
</div>
</template>
<script setup>
import store from "./store"
/*
须把响应式数据解构出来,然后再绑定数据!
不能在template里边用store.num 绑定,组件不刷新
*/
const { num, sum, addNum } = store
</script>
<style lang="less" scoped></style>
2、若有多个状态属于同一个功能点可以用reactive
- view/demo/store/index.js
import {
reactive,
} from "vue";
class Store {
/* 若有多个状态属于同一个功能点可以用reactive */
dataSource = reactive({
list: [],
cust: '6'
})
/* 改变当前选中项 */
changeCust = (item) => {
this.dataSource.cust = item.id;
}
/* 模拟请求 */
getDataSource = () => {
let arr = []
for (let index = 1; index <= 10; index++) {
arr.push({
id: index + '',
name: `你好${index}`
})
}
this.dataSource.list = arr;
}
}
/* 抛出单例,否则多组件不共享状态 */
export default new Store()
- view/demo/index.vue
<template>
<div class="demo-box">
<ul>
<li v-for="item in dataSource.list" :key="item.id" :class="`${dataSource.cust === item.id ? 'cust-sel' : ''}`"
@click="changeCust(item)">
{{ item.name }}
</li>
</ul>
</div>
</template>
<script setup>
import { onMounted } from "vue"
import store from "./store"
const { dataSource, getDataSource, changeCust } = store
onMounted(getDataSource)
</script>
<style lang="less" scoped>
.cust-sel {
background: red;
color: #fff;
}
</style>
3、公共逻辑封装、继承
- src/store/base.js<父类>
import {
reactive,
ref
} from "vue"
class BaseStore {
constructor(props){
this.api = props.api;
}
/* 每模块接口可能不一样,存一个api */
api = {}
/* 表格 */
tableData = reactive({
search: {},
list: [],
pagination: {
cust: 1,
size: 20,
}
})
/* 详情 */
detailData = ref({})
/* 查询 */
onSearch = () => {
let arr = []
for (let index = 1; index <= 10; index++) {
arr.push({
id: index + '',
name: `你好${index}`
})
}
this.tableData.list = arr;
}
/* 新增 */
onCreate = (item) => {
/* 调用新增接口... */
}
/* 修改 */
onEdit = (item) => {
/* 调用修改接口... */
}
/* 删除 */
onDelete = (ids) => {
/* 调用删除接口... */
}
/* 其他公共方法或属性... */
}
/* 这里直接抛出类,子类要继承; 不要抛出单例 */
export default BaseStore
- view/demo/store/index.js
import BaseStore from "@/store/base.js"
/* 继承父类功能 */
class Store extends BaseStore{
constructor(){
/* 初始化父类接口信息 */
super({
api: {
search: {
url: '/search',
method: 'get'
},
create: {
url: '/create',
method: 'post'
},
edit: {
url: '/edit',
method: 'post'
},
delete: {
url: '/delete',
method: 'post'
},
}
})
}
}
/* 抛出单例,否则多组件不共享状态 */
export default new Store()
- view/demo/index.vue
<template>
<div class="demo-box">
<ul>
<li v-for="item in tableData.list" :key="item.id">
{{ item.name }}
</li>
</ul>
</div>
</template>
<script setup>
import { onMounted } from "vue"
import store from "./store"
const { tableData, onSearch } = store
onMounted(onSearch)
</script>
<style lang="less" scoped>
</style>
结语
- 上边是使用reactive实现全局状态管理使用方法,包括开始提到的后台管理类代码提取继承;
- 大家碰到类似项目有没有更好的实现方式?
- 最后感谢尤大大开发这么好用的框架 orz