如果笔记

如果笔记

做有价值的技术笔记

简化代码系列1:Vue应用解耦登录判断逻辑

Web应用中,很多用户交互操作,比如收藏、关注、提交表单等,都需要在前端判断用户是否已登录,没登录则弹出登录框或跳登录页。如果不对登录判断逻辑进行解耦,那么在所有需要登录的地方都加上登录判断显然是不好的

Web应用中,很多用户交互操作,比如收藏、关注、提交表单等,都需要在前端判断用户是否已登录,没登录则弹出登录框或跳登录页。 如果不对登录判断逻辑进行解耦,那么在所有需要登录的地方都加上登录判断显然是不好的。比如像下面这样: ```javascript methods: { // 支付 pay() { if (User.getId()) { // 登录了 // 调用后端接口支付,此处省略 } else { // 没登录 User.login(user => { if (user) { // 登录成功 this.pay(); // 再次执行pay } }); } }, // 收藏 collect(el) { if (User.getId()) { // 登录了 // 调用后端接口收藏,此处省略 } else { // 没登录 User.login(user => { if (user) { // 登录成功 this.collect(el); // 再次执行collect } }); } } } ``` 可以看到,冗余代码太多了,开发和维护成本都很高。整个项目只有一两处还可以将就,但这是不可能的。所以必须要把登录判断逻辑提出去(解耦),封装到User里。目标是把代码简化成下面这样的: ```javascript methods: { // 支付 pay: User.ensure(function () { // 调用后端接口支付,此处省略 }), // 收藏 collect: User.ensure(function (el) { // 调用后端接口收藏,此处省略 }) } ``` 在业务组件里只写业务代码,是否登录由User自己去判断保证,这才是正解的写码姿势。 那么这个User.ensure怎么写呢?有几点要求: - 实现功能:没登录则弹登录框,已登录或登录成功则回调业务 - 返回的方法里要保留this引用,即当前Vue组件实例 - 支持传参 要求并不是很难,稍微思考下就能写出具体代码。 ```javascript const User = { // 此处省略无关代码 // 获取当前登录用户的id,能获取到表示已登录 getId() { // 此处省略 }, // 弹出登录框 login(callback) { var instance = new (Vue.extend(Login))({ el: document.createElement('div') }); instance.$on('logged', function (user) { // 登录后回调,有user表示登录成功,否则失败 callback(user); }); document.body.appendChild(instance.$el); }, // 确保用户在登录的情况下调用fn,没有登录则先登录再调用 ensure(fn) { return function () { let vm = this, args = arguments; User.getId() ? fn.apply(vm, args) : User.login(function (user) { user && fn.apply(vm, args); }); }; } }; ``` `User.ensure`返回的是一个标准的Vue组件的method。在这个返回函数里,通过arguments可以取得实参,然后用apply调用业务函数fn。 用apply保留this引用和传参,这是基础知识啦。

Vue, JS

前端

hahaboy