最近需要在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是值变化后的值。
<view id="olMap" class="olMap" @click="ol.emitData" style="height: 500px;" :cy="cy" :change:cy="ol.receiveName" />
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.youkuaiyun.com/M_Eve/article/details/115497269
https://blog.youkuaiyun.com/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

本文介绍了如何在UniApp中结合RenderJS来使用OpenLayers库,详细阐述了从下载OpenLayers资源到在Vue组件中动态引入,并通过RenderJS实现在非H5端操作DOM及通讯的过程,展示了在视图层和逻辑层间的数据交换方法,以及创建地图实例的步骤。
1443





