问题: 一个画图组件是用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绘图搭建好了。

Logo

前往低代码交流专区

更多推荐