業務背景是,在jq的前端專案中加入Vue作為元件。
原本的登入功能是每個頁面加一個登入彈窗(手機號+驗證碼驗證登入),然後發ajax請求到後端,登入成功後再進行一些操作。
但隨著需要登入的頁面的增多,多個頁面都需要新增相同的html,js,css以及前端登入邏輯,所以在原先的專案中新增了vue,將重複的新增的程式碼加入到了vue檔案中,然後通過$mount方法將vue物件掛載到某個ID的dom節點上。這樣,就讓所有的頁面呼叫統一的登入彈窗,執行相同的js登入程式碼了,並且將登入邏輯完全與頁面上的業務邏輯解耦了。
但後來需求又有了新的變化,原本loginForm 元件只是一個用來登入的彈窗,但有一個頁面PM同學卻希望不用執行驗證登入邏輯,只要輸入手機號,就可以直接直接執行後端邏輯。
好吧。。。
我找了 Vue.set
方法解決了這個問題:
通過Vue.set方法向vue物件中的data設定一個響應式物件,使該物件能夠在初始化階段接收控制引數 Vue.set(form.$data, `setData`, data);
在不同的頁面向頁面傳輸不同的引數來控制彈窗顯示,以及後續是否執行ajax請求邏輯。
呼叫登入元件的js
var callBack = function () {//加入callback方法作為回撥函式,將業務程式碼與登入邏輯解耦
...
}
var LoginComponent = require(`loginForm.js`);//獲得登入元件
var setData = {
`hideLogin`: true,
`callBack`: callBack
};//自定義資料
LoginComponent.loadLoginForm(setData);//初始化登入元件
loginForm.js
var Vue = require(`vue`);
var loginForm=require(`loginForm.vue`); //引入一個附帶模板的vue檔案
var login = exports;
var form;
/**
* 初始化登入元件
*/
login.loadLoginForm = function (data) {
if(form){
return;
}
form = newVue(loginForm); //new一個vue物件
if (typeof(data) !== "undefined") {
//通過Vue.set方法對要顯示的物件進行控制,使該物件能夠在初始化階段接收控制引數
Vue.set(form.$data, `setData`, data);//向vue物件中的data設定一個響應式物件,繞過了限制
}
form.$mount(`#loginForm`);//將物件繫結掛載到某個id上
};
html<div id="loginForm"></div>
loginForm.vue
<template>
/** 登入彈窗 **/
<div>
<input v-if="show" />
<input v-if="!setData.hideLogin" />
...
</div>
</template>
<script>
module.exports = {
data: function () {
return {
setData: {}
}
},
methods: {
getA: function () {
...
if (true) {
this.setData.callBack();// 執行回撥函式
}
},
setB: function () {
...
}
},
created: function () {
this.setB();
},
updated: function () {
this.getA();
}
</script>