uniapp使用renderjs

1,205 阅读2分钟

前言

在使用uniapp项目打包APP时发现登录的国密sm算法无法使用,在h5端正常使用。原来时sm2算法中使用了window上的方法,导致APP端报错。经过调查、对比采用了renderjs技术进行了修复。修复过程也遇到了很多坑,特此记录一下,希望能够帮助到有需要的小伙伴。

renderjs介绍

uni-app 官方介绍

个人理解

renderjs是一个运行在视图层的js,向APP端打的一个补丁,为了解决移动端无法使用window上的方法和属性, 关于性能(大幅降低逻辑层和视图层的通讯损耗,提供高性能视图交互能力)上的提升,属于吹嘘无关紧要。 仅支持 h5和app 不支持小程序端。

renderjs应用场景

主要时解决一些特殊场景或者一些类库在APP端无法使用。 例如:在app端使用了canvas、document等,某些使用了window上属性和方法的类库:国密算法、echarts等。

renderjs的之间的通讯

<template>
  <view>
    <button @tap="test.handleClick">点击</button>
  </view>
</template>

<script>
  export default {
    // 原先的script,这里被称为service层
  }
</script>

<script lang="renderjs" module="test">
  export default {
    data() {
      return {}
    },
    methods: {
      handleClick(event, ownerInstance) {
        // event是事件对象
        // ownerInstance和this.$ownerInstance是一样的,用来调用service层的方法
        console.log('点击了按钮')
      }
    },
    created() {
      console.log('renderjs初始化完毕')
    }
  }
</script>

vue调renderjs

<template>
  <view>
    // prop是个名字,可以随意改,注意:change:[name]这两个名字需要相同就行了
    <text :prop="options" :change:prop="test.onChange">无内容</text>
    <button @tap="changeOptionFn">点击修改options</button>
  </view>
</template>

<script>
  export default {
    data() {
      return {
        options: {
          // 这里存放准备传递给renderjs的数据
          token: null,
          num: 1
        }
      }
    },
    methods: {
      changeOptionFn() {
        this.options = {
          // 这个地方我用时间戳来修改token,用于触发change,实际需要传递的数据是num
          token: Date.now(),
          num: Math.random()
        }
      }
    }
  }
</script>

<script lang="renderjs" module="test">
  export default {
    methods: {
      onChange(newValue, oldValue, ownerInstance, instance) {
        console.log('service层中的options发生变化')
        console.log('新值', newValue)
        console.log('旧值', oldValue)
        // ownerInstance和this.$ownerInstance一样,可用来向service层通信
        // instance和ownerInstance的区别是:
        // instance.$el指向的是触发事件的那个节点;ownerInstance.$el指向当前vue文件中的根节点;
        // instance的作用目前尚不明确,官方没有给出用法
      }
    }
  }
</script>

renderjs调vue


<template>
  <view>
    <button @tap="test.onClick">点击</button>
  </view>
</template>

<script>
  export default {
    methods: {
      acceptDataFromRenderjs(data) {
        console.log('从renderjs中接收到的数据', data)
      }
    }
  }
</script>

<script lang="renderjs" module="test">
  export default {
    data() {
      return {}
    },
    methods: {
      onClick(event, ownerInstance) {
        ownerInstance.callMethod('acceptDataFromRenderjs', { content: '测试文字' })
        // 或this.$ownerInstance.callMethod('acceptDataFromRenderjs', { content: '测试文字' })
        // 需要注意的是:只有通过在template中用户手动操作触发renderjs的方法参数是这两个:event, ownerInstance;
        // 通过其他方法触发的函数参数不一样,后面会说
      }
    }
  }
</script>

renderjs的坑

vue2和vue3的使用有所差异, 并且vue3写法一些生命周期并不会走,官方文档写的不清不楚,现在不清楚是否有改变、修复 。我使用的是时候 是一点一点取测试。

总结:

坑很多,慎入。