经常会遇到一个组件又臭又长,思考怎么去让组件变得简单,更单纯点
vue2组件设计和派发器
派发器 -> 模式 -> 改造 -> 组件逻辑部分
- 抽离合适的部分不让method变得臃肿
- type -> 事件 -> 逻辑 -> type -> 派发器 -> 数据更改
组件化设计
- 由外到内
- 页面组件
- 块组件 -> 组件出口 + 子组件
例子1
- router/index.js
import Vue from 'vue'
import Router from 'vue-router'
import IndexPage from '@/pages/Index.vue'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
name: 'IndexPage',
component: IndexPage
}
]
})
- pages/Index.vue
<template>
<Counter />
</template>
<script>
import Counter from "@/components/Counter.vue";
export default {
components: {
Counter
}
}
</script>
- components/Counter.vue
<template>
<div>
<counter-result :result='result'/>
<div>
<counter-button
innerText="+"
action="PLUS"
@compute="compute"
/>
<counter-button
innerText="-"
action="MiNUS"
@compute="compute"
/>
</div>
</div>
</template>
<script>
import CounterResult from './CounterResult'
import CounterButton from './CounterButton'
export default {
name: "Counter",
components: {
CounterResult,
CounterButton
},
data() {
return {
result: 0
}
},
methods: {
compute(action) {
swith(action) {
case "PLUS":
this.result += 1;
break;
case "MiNUS":
this.result -= 1;
break;
default:
break;
}
}
}
}
</script>
- components/CounterResult.vue
<template>
<h1>{{ result }}</h1>
</template>
<script>
export default {
name: "CounterResult",
props: {
result: {
type: Number,
default: 0
}
}
}
</script>
- components/CounterButton
<template>
<button :action="action" @click="compute">{{innerText}}</button>
</template>
<script>
export default {
name: 'CounterButton',
props: ['innerText', 'action'],
methods: {
compute() {
this.$emit('compute', this.action);
}
}
}
</script>
对上面的进行改造
- 创建 actions
- 在目录下建立 counter.js
- 创建 reducer
- 在目录下建立 counter.js
- 创建 dispatch
- 在目录下建立 counter.js
// => actions/counter.js
export const PLUS = 'PLUS';
export const MINUS = 'MINUS';
// reducer/counter.js
function counterReducer(data) {
function plus() {
return data.result + 1;
}
function minus() {
return data.result - 1;
}
return {
plus,
minus
}
}
export default counterReducer;
// dispatch/counter.js
import reducer from "@/reducers/counter"
import { PLUS, MINUS } from '@/actions/counter'
/**
* ctx: 上下文组件
*/
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;
}
}
}
- 到组件中去使用
- components/Counter.vue
<template>
<div>
<counter-result :result='result'/>
<div>
<counter-button
innerText="+"
action="PLUS"
@compute="compute"
/>
<counter-button
innerText="-"
action="MiNUS"
@compute="dispatch"
/>
</div>
</div>
</template>
<script>
import CounterResult from './CounterResult'
import CounterButton from './CounterButton'
// => 使用 dispatch
import dispatch from '@/dispatch/counter'
export default {
name: "Counter",
components: {
CounterResult,
CounterButton
},
data() {
return {
result: 0
}
},
methods: {
dispatch(...args) {
dispatch(this)(...args);
}
}
}
</script>
总结: 组件的内部逻辑是非常复杂的时候,类型比较多,操作比较多,可通过上述方法进行组件的提纯