页面组件

每个页面有且只有一个页面组件,作为页面结构的根,往其上添加各种组件,形成完整的页面。

组件定义

  • 桌面端 React:UI2/comp/antdpro/components/Page/Page.react.js
  • 移动端 React:UI2/comp/vantui/components/Page/Page.react.js
  • 桌面端 Vue :UI2/comp/antdv/components/Page/Page.vue
  • 移动端 Vue :UI2/comp/vant/components/Page/Page.vue

组件属性

页面组件提供以下这些属性

属性 属性名 作用
禁用加载效果 disableLoading 页面显示时不显示加载遮罩
自动充满 isFullPage 页面显示时页面高度是否自动撑满
继承 extends 设置页面结构从哪个页面继承,设置后,被继承页面修改,当前页面也会修改
状态 state 存储页面状态,通过 this.setState 赋值,通过 this.state 取值

自动充满

页面背景色默认是透明的,设置为白色后,可看到自动充满的效果

  • 不自动充满如下图所示

  • 自动充满如下图所示

页面参数

无论是否设置页面参数,打开页面时在 url 上添加参数,在页面中通过 this.params 都可以获取到参数。那么,为什么要设置页面参数呢?

原因有以下两点:

  • 低代码开发:在页面设计时,设计器只能列出设置的页面参数,列不出未设置的页面参数;
  • 页面自完整:当页面参数很多时,还需要配合其它文档,才能了解页面参数,如果设置了页面参数,只需查看页面参数即可

案例参考页面交互

页面继承

页面继承用于多个页面基本相同,只有少量不同,且编辑一个页面后,其他页面也需要得到同样修改的场景。

普通页面包括完整的页面结构,而继承页面由两部分组成:

  • 被继承页面:包括完整的页面结构,作为继承页面的基础页面结构
  • 继承页面:包括与被继承页面的差异,作为继承页面的补充页面结构

页面编译时,将上面两部分合并为一个页面。

添加继承页面

添加继承页面的做法是

  • 添加页面时选择“页面继承”模板,从现有页面中选择一个作为父页面,作为被继承页面

  • 在设计页中编辑页面,例如:添加、删除组件、修改组件属性等

此时“源码”页中显示的是父页面和继承页面合并后的代码,用于页面设计,不要手工修改。切换到“代码”视图,可以看到合并后的代码文件,如下图所示

下图才是继承页面的源码,这里只记录和父页面的差异

JS 的继承

在 JS 文件中重写父页面中的方法,这个重写的 js 方法会覆盖父页面中的方法。例如在继承页面中重写页面显示事件,代码如下图所示 img

父页面的运行效果如下图所示

继承页面的运行效果如下图所示

在 vue 页面中使用 state

定义 state

使用 reactive 定义 state 中的属性及初始值

let state = reactive({aa:"1"});

页面显示 state

使用一个大括号引用 state 的属性

<antdv:Typography.Text content="{state.aa}" id="typographyText5">
</antdv:Typography.Text>

js 赋值 state

直接给 state 的属性赋值

let onSetValueBtnClick = (event) => {
    state.aa = 2;
}

双向绑定 state

系统 input 组件

使用 v-model_ 声明属性双向绑定,属性值使用两个个大括号引用 state 的属性

<antdv:Input id="input2" v-model_value="{{state.aa}}">
</antdv:Input>
原生 input 组件

引用原生组件,并重命名(不重命名使用的还是系统组件),定义一个渲染方法,使用 jsx 语法返回原生组件代码

import {Input as Input2} from "ant-design-vue";

let inputRender = () => {
    return <Input2 v-model:value={state.aa}></Input2>
}

在 w 文件的适当位置,使用一个大括号引用渲染方法

{inputRender()}

组件方法

页面组件提供以下这些方法

方法 作用 说明
comp(key) 获取组件的 js 对象,以便调用组件的方法 key 是组件的 id 或 ref
navigateTo(params) 打开页面 params.url 是要打开页面的 url,需要携带 title 参数作为页面标题,例如:$UI/pcx/page/yemian_jc.w?title=页面继承;params.executor 是传入页面的执行者,用于页面中的上下文组件获取当前人员成员信息
navigateBack(object = {}) 关闭页面 写 object.message 参数,在关闭页面后,会触发父页面的接收消息事件
setState(params) 设置页面状态 state,除了系统的 loading 和 data,也可以设置自己的 state 例如:设置 state 中的 loading 显示和隐藏遮罩,this.setState({loading:true});
isReadonly() 根据页面 url 中的参数,判断当前页面是否只读 以下4种情况表示只读:页面参数 _pagePattern 等于 readonly 时;页面参数 activity-pattern 等于 detail 时;页面参数 readonly 等于 true 时;页面参数 action 等于 view 时
getParentFrame() 作为内嵌页面,获取父页面
getServiceUrl(url, serviceName) 获取服务请求的完整路径 url 是服务请求的url,例如:/main/dbrest/orderm;serviceName 是应用名
getUIUrl(url) 获取页面编译后的 url url 是设计时页面文件路径,例如:$UI/pcx/page/yemian_jc.w
getParentPath() 设置使用父路径后,获取当前父路径
getServiceName() 获取当前应用名
request 发送请求 参考[前端调用服务]
i18n(key,import.meta.url) 获取当前语言对应的资源 参考[多语言配置]

页面生命周期

页面组件提供了页面的生命周期,在不同的时刻派发相应的事件。下图说明了页面 Page 实例的生命周期(以 /entry/mobile/work.w 为例)

img

打开页面过程说明

  1. 加载页面资源文件 → 创建组件 → loading=true(显示加载遮罩)→ 派发 onLoad 事件
  2. 下面开始两条线并行
    1. 加载自动加载的数据 → 派发 onInitState 事件(加载用户数据)→ loading=false(隐藏加载遮罩)
    2. 显示页面切换动画(用时300ms)→ 派发 onShow 事件
  3. 上面两条线完成,渲染页面 → 派发 onReady 事件

图形说明

  1. 上图中提到的数据组件,泛指不可视组件,包括数据集组件(restData)、服务请求组件(serviceRequest)、上下文组件(context)等
  2. 注意上图中 loading 的变化,loading 等于 true 时,页面会有默认遮罩加载效果,可通过 this.state.loading 获取 loading 的值

组件事件

页面组件提供以下这些事件,这些事件和生命周期不同,均是回调事件

事件 事件名 作用
页面加载 onLoad 自动加载的数据未准备好
数据初始化 onInitState 自动加载的数据已准备好,可执行用户的加载数据代码,返回值会作为状态数据
显示 onShow 页面显示时触发
初次渲染完成 onReady 自动加载的数据和用户加载的数据都已准备好,页面显示事件已执行完成
接收消息 onMessage 收到消息时触发
隐藏 onHide 打开其他页面时触发
卸载 onUnLoad 关闭当前页面时触发
Ref 变化 onReactRefChanged 组件的 ref 属性值改变后触发,即设置了 ref 属性的组件渲染后触发

数据初始化事件 onInitState 是页面组件提供的事件,旨在统一管理数据的初始化,即不论是自动加载的数据,还是用户写代码加载的数据,都属于数据初始化。当数据初始化开始时,显示页面加载遮罩,当数据初始化完成时,关闭页面加载遮罩。

数据初始化事件不仅用于加载用户数据,返回值会写入 state。作为状态数据。示例代码如下:

    onPageInitState = async (event) => {
        let serviceInfo = await this.request({
            url: "/manager/services/info"
        });
        return serviceInfo.data;
    }

在 onReady 事件中,执行 console.log(this.state);可看到 state 的内容,如下图所示

img

其中

  • loading 和 data 是平台使用的 state 部分
    • loading 表示页面的 loading 状态
    • data 包括页面不可视组件的状态,展开后如下图所示
  • name 和 label 是数据初始化事件的返回值,写入了 state

自定义加载遮罩

当页面的 this.state.loading 为 true 时,系统自动显示遮罩,桌面端显示 Spin,移动端显示 Loading。重载页面组件的 setDefaultLoading 方法自定义加载遮罩

react 自定义加载遮罩

在 common.js 中自定义加载遮罩的全局修改方案。按照标准 react 逻辑渲染,当页面的 this.state.loading 为 true 时,执行 Page.setDefaultLoading 方法,其中参数 props 包括 pagePath 以及当前页面的 props,可以据此做出不同页面的骨架屏方案

移动端自定义加载遮罩,UI2/mobile/common.js 代码如下

import React,{Fragment} from 'react';
import {Skeleton} from '@antmjs/vantui';
import Page from '../comp/vantui/components/Page/Page.react';
import "./common.css";

Page.setDefaultLoading((props)=>{
    let pagePath = props.pagePath;
    return <Fragment>
        <div className={'x-none-background'}></div>
        <Skeleton title={true} avatar={true} row="3" className={'x-none-background'}/>
    </Fragment>
})

桌面端自定义加载遮罩,UI2/pcx/common.js 代码如下

import React,{Fragment} from 'react';
import {Skeleton} from 'antd';
import Page from '../comp/antdpro/components/Page/Page.react';
import "./common.css";

Page.setDefaultLoading((props)=>{
    let pagePath = props.pagePath;
    return <Fragment>
        <div className={'x-none-background'}></div>
        <Skeleton active className={'x-none-background'}/>
    </Fragment>
})

UI2/mobile/common.css 和 UI2/pcx/common.css 代码相同,代码如下

:global{
    .x-none-background{
        clear: both;
        opacity: 1;
        user-select: none;
        pointer-events: none;
        background: white;
        position: absolute;
        top: 0;
        bottom: 0;
        width: 100%;
    }
}

vue 自定义加载遮罩

和 react 不同,vue 的 jsx 代码必须写到 xxx.vue.jsx 文件中,因此不能在 common.js 文件中,实现统一的自定义加载遮罩,在需要自定义遮罩的页面的 js 文件中自定义加载遮罩方案。按照标准 vue 逻辑渲染,当页面的 this.state.loading 为 true 时,执行 Page 组件的 setDefaultLoading 方法,其中参数 props 包括当前页面的 props

移动端自定义加载遮罩,UI2/mobile/页面的 js 文件代码如下

import {setDefaultLoading} from '$UI/comp/vant/components/Page/Page.vue';
import { Skeleton } from 'vant';

setDefaultLoading((props)=>{
    let pagePath = props.pagePath;
    return <Fragment>
        <div class={'x-none-background'}></div>
        <Skeleton title row="3" class={"x-none-background"}/>
    </Fragment>;
})
let $page = usePage();

桌面端自定义加载遮罩,UI2/pcx/页面的 js 文件代码如下

import {setDefaultLoading} from '$UI/comp/antdv/components/Page/Page.vue';
import { Skeleton } from 'ant-design-vue';

setDefaultLoading((props)=>{
    let pagePath = props.pagePath;
    return <Skeleton active class={"x-none-background"}/>;
})
let $page = usePage();

样式定义在 UI2/mobile/common.css 或 UI2/pcx/common.css 中,样式代码相同,代码如下

.x-none-background{
    clear: both;
    opacity: 1;
    user-select: none;
    pointer-events: none;
    background: white;
    position: absolute;
    top: 0;
    bottom: 0;
    width: 100%;
}

页面自动引用 common.js,在 common.js 文件中引用 common.css,每个页面就自动引用了 common.css 文件,common.js 代码如下

import './common.css';

案例位置

桌面-页面-页面-页面组件.w

桌面-页面-页面-使用state.w

桌面-页面-页面-页面继承.w

桌面-页面-页面-返回消息.w

桌面-页面-页面-骨架屏.w

results matching ""

    No results matching ""