跳到主要内容

自定义能力示例

微搭作为一个跨端的应用开发平台,并没有提供诸如 DOM API 这样的端底层接口,但在一些扩展场景在微搭平台能力不满足的时候我们仍然需要使用这些能力。

一般来说可以在页面或者应用的生命周期中进行平台相关原生代码编写,这里举例来说如何在微搭中进行 web 平台上进行一些原生代码的编写。

更多实践实例可参考:https://cloud.tencent.com/document/product/1301/83129

全局反馈按钮 (WEB)

案例诉求:希望提供一个全局级别的反馈链接。微搭中当前缺乏相关实现,但利用生命周期钩子很容易实现该特性。

实现思路:

  1. 在全局 common handler 里新建 反馈 功能方法 feedback。代码如下:
export function initFeadback() {
if(!document.getElementById('feedback')){
const feedbackElement = document.createElement('div');

// 实现 feedback 样式
const feedbackTemplate = `
<div id='feedback' draggable="true">
<style>
#feedback {
position: absolute;
right: 8px;
bottom: 20px;
width: 48px;
height: 48px;
line-height: 48px;
font-size: 14px;
border-radius: 50%;
text-align: center;
cursor: pointer;
opacity: 0.3;

color: white;
background-color: grey;
transition: opacity 0.5s;
}
#feedback:hover{
opacity: 1;
}
</style>

反馈
</div>
`;

feedbackElement.innerHTML = feedbackTemplate;

feedbackElement.addEventListener('click', (e) => {
// TODO 实现反馈能力
window.open('https://wj.qq.com/');
});

document.body.appendChild(feedbackElement);
}
}
  1. 全局生命周期(lifecycle)中调用 feedback 的初始化方法。代码如下:
export default {
onAppLaunch(launchOpts) {
$app.common.feedback.initFeadback();
},
}

前端处理 excel(WEB)

案例诉求:在前端页面上导入一个 excel 文件,解析其中的内容并将其展示在一个数据表格中。

实现思路:

  1. 在微搭的应用开发设置引入 excel 文件处理工具 xlsx的CDN js 地址如: https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.18.5/xlsx.full.min.js

  2. 实现 excel 文件的处理逻辑:页面内添加一个 excelHandler 的 javascript handler 自定义方法。代码如下:

export default async function({ event }) {
console.log(event.detail);
// 获取文件链接
const res = await $w.cloud.getTempFileURL(event.detail.value);
console.log(res);
const dataBuffer = await (await fetch(res[event.detail.value[0]])).arrayBuffer();
// 使用 xlsx.js 读取 excel 文件内容
const workbook = XLSX.read(dataBuffer);
console.log(workbook);
const { SheetNames, Sheets } = workbook;
const records = parseSheet(Sheets[SheetNames[0]]); // 处理第一个 sheet
console.log(records);
return records
}

// 将 excel 内容转成数组
function parseSheet(sheetData = {}, start = 'A0') {
const titleInfo = parseCellIndex(start);

let records = Object.keys(sheetData).filter(key => {
const index = parseCellIndex(key)
return /^([a-zA-Z]+)(\d+)$/.test(key) && index[1] && index[1] > titleInfo[1];
}).reduce((s, key) => {
const index = parseCellIndex(key);
if(index[1] === titleInfo[1] + 1) {
s.push([sheetData[key].w])
}else {
s[index[0]].push(sheetData[key].w);
}
return s;
}, []).reduce((s, row, i) => {
row.forEach((x, j) => {
if(j) { // 非 title
s[j-1] = s[j-1] || {}
s[j-1][row[0]] = x;
}
})
return s;
}, []);

return records
}

function parseCellIndex(key = '') {
const matches = key.match(/^([a-zA-Z]+)(\d+)$/);
return [matches?.[1] && columnToNumber(matches[1]), matches?.[2] && Number(matches[2])];
}

// 将 A,B,C... 转成 0,1,2...
function columnToNumber(column) {
let result = 0;
for (let i = 0; i < column.length; i++) {
const charCode = column.charCodeAt(i) - 64;
result = result * 26 + charCode;
}
return result - 1;
}
  1. 页面中添加一个文件上传组件以及一个数据表格组件,以及一个数组的中转页面变量 records。表格数据源选择表达式,表达式值为中转变量 $w.page.dataset.state.records,并且开启分页器和动态分页。

  2. 最后开始配置事件逻辑:

    • 文件上传成功事件里添加对自定义代码 excelHandler 的调用
    • 在调用成功分支里添加给 records 变量赋值节点,入参为 event.detail。表示将上传处理好的 excel 表格转成的数组赋值给 records 变量

这里核心逻辑即已完成,在表格获取数据渲染后可以在表格属性那里更新调整下展示的列内容已达到想要的效果。