最近系统的学了一下vue,在这里随便写下一点学习心得,“中心思维”是我自己总结的土方法,有助于自己对技术的理解,且看。
先说结论
“中心思维”顾名思义,以一个模块为中心,所有信息传递由中心模块完成。这是一种思维方式,对于初学者有利于在写代码时理清逻辑。
使用场景1
学习vue之前,我在公司做过原生微信小程序开发,二者代码风格类似。某次做了一个砍价功能,受限于后端接口支持,只能由前端用“增, 改,查”通用接口凑成一个砍价程序。后端能用代码写的每一层判断逻辑,在前端只能以发请求的方式去拼凑。于是不可避免的有了以下屎山代码:
// 一点伪代码
onLoad: async function () {
const res1 = await fn1(phone);
if (注册了?) {
// 获取砍价信息
const res2 = await fn2(res1);
if (参加了砍价?) {
// 点击拉好友
this.setData('isKj', true);
} else {
// 点击参加
this.setData('isKj', false);
const res3 = await fn2(res2);
this.setData('isKj', res3.data);
this.fn4(res3.data);
}
} else {
// 拦截操作,显示注册按钮
}
},
async handleClick() {
const res5 = await this.fn5(this.isKj);
this.setData('data1', res5.xx);
this.fn6('res5.xx');
}
// 后面还有几百行代码.....
上面的代码看着是否头疼?但是接口支持不好,这样的屎山无可避免。有时候写着写着自己都不知道那个数据是哪个数据,啥时候该this.setData(),啥时候该用this.data.xx, 啥时候该用上一个函数返回的res?
“中心思维”
只要是要放在this.data中的数据,皆以this.data的数据为准:
只要注意调用函数的顺序,一切都如船到桥头。
async onLoad() {
await this.fn1();
await this.fn2();
if(this.data.d2.tr) {
// 一些操作
await this.fn3();
}
if(this.data.d3) {
...
}
},
async fn1() {
const res1 = await axios.get(url);
this.setData('d1', res1.xxx);
},
async fn2() {
const res2 = await axios.get(url, this.data.d1);
this.setData('d2', res2.xxx);
}
async fn3() {
const res3 = await axios.get(url, this.data.d2);
this.setData('d3', res3.xxx);
}
// ...500行代码
所有关键数据第一时间存到this.data,所有需要使用数据的地方一律用this.data.xx,不要用上一个函数的res,不要传参数,不要return,思路一下清楚了很多。小程序如此,vue亦然。
“中心思维”并不能消除屎山,但能让屎山稍微好看一点,让写屎山的人逻辑清除一些。
使用场景2
组件通信的一种方式——路由
路由是中心,一切变化提交中心,一切行为监听中心
上图中,List、Pager、Toc很可能在组件树上不是同一级组件,甚至可能不在一个父组件下,所有信息通过路由信息传递。目录Toc组件点击后,改变路由,List和Pager组件分别通过computed和watch监听路由的变化,做出对应的行为。
所有数据的改变第一时间去路由信息中心找答案,组件的行为由路由的变化引起,一切以路由为中心。
同理,使用vuex和props也可以根据这种思维设计代码
使用场景3
组件通信的一种方式——事件总线
以事件总线为中心,组件2、3监听某一个事件event1,并绑定处理函数handlerN。组件1需要的时候触发事件event1,监听到事件被触发,组件2、3的handlerN相继执行。
思维上以事件总线为中心,不用再去费心思考组件之间如何传递信息,一切皆由事件总线决定,监听就完事儿了,数据可通过handler的参数传递。
以上便是我自己的方法论,不太专业,土方法适用于自己。