5-3 uniapp 里使用 echarts、threejs、地图插件等
renderjs 介绍
renderjs
是一个运行在视图层的 js
。它比 WXS
更加强大,性能堪比 flutter
。
renderjs
的主要作用有2个:
- 大幅降低逻辑层和视图层的通讯损耗,提供高性能视图交互能力
- 在视图层操作
dom
,运行for web
的js
库,包括但不限于:echarts
,threejs
,d3js
,百度地图,高德地图,腾讯地图等
平台差异
App | H5 |
---|---|
√(2.5.5+,仅支持vue) | √ |
使用方式
设置 script
节点的 lang
为 renderjs
<script module="test" lang="renderjs">
export default {
mounted() {
// ...
},
methods: {
// ...
}
}
</script>
类库引用方式
-
支持
npm
、require
、import
、动态创建script
方式。 -
不要直接引用大型类库,推荐通过动态创建
script
方式引用。 -
APP 端视图层的页面引用资源的路径相对于根目录计算,例如:
./static/test.js
。实际情况是只能引用static
目录里的资源。
生命周期
H5
:所有UNI
框架的生命周期都可使用APP
:仅可使用VUE
组件生命周期- 视图层与逻辑层可以重复定义生命周期,都会执行。
- 可以使用
vue
组件的生命周期不可以使用App
、Page
的生命周期
组件生命周期
beforeCreate
created
beforeMount
mounted
beforeUpdate
updated
beforeDestroy
destroyed
App
生命周期
onLaunch
onShow
onHide
onError
onUniNViewMessage
onUnhandledRejection
onPageNotFound
onThemeChange
Page
生命周期
onInit
onLoad
onShow
onReady
onHide
onUnload
onResize
onPullDownRefresh
onReachBottom
onTabItemTap
onShareAppMessage
onPageScroll
onNavigationBarButtonTap
onBackPress
onNavigationBarSearchInputChanged
onNavigationBarSearchInputConfirmed
onNavigationBarSearchInputClicked
onShareTimeline
onAddToFavorites
注意事项
- 目前仅支持内联使用。
- 观测更新的数据在视图层可以直接访问到。
APP
端可以使用dom
、bom API
,不可直接访问逻辑层数据,不可以使用uni
相关接口(如:uni.request
)H5
端逻辑层和视图层实际运行在同一个环境中,相当于使用mixin
方式,可以直接访问逻辑层数据。
通信
页面与renderjs模块通信逻辑层与视图层通信
<!-- 监听变量 operation 的变化,operation 发生改变时,调用 test 模块的 loadOperation 方法 -->
<view :operation="operation" :change:operation="test.loadOperation">
</view>
当 operation
变化时, renderjs
中 loadOperation
被调用
loadOperation(newValue, oldValue, ownerInstance, instance) {
// 数据变更
this.clicked = newValue;
// 向uni-app页面组件发送信息
this.sendMsg();
}
renderjs 发送数据给页面 视图层发送数据给逻辑层
在 renderjs
中调用页面的 reciveMessage
方法
sendMsg() {
// 向页面传参
this.$ownerInstance.callMethod('reciveMessage', ++this.count)
},
页面中定义 reciveMessage
方法
/**
* 接收 renderjs 传过来的数据
* @param {Object} data
*/
reciveMessage: function(data) {
this.total = data;
}
代码示例
echarts
html
部分
<template>
<view class="content">
<view @click="echarts.onClick" :prop="optionData" :moduleParamProp="moduleParam"
:change:moduleParamProp="echarts.moduleParamUp" :change:prop="echarts.updateEcharts" :id="moduleParam.id"
class="echarts"></view>
<button @click="changeOption">更新数据</button>
</view>
</template>
javascript
部分
export default {
props: {
moduleParam: {
type: Object,
default: () => {
id: "myCharts";
width: "100%";
height: "300rpx"
}
},
optionData: {
type: Object,
default: () => {}
}
},
methods: {
changeOption() {
// 父组件刷新数据
this.$emit("changeOption")
},
onViewClick(options) {
this.$emit("getClickData", options)
}
}
}
renderjs
部分
let myChart
export default {
data() {
return {
clickData: null
}
},
mounted() {
if (typeof window.echarts === 'object') {
this.initEcharts()
} else {
// 动态引入较大类库避免影响页面展示
const script = document.createElement('script')
// view 层的页面运行在 www 根目录,其相对路径相对于 www 计算
script.src = 'static/echarts.min.js'
script.onload = this.initEcharts
document.head.appendChild(script)
}
},
methods: {
initEcharts() {
myChart = echarts.init(document.getElementById(this.moduleParam.id))
// 观测更新的数据在 view 层可以直接访问到
myChart.setOption(this.optionData)
// 点击传参
myChart.on('click', params => {
this.clickData = params
})
},
updateEcharts(newValue, oldValue, ownerInstance, instance) {
// 监听 service 层数据变更
myChart = echarts.init(document.getElementById(this.moduleParam.id))
myChart.setOption(newValue)
},
moduleParamUp(newvalue, oldvalue) {},
onClick(event, ownerInstance) {
ownerInstance.callMethod('onViewClick', {
value: this.clickData.value,
name: this.clickData.name,
dataIndex: this.clickData.dataIndex,
seriesName: this.clickData.seriesName
})
}
}
}
threejs
支持 npm
、 require
、 import
、动态创建 script
方式。
使用方法和一般的项目使用一样。
这里只介绍下载方式
下载 threejs
html
部分
<template>
<view id="three" class="content"></view>
</template>
renderjs
部分
import THREELib from 'static/three-js/index.js';
const THREE = THREELib(['OrbitControls'])
export default {
mounted() {
this.doThree()
},
methods: {
doThree() {
// OrbitControls(THREE)
console.log(THREE)
/**
* 创建场景对象Scene
*/
var scene = new THREE.Scene();
/**
* 创建网格模型
*/
var geometry = new THREE.BoxGeometry(50, 50, 50)
var material = new THREE.MeshPhongMaterial({
color: '#0000FF',
specular: '#4488ee',
shininess: 12
})
var mesh = new THREE.Mesh(geometry, material);
scene.add(mesh)
/**
* 光源设置
*/
//点光源
var point = new THREE.PointLight('#ffffff')
point.position.set(400, 200, 300);
scene.add(point)
//环境光
var ambient = new THREE.AmbientLight('#EEEE11')
scene.add(ambient)
var axisHelper = new THREE.AxisHelper(250);
scene.add(axisHelper);
/**
* 相机设置
*/
var width = window.innerWidth; //窗口宽度
var height = window.innerHeight; //窗口高度
var k = width / height; //窗口宽高比
var s = 200; //三维场景显示范围控制系数,系数越大,显示的范围越大
//创建相机对象
var camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);
camera.position.set(200, 300, 200); //设置相机位置
camera.lookAt(scene.position); //设置相机方向(指向的场景对象)
/**
* 创建渲染器对象
*/
var renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height); //设置渲染区域尺寸
renderer.setClearColor(0xb9d3ff, 1); //设置背景颜色
console.log(document.getElementById("three"))
document.getElementById("three").appendChild(renderer.domElement);
//执行渲染操作 指定场景、相机作为参数
function render() {
renderer.render(scene, camera)
}
render();
var controls = new THREE.OrbitControls(camera, renderer.domElement)
controls.addEventListener('change', render)
}
}
}