uni-render-logic
Version:
uni-app renderjs 逻辑层和视图层跨层调用 mixin
167 lines (137 loc) • 4.04 kB
Markdown
## uni-app renderjs 跨层调用
基于 uni-app 的 [renderjs](https://uniapp.dcloud.net.cn/tutorial/renderjs.html#renderjs) 以及 Vue 3 的 `Composition API`,利用 `mixin` 创建自定义组件,跨层调用浏览器环境下的 `DOM` 和 `BOM`,实现 input 文件选择、canvas 生成视频封面、封装 FormData 请求等功能。
### 安装
```bash
# npm
npm install uni-render-logic
```
```bash
# yarn
yarn add uni-render-logic
```
```bash
# pnpm
pnpm install uni-render-logic
```
### 示例
参考 `./example` 文件夹调用 `canvas` 生成视频封面
### 使用
1. 分别在视图层和逻辑层导入 `mixin`
```html
<!-- 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. 模板绑定视图层数据、逻辑层模块
```html
<!-- MyComp.vue -->
<template>
<view :jobs="jobs" :change:jobs="<moduleName>.dispatchJob"></view>
</template>
```
3. 视图层、逻辑层示例
```html
<!-- 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. 跨层调用逻辑层方法,监听逻辑层事件
```html
<!-- 父组件 -->
<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>
```