問題: 一個畫圖元件是用react做的,而頁面是用vue來寫的,怎麼掛載,vue應用裡的資料怎麼傳遞到react裡面呢。
react繪圖功能和vue頁面被分別打包成了兩個包。
先來看下效果
先來了解下 生命鉤子,需要在vue生命鉤子的mounted裡面呼叫react方法來繪製圖形,可以在react程式碼裡面暴露一個方法,
//react app
import App from './app/kon/index'
window.loadCanvas = function(param) {
ReactDOM.render(<App
projectId={param.projectId} //繪圖元件需要它去請求api
isEdit={param.type == 'edit'} //圖形有兩種狀態,檢視和編輯狀態
router={param.router} //在內部繪圖完成可能會做一些vue-router層面的跳轉,所以傳遞
/>, document.getElementById(param.id))
}
複製程式碼
在vue裡面的呼叫
mounted() {
// 在react app裡面暴露該方法
window.loadCanvas({
type: 'edit',
id: 'reactApp',
projectId: this.$route.query.projectId
})
}
即vue掛載完成後初始化react元件。
複製程式碼
資料通訊 vue 傳遞到react 先實現一個全域性的訂閱釋出(也可以直接使用backbone裡面的事件模組Event)
utils={
Event:(function(){
var clientList={},listen,trigger,remove;
listen=function(key,fn){
clientList[key]=clientList[key] ||[];
clientList[key].push(fn);
};
trigger=function(){
var args=[].slice.call(arguments),
key=args.shift(),
fns=clientList[key];
// 修復bug 不是&&的關係 是或的關係
if(!fns || !fns.length){
return;
}
for(var i =0,len=fns.length;i<len;i++){
fns[i].apply(this,args);
}
};
remove=function(key,fn){
clientList[key]=[];
// fns=[];
return;
if(fns){
for(var i=0,len=fns.length;i<len;i++){
if(fns[i]){
fns.splice(i,1);
}
}
}
};
return {
trigger:trigger,
listen:listen,
remove:remove,
on:listen
}
})(),
}
複製程式碼
資料是從vue傳遞到react,所以需要在react裡面訂閱,在vue裡面觸發 先再react繪圖頂級元件裡面訂閱
componentWillMount() {
// 檢視模式,從頁面獲取事件初始化
//防止trigger多次
utils.Event.remove('VMDATA')
//第一次繪圖初始化
utils.Event.listen('VMDATA', param => {
this.initData(param)
})
utils.Event.remove('VMUPDATE')
//監聽vue裡點選切換樓棟時資料變化,此時需要重繪
utils.Event.listen('VMUPDATE', param=>{
this.updateData(param)
})
}
複製程式碼
然後在vue裡面
先獲取資料,再繪製,繪製完後再傳遞資料
let canvasInit = _.after(2, () => {
utils.hideLoading()
this.$nextTick(() => {
window.loadCanvas({
type: 'show',
projectId: this.$route.query.projectId,
id: 'js_canvas',
router: this.$router
})
this.hadShowCanvas = true
utils.Event.trigger('VMDATA', canvasData)
this._canvasData = canvasData
})
})
複製程式碼
當右側點選按鈕變化時
先進行資料過濾處理,再繪製
utils.Event.trigger('VMDATA', canvasDataFilter)
複製程式碼
至此,整個從vue到react繪圖搭建好了。