派发器vue2单组件逻辑抽离
陌年微凉_ 人气:0概述
在vue2当中,我们写的逻辑都是options配置对象,比较固定的写法,方法,数据,都对应到各自的配置项当中,但是当一个组件的逻辑变得更加复杂,逻辑也越来越多的时候,这时候,我们一个组件避免不了要写大量的逻辑代码,在2版本中,使用官方推荐的mixin可以解决一个组件逻辑过多的问题,现在记录我在工作用用到的另外方法。
本质
在react中,我们使用redux,会接触到对应的action,reducer,dispatch等等,通过派发对应事件类型,然后触发对应逻辑修改,有点像发布订阅,哈哈,在这里,借鉴react当中使用redux的思路,记录vue2当中抽离逻辑代码的技巧。
具体实现
举例就拿最经典的toodList来举例
- .components/ToodList/ToodList.vue
<template> <div> <input type="text" placeholder="请输入关键字" v-model="value" /><button @click="handleAddTood" > 操作按钮 </button> <tood-list-item v-for="item in list" :key="item.id" :item="item" @handleDel="handleDel" ></tood-list-item> </div> </template> <script> import ToodListItem from "./ToodListItem"; export default { components: { ToodListItem, }, props: { list: { type: Array, default() { return []; }, }, }, data() { return { value: "", }; }, methods: { handleDel(item) { this.$emit("handelDel", item); }, handleAddTood() { this.$emit("addTood", this.value); }, }, }; </script>
- .components/ToodList/ToodListItem.vue
<template> <div> <input type="checkbox" v-model="item.complated" /> <span :style="{ textDecoration: item.complated ? 'line-through' : 'none' }" >{{ item.title }}</span > <button @click="handleDel(item)">删除</button> </div> </template> <script> export default { props: { item: { type: Object, default() { return {}; }, }, }, methods: { handleDel(item) { this.$emit("handleDel", item); }, }, }; </script>
.components/ToodList/hook文件下:
- actionTypes.js
//主要定义时间触发的类型常量 export const ACTION_TYPES = { del: "DEL", add: "ADD", };
.components/ToodList/hook文件下:
- actionTypes.js
//派发器,通过action找到对应的事件处理逻辑,然后触发 import { addTood, removeTood } from "./toodReducer"; import { ACTION_TYPES } from "./actionTypes"; //接收参数,vue组件上下文对应 export default function (ctx) { function dispatch(args) { const { type, payLoad } = args; //根据行为,触发reducer中的对应逻辑 switch (type) { case ACTION_TYPES.del: removeTood.bind(ctx)(payLoad); break; case ACTION_TYPES.add: addTood.bind(ctx)(payLoad); break; default: break; } } //返回绑定组件实例的函数 return dispatch.bind(ctx); }
.components/ToodList/hook文件下:
- toodReducer.js
//主要事件处理逻辑文件(对应vue组件中的一个个method方法) //添加一个tood export function addTood(value) { const toodListItme = { title: value, complated: false, id: Date.now(), }; this.list.push(toodListItme); } //删除一个tood export function removeTood(item) { const { id } = item; this.list = this.list.filter((item) => item.id != id); }
- App.vue文件
<template> <div id="app"> <tood-list :list="list" @handelDel="handelDel" @addTood="addTood" ></tood-list> </div> </template> <script> import ToodList from "@/components/ToodList/ToodList.vue"; import dispatch from "./components/ToodList/hook/dispatch"; import { ACTION_TYPES } from "./components/ToodList/hook/actionTypes"; export default { name: "App", components: { ToodList, }, data() { return { list: [ { title: "第一项", complated: false, id: 1, }, { title: "第二项", complated: false, id: 2, }, { title: "第三项", complated: true, id: 3, }, ], }; }, methods: { //逻辑代码全部抽离到外部进行处理,当前组件只需要关注视图即可 handelDel(item) { dispatch(this)({ type: ACTION_TYPES.del, payLoad: item, }); }, addTood(value) { dispatch(this)({ type: ACTION_TYPES.add, payLoad: value, }); }, }, }; </script>
总结
在vue2中在一个组件中写过多代码还是很常见的,不好分离逻辑的地方就在this,因此避免一个文件逻辑过多,可以试试这种方法,在vue3更新后,移除单文件组件对this的过渡依赖,对应的compositionApi已经非常便于我们抽离单文件逻辑代码了。
加载全部内容