缘起
今天接到一个新的需求,就是在我们研发的产品A登录后,需要同步登录我司的其他产品B,考虑到产品A的登录方式比较多(包括: 微信oauth登录、用户密码登录、jwtcode登录等),但是后来发现登录成功后相关组件都会执行 this.$store.dispatch("updateUserToken")
的操作。
由于本人比较懒,如果改登录相关的组件,则改动的地方比较多。考虑到登录都会触发 commit 到 store 的 mutation, 想到store是否有订阅相关的逻辑, 于是查看Vuex的资料, 发现 【store插件系统】 能订阅 commit
到 store
的 mutation
那么我可以考虑写个store插件, 订阅 mutation 的类型为 updateUserToken
时, 然后调用登录产品B的 业务
这样我只写个plugin
就可以了, 不用改动登录相关的组件,降低了业务的耦合, 而且让我改动最小。
性空
plugin的官方文档如下:
Vuex 的 store 接受 plugins 选项,这个选项暴露出每次 mutation 的钩子。Vuex 插件就是一个函数,它接收 store 作为唯一参数:
const myPlugin = store => {
// 当 store 初始化后调用
store.subscribe((mutation, state) => {
// 每次 mutation 之后调用
// mutation 的格式为 { type, payload }
})
}
然后像这样使用:
const store = new Vuex.Store({
// ...
plugins: [myPlugin]
})
具体实现
我在 store 目录下, 新建个 plugins
插件目录,在里面新建个 thirdParty.js
文件, 下附store目录结构:
store
│ index.js
│
├─modules
│ moduleA.js
│ moduleB.js
│
└─plugins
thirdParty.js
把第三方登录写在 plugins/thirdParty.js
里面:
import axios from 'axios';
// 第三方登录类
class thirdPartyLogin {
constructor({getters},userToken) {
this.getters = getters;
this.userToken = userToken;
}
async init() {
const thirdLoginUrl = `${thirdPartyHost}/login-with-token`;
const params = {userToken: this.userToken};
await axios.get(thirdLoginUrl, {params, withCredentials: true}).then(({status, data}) => {
console.log(status, data);
});
}
}
// 第三方的插件
export default function thirdParty (store) {
store.subscribe(({type, payload}) => {
// 如果不是执行 更新用户 userToken操作, 则终止
if(type != 'updateUserToken' || !payload) return;
const thirdPartyLoginObj = new thirdPartyLogin(store, payload);
thirdPartyLoginObj.init();
});
}
然后在 store 的 index.js 里面引用即可:
import thirdParty from './plugins/thirdParty.js';
Vue.use(Vuex)
const store = new Vuex.Store({
plugins: [thirdParty],
state: {
userToken: null,
},
……
mutations: {
updateUserToken(state, userToken) {
state.userToken = userToken;
},
……
},
actions: {
updateUserToken({commit}, userToken}) {
commit('updateUserToken', userToken);
},
……
}
……
……
})
如此, thirdParty 插件, 就可以订阅 mutation 的 updateUserToken 事件了。
而且不改动原有的业务逻辑代码, 耦合度降到最低。
网友评论