最近需要在uniapp上使用openlayer,于是網上查找相關資料貌似renderjs可以實作,貌似fs,three.js,echart,mapbox庫都可以使用renderjs實作,且renderjs可以在app及H5上運作,就順便及記錄下。
renderjs是一個運作在視圖層的js。它比WXS更加強大。它隻支援app-vue和h5。
renderjs的主要作用有2個:
renderjs可以實作邏輯層和視圖層之間的通訊,大幅降低邏輯層和視圖層的通訊損耗,提供高性能視圖互動能力。renderjs運作在視圖層,可以直接操作視圖層的元素。
在視圖層操作dom,運作for web的js庫。uniapp不支援DOM操作(如删除某元素節點)當然H5端除外。非H5端可以渲染後擷取某元素的節點資訊。使用render技術可以對實作對DOM操作和使用某些window庫,如導入jquery,echart。可以實作像開發WebGIS一樣開發移動端GIS,極大降低開發難度。
頁面和renderjs子產品通信
在頁面中監聽變量cy,當cy變化時,調用renderjs子產品中receiveName方法,此時,該方法有這幾個參數,newValue, oldValue, ownerVm, vm,其中newValue是值變化後的值。
renderjs發送資料給頁面
// 點選renderjs層後發送資料到邏輯層
emitData(e, ownerVm) {
ownerVm.callMethod('receiveRenderData', e, this.title)
},
下面是renderjs上使用openlayer大緻步驟:
1.openlayers官網下載下傳openlayer包,位址如https://openlayers.org/download/
2.下載下傳好後,解壓檔案,将ol.js和ol.css拷貝到uniapp項目的static檔案下。
3.在元件引入openlayers,建立視圖成層,不要直接import 引用大型類庫,否則打包會因為檔案過大失敗,推薦通過動态建立 script 方式引用。具體如下
<template>
<view class="content">
<view class="" @click="changen()">
點選{{this.cy}}
</view>
<!--監聽檢視 :cy="cy" :change:cy="ol.receiveName" -->
<view id="olMap" class="olMap" style="height: 500px;" @click="ol.emitData" :cy="cy" :change:cy="ol.receiveName" />
</view>
</template>
<script>
//邏輯層操作
import {
maptree,
mapInfo
} from '@/utils/api/http.js'
import {
baseUrl,
wsUrl
} from '@/utils/api/global.js'
export default {
data() {
return {
cy: '我名字',
num: 0
}
},
methods: {
//改變cy變量的值,當值改變傳遞給renderjs
changen() {
++this.num;
this.cy = this.cy + this.num
},
// 接收renderjs發回的資料
receiveRenderData(val) {
console.log('receiveRenderName', val);
},
}
}
</script>
<script module="ol" lang="renderjs">
//視圖層renderjs操作,注意此層中不能uniapp提供相關接口。
// import '../../static/openlayer/v6.6.1-dist/ol.js'不支援此導入方式否則,打包失敗
export default {
data() {
return {
title: 'Hello'
}
},
mounted() {
if (typeof window.ol === 'function') {
this.initAmap()
} else {
const script = document.createElement('script')
script.src = 'static/ol.js'//可以通過此方式導入jquery,echart庫
script.onload = this.initAmap.bind(this)
document.head.appendChild(script)
}
//可以操作節點
console.log(document.getElementId('olMap'))
},
methods: {
initAmap() {
this.map = new ol.Map({
layers: [
new ol.layer.Image({
source: new ol.source.ImageStatic({
url: 'https://scpic1.chinaz.net/Files/pic/pic9/202108/apic34419_s.jpg',
projection: new ol.proj.Projection({
code: 'EPSG:3857',
extent: [0, 0, 786, 968]
}),
imageExtent: [0, 0, 786, 968]
})
})
// new ol.layer.Tile({
// source: new ol.source.OSM()
// })
],
target: "olMap",
view: new ol.View({
maxzoom: 18,
zoom: 2,
center: [114, 25],
projection: new ol.proj.Projection({
code: 'EPSG:3857',
extent: [0, 0, 786, 968]
})
})
})
},
// 點選renderjs層後發送資料到邏輯層
emitData(e, ownerVm) {
ownerVm.callMethod('receiveRenderData', e, this.title)
},
// 接收邏輯層發送的資料
receiveName(newValue, oldValue, ownerVm, vm) {
console.log('newValue', newValue)
console.log('oldValue', oldValue)
console.log('ownerVm', ownerVm)
console.log('vm', vm)
},
}
}
</script>
<style>
@import url("@/static/ol.css");
.content {
width: 100%;
}
</style>
addPoint() {
this.TagSource = new ol.source.Vector({
wrapX: false
});
let currentPoint = new ol.Feature({
geometry: new ol.geom.Point([0, 0])
});
this.TagSource.addFeature(currentPoint);
this.TagLayer = new ol.layer.Vector({
source: this.TagSource,
zIndex: 99,
style: (feature)=>{
return this.TagStyle(feature, 0)
}
})
this.map.addLayer(this.TagLayer)
},
TagStyle(f, rontation) {
let textname = '測試'
return new ol.style.Style({
image: new ol.style.Icon({
src: '/static/icon/5ren.png',
color: '#409EFF'
}),
text: new ol.style.Text({
text: textname,
offsetY: 14,
fill: new ol.style.Fill({
color: '#fff'
}),
stroke: new ol.style.Stroke({
color: '#000',
width: 3
}),
rotation: rontation
})
})
},
參考:
https://blog.csdn.net/M_Eve/article/details/115497269
https://blog.csdn.net/qq_43171049/article/details/117773952?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-6.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-6.control