通常組件傳參是有兩種情況
- 父子組件進行傳參,這時候通常利用props
- 非父子組件傳參,這時候一般利用vuex
會有一種情況隔代組件傳參,這時候可以利用props一層一層傳遞下去,但是代碼就比較亂了
所以就有了 provide/inject
進行隔代組件傳遞
參考:link
例:components\globe\viewer.vue
<template> <el-row type="flex" class="index"> <el-col> <slot v-if="viewerLoad" name="left"></slot> <div :id="id" class="globe-container" ref="viewer"> <slot v-if="viewerLoad"></slot> </div> <slot v-if="viewerLoad" name="right"></slot> </el-col> </el-row> </template>
可以看到里面有插槽。將屏幕分為左中右三塊。中間很明顯是地球,別名viewer
在調用viewer.vue時,可以這樣調用
Viewer.config
Viewer: { style: { width: '100%',height:"100vh"}, url: 'config/config.json', success: this.handleViewerSuccess, options: { homeButton: true, } },
>>淺談vue中provide和inject用法:https://www.jianshu.com/p/d34a7df4cd6a
>>詳解VueJs中的V-bind指令:https://www.jb51.net/article/139306.htm
>>css3的vw單位,vh單位的講解,以及vw vh的兼容性:https://blog.csdn.net/u011200562/article/details/105192051/
viewer的初始化:

initglobe() { if (window.viewer) return; globe.createMap({ id: this.id, url: this.url, data: this.data, success: this.initAtglobeSuccess, serverURL: this.serverURL, ...this.options }); }, initglobeSuccess(viewer, config) { //開場動畫 viewer.globe.openFlyAnimation(); // 通過事件總線分發 EventBus.$emit('ViewerLoad',viewer,config,this.$refs.viewer) window.viewer = viewer; this.config = config; this.$viewer = this.$refs.viewer // url參數處理 const { x, y, z, heading, pitch, roll } = { x: this.getQueryString('x'), y: this.getQueryString('y'), z: this.getQueryString('z'), heading: this.getQueryString('heading'), pitch: this.getQueryString('pitch'), roll: this.getQueryString('roll') } if(x || y || z || heading || pitch || roll){ const camera = window.viewer.globe.getCameraView() window.viewer.globe.centerAt(Object.assign(camera,{ x, y, z, heading, pitch, roll})); } // Cesium 1.61以后會默認關閉反走樣,對於桌面端而言還是開啟得好, viewer.scene.postProcessStages.fxaa.enabled = true; // 鼠標滾輪放大的步長參數 viewer.scene.screenSpaceCameraController._zoomFactor = 2.0; // IE瀏覽器優化 if (window.navigator.userAgent.toLowerCase().indexOf('msie') >= 0) { viewer.targetFrameRate = 20; // 限制幀率 viewer.requestRenderMode = true; // 取消實時渲染 } // 禁用默認的實體雙擊動作。 viewer.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK); viewer.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK); // 二三維切換不用動畫 if (viewer.sceneModePicker) { viewer.sceneModePicker.viewModel.duration = 0.0; } console.log('>>>>> 地圖創建成功 >>>>'); // 綁定對alert的處理,右鍵彈出信息更美觀。 window.haoutil = window.haoutil || {}; window.haoutil.msg = (msg) => { this.$message.success(msg); }; window.haoutil.alert = (msg) => { this.$message.success(msg); }; this.viewerLoad = true this.success && this.success(viewer, config) },
provide:
provide () { const _this = this; return { get config () { return _this.config; }, get $viewer() { return _this.$viewer; } } },
this表示:該地球所在的vue
this.$viewer表示:該vue頁面上的$viewer
所以,可以看出cesium的初始化是在viewer.vue就進行完的
初始化完成后,就發出一條eventbus指令
EventBus.$on('ViewerLoad',(viewer,config)=>{//監聽事件onLoad。 window.viewer = viewer; this.config = config; })