Skip to content

自定义组件移动端适配

电脑端组件做好了,手机预览却报错、样式乱、或还是电脑端控件——通常是因为只注册了电脑端,没给手机端单独做一份

本文教你:给已有组件补上手机端。

建议先做电脑端

如果电脑端组件还没接进设计器,请先看添加新组件

重要结论:
手机端不用再写一份拖拽规则。左边菜单还是同一个组件,只是手机上换一套 Vue 文件来显示。

开始前你需要知道

  • 要用带移动端的完整包(只有 PC 的包没有手机渲染能力)
  • 手机端界面一般基于 Vant 组件库
  • 电脑端、手机端对同一个字段,保存的值类型最好一致(比如都存用户 id 字符串)

你大概要多做这几件事

  1. 新建手机端组件文件:src/components/mobile/你的组件.vue
  2. 告诉系统「手机端用这份」:写到 extension/index.jsmobileComponents
  3. (可选)设计画布在手机模式下也要简化显示:写 mobileComponentViews
  4. (可选)只读/预览时特殊展示

拖拽规则(src/config/rule/xxx.js继续共用电脑端那一份,不要复制一份给手机。

可以抄的例子:手写签名 SignaturePad

做什么看哪个文件
电脑端组件src/components/SignaturePad.vue
手机端组件src/components/mobile/SignaturePad.vue
拖拽规则(两边共用)src/config/rule/signaturePad.js
电脑端注册src/form/elm.js
手机端注册src/form/mobile.js

记住 3 点就够:

  1. 注册名字要一样(两边都叫 SignaturePad 这类同一名字)
  2. 保存的值要一样(比如都是图片 base64 字符串)
  3. 只读预览时,手机端也要处理好显示

为什么必须「同名」?

系统加载手机端时,顺序是:

  1. 先挂电脑端那份组件
  2. 再用 mobileComponents同名的组件盖掉它

名字差一点,覆盖就失败,手机上仍会用电脑端组件。

跟着做

第 1 步:写手机端组件

新建 src/components/mobile/UserSelect.vue
下面是一个示意(你可以换成自己的选人弹窗):

vue
<template>
    <div class="_fc-user-select-m">
        <!-- 只读/预览:只显示文字 -->
        <template v-if="formCreateInject?.preview">
            <span>{{ previewText }}</span>
        </template>

        <!-- 编辑:用 Vant 的输入框样式 -->
        <van-field
            v-else
            readonly
            is-link
            :model-value="displayText"
            :disabled="disabled"
            :placeholder="placeholder"
            @click="openPicker"
        />
    </div>
</template>

<script>
import { defineComponent } from 'vue';

export default defineComponent({
    name: 'UserSelect', // 建议和电脑端组件名一致
    props: {
        modelValue: [String, Number],
        disabled: Boolean,
        placeholder: String,
        formCreateInject: Object,
    },
    emits: ['update:modelValue', 'change'],
    computed: {
        previewText() {
            return this.modelValue || '-';
        },
        displayText() {
            return this.modelValue || '';
        },
    },
    methods: {
        openPicker() {
            if (this.disabled) return;
            // 打开你的选人界面,选中后:
            // const id = '选中的用户id';
            // this.$emit('update:modelValue', id);
            // this.$emit('change', id);
        },
    },
});
</script>

和电脑端保持一致的重点:

  • 都用 modelValue / update:modelValue 传值(Vue3)
  • disabled、空值怎么处理要一致
  • 值的类型要一致(不要电脑端存对象、手机端存字符串)

第 2 步:注册(推荐写在 extension)

js
// src/extension/index.js
import UserSelect from '../components/UserSelect.vue';
import MUserSelect from '../components/mobile/UserSelect.vue';

export default {
    components: {
        UserSelect, // 电脑端
    },
    mobileComponents: {
        UserSelect: MUserSelect, // 手机端,key 必须相同
    },
    updateFormCreate() {},
};

更完整的 extension 用法见通过 extension 扩展

第 3 步:启动检查

bash
pnpm run dev
  1. 把设计器切到手机宽度,或打开手机预览
  2. 拖入组件,看是不是手机端交互
  3. 电脑、手机各填一次,确认保存的值一样

常见问题排查

1. 控制台提示找不到组件

→ 手机端还没注册。去 extension/index.jsmobileComponents 补上,名字和电脑端一致。

2. 手机上还是电脑端控件

mobileComponents 的名字和 components 不一致,覆盖失败。改成完全一样。

3. 设计器手机画布正常,单独用手机渲染器却没有

→ 你可能只配了「设计时显示」(mobileComponentViews),没配「填表组件」(mobileComponents)。填表必须配 mobileComponents

4. 电脑有值,手机绑定不对

→ 两边保存的数据类型不一致。统一成同一种,并做好空值处理。

5. 报错说没有 formCreateMobile

→ 当前用的是纯 PC 包。请换完整包,或不要在代码里访问手机端对象。

小提示

  • 老表单不用改:组件 type 不变,只是手机上换了实现
  • 如果电脑端曾用两个名字注册(兼容旧数据),手机端也建议同样注册两个名字
  • 不改源码、只在业务项目里注册时,电脑和手机都要分别 component 一次

相关文档