/uni-render-logic

uni-app renderjs 跨层调用

Primary LanguageTypeScriptMIT LicenseMIT

uni-app renderjs 跨层调用

基于 uni-app 的 renderjs 以及 Vue 3 的 Composition API,利用 mixin 创建自定义组件,跨层调用浏览器环境下的 DOMBOM,实现 input 文件选择、canvas 生成视频封面、封装 FormData 请求等功能。

安装

# npm
npm install uni-render-logic
# yarn
yarn add uni-render-logic
# pnpm
pnpm install uni-render-logic

示例

参考 ./example 文件夹调用 canvas 生成视频封面

使用

  1. 分别在视图层和逻辑层导入 mixin

    <!-- MyComp.vue -->
    <!-- 视图层 -->
    <script>
      import { renderMixin } from 'uni-render-logic'
    
      export default {
        mixins: [renderMixin]
      }
    </script>
    
    <!-- 逻辑层 -->
    <script module="<moduleName>" lang="renderjs">
      import { logicMixin } from 'uni-render-logic'
    
      export default {
       mixins: [logicMixin],
      }
    </script>
  2. 模板绑定视图层数据、逻辑层模块

    <!-- MyComp.vue -->
    <template>
      <view :jobs="jobs" :change:jobs="<moduleName>.dispatchJob"></view>
    </template>
  3. 视图层、逻辑层示例

    <!-- MyComp.vue -->
    <!-- 视图层 -->
    <script>
      import { renderMixin } from 'uni-render-logic'
    
      export default {
        mixins: [renderMixin],
        data() {
          return {
            ['<key>']: false
          }
        },
        methods: {
          ['<methodName>'](a, b) {
            // 被调用
            console.log('<methodName> called', a, b)
          }
        }
      }
    </script>
    
    <!-- 逻辑层 -->
    <script module="<moduleName>" lang="renderjs">
      import { logicMixin } from 'uni-render-logic'
    
      export default {
      mixins: [logicMixin],
      methods:{
        /**
         * 测试
         *
         * @param args 传递参数
         */
        test(...args){
          // Map 类型,JSON.parse(JSON.stringify(<Map>)) 转换后变成 {}
          // { a: 1, b: [], c: "test", d: false, e: {}, f: {} }
          console.log(args[0])
    
          // ... DOM 操作
          const ele = document.createElement('div')
          ele.innerText = 'hello world'
          document.body.appendChild(ele)
    
          // 触发事件
          this.emitEvent('<eventName>', 1, 2)
    
          // 修改视图层数据
          this.emitData('<key>', true)
    
          // 触发视图层方法
          this.emitMethod('<methodName>', 1, 2)
    
          return new Promise((resolve) => {
            setTimeout(() => {
              resolve(ele.innerText)
            }, 1000)
          })
        },
      }
      }
    </script>
  4. 跨层调用逻辑层方法,监听逻辑层事件

    <!-- 父组件 -->
    <template>
      <!-- MyComp 组件 -->
      <MyComp @['<eventName>']="handleEvent" ref="comp" />
      <button @click="handleTest">测试</button>
    </template>
    <script setup lang="ts">
      import MyComp from '@/components/MyComp.vue'
      const comp = ref<InstanceType<typeof MyComp>>()
    
      /**
       * 处理测试
       */
      const handleTest = async () => {
        // 调用逻辑层 'test' 方法
        // 由于跨层调用是异步的,无论 'test' 方法是否异步,结果均返回 Promise
        const res = await comp.value?.addJob<string>('test', {
          a: 1,
          b: [],
          c: 'test',
          d: false,
          e: {},
          // Map 类型
          f: new Map()
        })
        // 'hello world'
        console.log(res)
      }
    
      /**
       * 处理逻辑层触发事件
       */
      const handleEvent = (a: number, b: number) => {
        // 1 2
        console.log(a, b)
      }
    </script>