原生编程扩展

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 属性,如下图所示

1742368737740

在 w 文件中写为

<antdv:Tabs id="tabs0" v-model_activeKey="{{state.tabsActiveKey}}">

在 js 中定义 state,代码如下

let state = reactive({ tabsActiveKey: "tabRole" });

原生组件的写法

在原生组件中,使用 v-model:xxx 或 vModel 的写法。例如:输入框组件有 value 属性,如下图所示

1742369313777

在 jsx 中支持下面两种写法,两种写法等效

v-model:value={file.version}
vModel={[file.version, "value"]}

results matching ""

    No results matching ""