派发器思想应用
开发Vue中遇到的最大的问题就是框架的规范性太强,导致所有的业务方法都必须定义在methods对象里,代码可以达到几百行,甚至几千行。当然,也可以通过抽离组件的方式来查拆分业务,但是还是会存在大量的业务逻辑堆积。这时,使用JS的派发器思想就可以进行业务逻辑的抽离,便于后期维护。
废话不多说,直接上干货。
1. 案例效果
案例是比较简单的,是一个数值计算案例。
点击 + 的时候让数值加1;
点击 - 号的时候数值减1;
包括3个组件。Button组件、Result组件、Counter组件。
Button组件触发事件处理函数,用于事件的处理;
Result组件用来显示计算后的结果;
Counter组件用来处理数值计算的业务;
本次的目的就是抽离Counter组件的业务逻辑。
2. 目录结构
由于案例比较简单,大概说一下实现流程。
首先创建一个简单的Vue项目。项目不涉及Vue-Router和Vuex,一切从简。
vue create vue_dispatch // 创建项目
创建基础项目后,删掉没用的样式和组件,在components文件中编写自己的组件,实现对应的逻辑后,在App.vue中引入。
代码如下:
App.vue
<template>
<div id="app">
<counter />
</div>
</template>
<script>
import Counter from './components/Counter';
export default {
name: 'App',
components: {
Counter
}
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
index.vue
<template>
<div class="counter-container">
<!-- 结果显示区域 -->
<counter-result :result="result" />
<!-- Button 按钮组 -->
<div>
<counter-button
innerText="+"
type="PLUS"
@handBtnClick="handBtnClick"
/>
<counter-button
innerText="-"
type="MINUS"
@handBtnClick="handBtnClick"
/>
</div>
</div>
</template>
<script>
import CounterResult from './Result';
import CounterButton from './Button';
export default {
name: 'Counter',
components: {
CounterResult,
CounterButton
},
data () {
return {
result: 0
}
},
methods: {
handBtnClick (type) {
switch (type) {
case 'PLUS':
this.result++;
break;
case 'MINUS':
this.result--;
break;
default:
break;
}
}
}
}
</script>
Button.vue
<template>
<button
class="counter-btn"
:type="type"
@click="count"
>
{{ innerText }}
</button>
</template>
<script>
export default {
name: 'CounterButton',
props: {
innerText: String,
type: String
},
methods: {
count () {
this.$emit('handBtnClick', this.type);
}
}
}
</script>
<style scoped>
.counter-btn {
width: 60px;
height: 40px;
margin: 5px;
}
</style>
Result.vue
<template>
<h1>{{ result }}</h1>
</template>
<script>
export default {
name: 'CounterResult',
props: {
result: Number
}
}
</script>
3. 优化思路
实现思路
type -> 事件 -> 逻辑 -> type -> 派发器 -> 数据更改
你会发现,派发器的思想其实和redux是一致的,只不过在这里不对store进行实现,只实现reducer、type和dispatch部分。还有,如果项目中没有特别较多需要共享的状态,不需要引入redux或者vuex,它们只是为我们提供便利的中央数据存储。
4. 项目优化
a. 创建actions文件夹,新建counter.js文件
actions/counter.js
定义action类型,旨在通过不同的action触发不同的操作。
const PLUS = "PLUS",
MINUS = "MINUS";
export {
PLUS,
MINUS
};
b. 创建reducers文件夹,新建counter.js文件
reducers/counter.js
主要定义操作数据的纯函数。
function counterReducer (data) {
function plus () {
return data.result + 1;
}
function minus () {
return data.result - 1;
}
return {
plus,
minus
};
}
export default counterReducer;
c. 创建dispatchers文件夹,新建counter.js文件
使用定义的reducer和action,用于业务逻辑处理。
import reducer from '@/reducers/counter';
import { PLUS, MINUS } from '@/actions/counter';
export default (ctx) => {
const { plus, minus } = reducer(ctx.$data);
return function (type, ...args) {
switch (type) {
case PLUS:
ctx.result = plus(...args);
break;
case MINUS:
ctx.result = minus(...args);
break;
default:
break;
}
}
}
d. 改造现有业务逻辑
components/Counter/index.vue
methods对象现有方法
methods: {
handBtnClick (type) {
switch (type) {
case 'PLUS':
this.result++;
break;
case 'MINUS':
this.result--;
break;
default:
break;
}
}
}
methods对象改造后
methods: {
handBtnClick (...args) {
dispatch(this)(...args);
}
}
测试当前程序,可以正常运行。相比于之前来说,现在的逻辑要比之前清晰很多,当业务复杂时,这种对比效果就更加明显,使用这种方式可以有效的分割业务代码,易于项目后期的拓展与维护。
e. 代码优化
处理一下方法名称和传递的参数名,使之更加规范。
Counter/index.vue
<template>
<div class="counter-container">
...
<div>
<counter-button
innerText="+"
action="PLUS"
@dispatch="dispatch"
/>
<counter-button
innerText="-"
action="MINUS"
@dispatch="dispatch"
/>
</div>
</div>
</template>
<script>
...
export default {
...
methods: {
dispatch (...args) {
dispatch(this)(...args);
}
}
}
</script>
Counter/Button.vue
<template>
<button
class="counter-btn"
:action="action"
@click="count"
>
{{ innerText }}
</button>
</template>
<script>
export default {
name: 'CounterButton',
props: {
innerText: String,
action: String
},
methods: {
count () {
this.$emit('dispatch', this.action);
}
}
}
</script>
5. 总结
通过一个数值计算案例,讲解如何使用派发器的思想来抽离业务逻辑。当业务复杂时,可以通过这种思路来优化代码,进行业务逻辑的抽离。这仅是一种优化的思路,作为一个合格的攻城狮,不仅要实现功能,更要考虑功能后期的拓展与维护。