原生编程扩展
React 页面中的原生代码扩展
在页面中使用 JSX 进行动态渲染
示例场景,页面局部用 JSX 来进行动态渲染
在页面上定义一个 tableRender 函数,代码如下:
import { Table } from "antd";
//渲染表格
let tableRender = () => {
let columns = getColumns();
//渲染字段
return (
<>
<Table
key={new Date().getTime()}
class={"tableBox"}
columns={columns}
dataSource={state.treeData}
rowKey="fid"
pagination={false}
bordered={true}
rowHoverable={false}
/>
</>
);
}
在页面的 .w 源码中嵌入 tableRender,代码如下:
{$page.tableRender?.()}
预览即可看到显示效果
在页面中引用 React 原生组件
示例场景,将一个 React 组件引用到 .w 中,并且跟页面上的数据组件集成
进入代码页,在 UI2/pcx 目录下,创建一个 react_demo1.react.js 文件,内容如下:
import React, { useState, forwardRef, useImperativeHandle } from 'react';
import { Select, Space, Input } from 'antd';
const Demo1 = forwardRef((props, ref) => {
let [selectValue, setSelectValue] = useState("test");
/* 通过 ref 将内部属性暴露给外部 */
useImperativeHandle(ref, () => ({
selectValue
}));
/* 通过 props 接收来自页面组件源码传入的属性 */
let data = props.data;
let field = props.field;
return <div>
<Space wrap>
{/* 绑定数据组件当前行的选择器 */}
<Select value={data.current[field]} onChange={(value) => { data.current[field] = value }} options={[{ value: 'red' }, { value: 'green' }, { value: 'blue' }]} />
{/* 选项数据来自数据组件的选择器 */}
<Select value={selectValue} onChange={(value) => { setSelectValue(value) }} options={data.value.map(row => ({ value: row[field] }))} />
{/* 绑定数据组件当前行的输入框 */}
<Input value={data.current[field]} onChange={(e) => { data.current[field] = e.target.value }} />
</Space>
{/* 基于数据组件渲染一个列表,输入框焦点进入(onFocus)的时候设置当前行 */}
<ul>
{
data.value.map(row => <li>
<Input value={row[field]} onChange={(e) => { row[field] = e.target.value }} onFocus={() => { data.to(row) }} />
</li>)
}
</ul>
</div>
});
export default Demo1;
通过 common.js 引入 React 原生组件 进入代码页,在 UI2/pcx 目录下,创建或打开 common.js,加入以下代码:
/* 引入 React 原生组件 */
import Demo1 from "$UI/pcx/react_demo1.react";
export default {
Demo1
};
在 .w 页面源码中嵌入上面引入的 React 原生组件 注意:productsData 和 productName 改成自己页面上的数据组件和字段
<WxCommon.Demo1 data="{productsData}" field="productName" />
预览即可看到显示效果
通过 ref 获取组件实例
示例场景,在上一个示例基础上,在页面的按钮事件代码中,获取 Demo1 组件实例,并访问组件内部数据
在 .w 页面源码中,给 Demo1 组件增加 ref 属性,代码如下:
<WxCommon.Demo1 data="{productsData}" field="productName" ref="demo1"/>
页面上拖一个按钮组件,点击事件选择写代码方式,代码如下:
onButton0Click = (event) => {
/* 获取组件实例 */
let demo1 = this.comp("demo1");
console.log(demo1.selectValue);
}
预览后,点击按钮,在开发者工具的控制台可以看到输出组件的内部数据
Vue 页面中的原生代码扩展
在页面中使用 JSX 进行动态渲染
示例一:在 w 文件中引入 js 中声明的渲染方法
在页面 js 文件中定义一个 uploadRender 函数,返回要显示的 vue 组件或 html 元素,代码如下:
import { message, Upload as Upload2, Button } from "ant-design-vue";
let uploadRender=()=>{
const props = {
name: 'files',
accept: ".jpg, .jpeg, .png",
multiple: true,
action: $page.getServiceUrl("/main/file/upload"),
headers: {
authorization: 'authorization-text',
Accept: 'application/json'
},
data: {
pid: "123"
},
onChange(info) {
$page.fileList = info.fileList;
if (info.file.status === 'done') {
message.info("上传成功");
} else if (info.file.status === 'error') {
message.error("上传出错!");
}
}
};
return <>
<Upload2 maxCount={2} listType="text" {...props}>
<Button icon={<UploadOutlined />} id="upload" >上传</Button>
</Upload2>
</>
}
在页面的 .w 源码中嵌入 uploadRender 方法,代码如下:
{uploadRender()}
预览即可看到显示效果
示例二:在 w 文件中引入 js 中声明的组件
在页面的 js 文件中定义一个 MyRender 函数,接收属性 props 和上下文 context 两个参数,返回 vue 组件或 html 元素,代码如下:
import { reactive, ref, watch } from "vue";
import { usePage, useData } from "vue_addon/core";
let $page = usePage();
/* 引入 ant-design-vue 的 Input,并重命名为 VueInput */
import { Input as VueInput } from 'ant-design-vue';
let MyRender = (props, context) => {
/* 通过 props 接收来自页面组件源码传入的属性 */
let data = props.data;
let field = props.field;
/* 返回自定义渲染 */
return <div>
{/* data.current 对应数据组件的当前行 */}
{/* HTML 原生 input 的两种写法,在 JSX 中推荐用 vModel 驼峰的写法 */}
<input v-model={data.current[field]} />
<input vModel={data.current[field]} />
{/* ant-design-vue 的 Input 的三种写法,在 JSX 中推荐用 vModel 驼峰的写法 */}
<VueInput v-model:value={data.current[field]} />
<VueInput v-model={[data.current[field], "value"]} />
<VueInput vModel={[data.current[field], "value"]} />
{/* 通过 data.value.map 渲染多行,输入框焦点进入(onFocus)的时候设置数据当前行 */}
<ul>
{
data.value.map(row => <li>
<input vModel={row[field]} onFocus={() => { data.to(row) }} />
<VueInput vModel={[row[field], "value"]} onFocus={() => { data.to(row) }} />
</li>)
}
</ul>
{/* context.slots.default?.() 接收来自页面组件源码中的插槽 */}
{context.slots.default?.()}
</div>;
}
在页面的 .w 源码中嵌入 MyRender,代码如下: 注意:productsData 和 productName 改成自己页面上的数据组件和字段
<MyRender data="{productsData}" field="productName">
<div>测试插槽</div>
<!-- 插槽里放一个可视化组件 -->
<antdv:Input bind:ref="productsData.current.productName"/>
</MyRender>
预览即可看到显示效果
在页面中引用 Vue 原生组件
示例场景,将一个 Vue 组件引用到 .w 中,并且跟页面上的数据组件集成
进入代码页,在 UI2/pcx 目录下,创建一个 vue_demo1.vue 文件,内容如下:
<template>
<h2>Vue Component</h2>
<a-space>
<!-- 绑定数据组件当前行的选择器 -->
<a-select v-model:value="data.current[field]" :options="[{value: 'red'}, {value: 'green'}, {value: 'blue'}] "></a-select>
<!-- 选项数据来自数据组件的选择器 -->
<a-select v-model:value="value" :options="data.value.map(row => ({ value: row[field] }))"></a-select>
<!-- 绑定数据组件当前行的输入框 -->
<a-input v-model:value="data.current[field]"></a-input>
</a-space>
<!-- 基于数据组件渲染一个列表,输入框焦点进入(focus)的时候设置当前行 -->
<ul>
<template v-for="(row, index) in data.value">
<li>
<a-input v-model:value="row[field]" @focus="data.to(row)"></a-input>
</li>
</template>
</ul>
</template>
<script>
import { defineComponent, ref } from "vue";
/* 注意:这里需要引用组件 */
import { Input, Space, Select } from "ant-design-vue";
export default defineComponent({
/* 声明属性 */
props: ["data", "field"],
setup(props, context) {
/* 通过 props 接收来自页面组件源码传入的属性 */
let data = props.data;
let field = props.field;
return {
value: ref("test"),
data,
field,
};
},
/* 注意:这里需要组件名映射 */
components: {
ASelect: Select,
ASpace: Space,
AInput: Input,
}
});
</script>
注意:上面代码中的 引用组件 和 组件名映射 是必须的
在 .w 页面源码中引用上面的 vue 文件,需要分别在页面的 .js 和 .w 源码中加入以下代码:
- .js
import Demo1 from '$UI/pcx/vue_demo1.vue';
- .w 注意:productsData 和 productName 改成自己页面上的数据组件和字段
<Demo1 data="{productsData}" field="productName" />
预览即可看到显示效果
通过 ref 获取组件实例
示例场景,在上一个示例基础上,在页面的按钮事件代码中,获取 Demo1 组件实例,并访问组件内部数据
在 .w 页面源码中,给 Demo1 组件增加 ref 属性,代码如下:
<Demo1 data="{productsData}" field="productName" ref="demo1"/>
页面上拖一个按钮组件,点击事件选择写代码方式,代码如下:
let onButton0Click = (event) => {
/* 获取组件实例 */
let demo1 = $page.comp("demo1");
console.log(demo1.value);
}
预览后,点击按钮,在开发者工具的控制台可以看到输出组件的内部数据
v-model 的写法
系统组件的写法
在系统组件中,使用 v-model_xxx 的写法。例如:标签页组件有 activeKey 属性,如下图所示
在 w 文件中写为
<antdv:Tabs id="tabs0" v-model_activeKey="{{state.tabsActiveKey}}">
在 js 中定义 state,代码如下
let state = reactive({ tabsActiveKey: "tabRole" });
原生组件的写法
在原生组件中,使用 v-model:xxx 或 vModel 的写法。例如:输入框组件有 value 属性,如下图所示
在 jsx 中支持下面两种写法,两种写法等效
v-model:value={file.version}
vModel={[file.version, "value"]}