使用场景
覆盖配置分为两种场景
- 需要覆盖多个组件公有 Props 配置(例如
timezone、rtl),使用ConfigProvider - 当
ConfigProvider暴露参数未能满足,希望修改全局修改某个组件的 某类 Props(例如期望将所有Button的theme都配置为solid或所有Popover的position),使用semiGlobal
ConfigProvider
ConfigProvider 借助 provide / inject 实现,因此它能影响组件树中的子组件。ConfigProvider、ConfigConsumer 丢弃未声明的属性,class、style 等不会落到 DOM 上。
代码演示
如何引入
<script setup lang="ts">
import { ConfigProvider, ConfigConsumer, useConfig } from '@fibrous/semi-ui-vue';
</script>
基本用法
通过传入 timeZone 参数,用户可以为时间类组件配置时区:
Select Time Zone:
代码
<script setup lang="ts">
import { ref } from 'vue';
import { ConfigProvider, DatePicker, Select, TimePicker } from '@fibrous/semi-ui-vue';
const timeZone = ref('GMT+08:00');
const defaultTimestamp = 1581599305265;
const gmtList: string[] = [];
for (let hourOffset = -11; hourOffset <= 14; hourOffset++) {
const prefix = hourOffset >= 0 ? '+' : '-';
gmtList.push(`GMT${prefix}${String(Math.abs(hourOffset)).padStart(2, '0')}:00`);
}
// fractional offsets stay fixed all year; an IANA name follows its daylight saving time
gmtList.push('GMT-03:30', 'GMT+05:45', 'GMT+13:45', 'America/New_York');
</script>
<template>
<ConfigProvider :timeZone="timeZone">
<div :style="{ width: '300px' }">
<h5 :style="{ margin: '10px' }">Select Time Zone:</h5>
<Select aria-label="时区" :modelValue="timeZone" placeholder="请选择时区" showClear :style="{ width: '300px' }" @select="(value) => (timeZone = String(value))">
<Select.Option v-for="gmt in gmtList" :key="gmt" :value="gmt">{{ gmt }}</Select.Option>
</Select>
<br />
<br />
<DatePicker :defaultValue="defaultTimestamp" type="dateTime" @change="(date, dateString) => console.log('DatePicker changed: ', date, dateString)" />
<br />
<br />
<TimePicker :defaultValue="defaultTimestamp" @change="(date, dateString) => console.log('DatePicker changed: ', date, dateString)" />
</div>
</ConfigProvider>
</template>手动获取值
通常情况下,组件内部会自动获取 ConfigProvider 的值自动消费,无需关心。但是一些特殊场景,你可能需要手动获取值来进行其他操作。
使用 ConfigConsumer 的默认作用域插槽获取 ConfigProvider 的值;在子组件的 <script setup> 中也可以调用 useConfig(),它返回 ComputedRef<ContextValue>,没有 ConfigProvider 时为空对象。
代码
<script setup lang="ts">
import { ConfigConsumer, ConfigProvider, TypographyText } from '@fibrous/semi-ui-vue';
</script>
<template>
<ConfigProvider timeZone="GMT+08:00">
<ConfigConsumer #default="value">
<TypographyText :ellipsis="{ showTooltip: { opts: { style: { minWidth: '1200px' } } } }" :style="{ width: '600px' }">
{{ JSON.stringify(value) }}
</TypographyText>
</ConfigConsumer>
</ConfigProvider>
</template>响应式断点监听
ConfigProvider 支持配置响应式断点,并在断点变化时进行订阅回调。
开启监听与自定义断点
- 通过
responsiveObserve开启断点监听(建议只在确实需要订阅的场景开启) - 通过
responsiveMap自定义断点(未传入时使用默认断点)
<!-- breakpoint-subscriber.vue -->
<script setup lang="ts">
import { onBeforeUnmount, onMounted, ref } from 'vue';
import { TypographyText, useConfig } from '@fibrous/semi-ui-vue';
const config = useConfig();
const screens = ref(config.value.screens);
let unsubscribe: (() => void) | undefined;
onMounted(() => {
unsubscribe = config.value.onBreakpoint?.((next) => {
screens.value = next;
});
});
onBeforeUnmount(() => unsubscribe?.());
</script>
<template>
<TypographyText>{{ JSON.stringify(screens) }}</TypographyText>
</template>
<script setup lang="ts">
import { ConfigProvider } from '@fibrous/semi-ui-vue';
import BreakpointSubscriber from './breakpoint-subscriber.vue';
const responsiveMap = {
xs: '(max-width: 575px)',
sm: '(min-width: 576px)',
md: '(min-width: 768px)',
lg: '(min-width: 992px)',
xl: '(min-width: 1200px)',
xxl: '(min-width: 1600px)',
};
</script>
<template>
<ConfigProvider responsiveObserve :responsiveMap="responsiveMap">
<BreakpointSubscriber />
</ConfigProvider>
</template>
订阅 API
onBreakpoint 支持两种签名,均会返回取消订阅函数:
onBreakpoint((screens) => void):回调拿到完整的 screens 映射onBreakpoint(['md', 'lg'], (screen, match) => void):只监听指定断点,回调拿到单个断点变化
RTL/LTR
全局配置 direction 可以改变组件的文本方向。
rtl 表示从右到左 (类似希伯来语或阿拉伯语), ltr 表示从左到右 (类似中文、英语等大部分语言)。显式传入的 direction 与外层不同时(含最外层),ConfigProvider 会在内容外包一层带 dir 属性的 div。组件的 RTL 样式用 :dir(rtl) 匹配,跟随最近的祖先 dir 属性;弹层根元素按 ConfigProvider 的 direction 输出 dir。页面自己在 <html> 等元素上设置 dir="rtl" 时,页面内的组件样式按 RTL 显示,但键盘方向、弹层位置等逻辑只读 ConfigProvider 的 direction,ConfigProvider 内的弹层与 Table 也按它的 direction(默认 ltr)显示,因此仍需同时设置 direction="rtl"。
特殊组件:
- Modal,Notification,Toast 的命令式调用需要通过 prop 传
direction。 - 如果你想对有方向性的 Icon 做 RTL 国际化,需要自己单独进行处理。我们认为对 Icon 进行 RTL 会让它变得难以理解和维护。其他组件内的 icon Semi 已经做了 RTL 适配。
- Table 的树形数据暂不支持 RTL(Chrome、Safari 浏览器表现与 Firefox 表现不同),固定列支持 RTL。
Vue 的命令式调用读不到 ConfigProvider(它是组件级 provide),需要跟随方向时在选项里传 direction,或改用 Modal.useModal()、Toast.useToast()、Notification.useNotification(),它们返回的 Holder 组件渲染在哪里,就继承哪里的 ConfigProvider。
Buttons
Input
Navigation
- 每页条数:10
Display
- 审核中2019-07-14 10:35
- 发布成功2019-06-13 16:17
- 审核失败2019-05-14 18:34
Feedback
Here are some texts.
And more texts on the way.
代码
<script setup lang="ts">
import { h, ref, type CSSProperties } from 'vue';
import { IconCamera, IconChevronDown, IconEdit, IconList, IconSidebar, IconVigoLogo } from '@fibrous/semi-icons-vue';
import {
Avatar,
Badge,
Breadcrumb,
Button,
ButtonGroup,
Cascader,
Checkbox,
Col,
ConfigProvider,
DatePicker,
Input,
Modal,
Nav,
Notification,
Pagination,
Popover,
Radio,
Rating,
Row,
Select,
Spin,
Steps,
Switch,
Tag,
TextArea,
TimePicker,
Timeline,
Toast,
Tooltip,
TypographyText,
type NavItemConfig,
} from '@fibrous/semi-ui-vue';
const direction = ref<'ltr' | 'rtl'>();
const flexStyle: CSSProperties = { display: 'flex', marginBottom: '32px', flexWrap: 'wrap' };
const titleStyle = { margin: '50px 0 16px 0' };
const rowStyle = { margin: '16px 10px' };
const badgeStyle = {
width: '42px',
height: '42px',
borderRadius: '4px',
display: 'inline-block',
};
const tagStyle = { marginRight: '8px', marginBottom: '8px' };
const buttonStyle = { ...tagStyle };
const opts = () => ({
title: 'Hi,Bytedance',
content: 'ies dance dance dance',
duration: 3,
direction: direction.value,
});
const treeData = [
{
label: '浙江省',
value: 'zhejiang',
children: [
{
label: '杭州市',
value: 'hangzhou',
children: [
{ label: '西湖区', value: 'xihu' },
{ label: '萧山区', value: 'xiaoshan' },
{ label: '临安区', value: 'linan' },
],
},
{
label: '宁波市',
value: 'ningbo',
children: [
{ label: '海曙区', value: 'haishu' },
{ label: '江北区', value: 'jiangbei' },
],
},
],
},
];
const navItems = [
{ itemKey: 'user', text: 'Option1' },
{ itemKey: 'union', text: 'Option2' },
{ itemKey: 'approve-management', text: 'Group3', items: ['3-1', '3-2'] },
];
const navIcons = { user: IconEdit, union: IconCamera, 'approve-management': IconList };
const navIconOf = (item: NavItemConfig) => navIcons[item.itemKey as keyof typeof navIcons];
const vigoNotice = (color?: string) => Notification.info({ ...opts(), icon: h(IconVigoLogo, color ? { style: { color } } : null) });
</script>
<template>
<div>
<div :style="{ marginBottom: '20px' }">
<ButtonGroup>
<Button @click="direction = 'ltr'">LTR</Button>
<Button @click="direction = 'rtl'">RTL</Button>
</ButtonGroup>
</div>
<ConfigProvider :direction="direction">
<Row>
<h3 :style="titleStyle">Buttons</h3>
</Row>
<Row :style="rowStyle">
<Button loading :style="{ marginRight: '8px' }" theme="solid">加载</Button>
<Button :style="{ marginRight: '8px' }" theme="solid">
<template #icon>
<IconSidebar />
</template>
收起
</Button>
<Button iconPosition="right" :style="{ marginRight: '8px' }" theme="solid">
<template #icon>
<IconChevronDown />
</template>
展开选项
</Button>
<br />
<br />
<ButtonGroup>
<Button>拷贝</Button>
<Button>查询</Button>
<Button>剪切</Button>
</ButtonGroup>
</Row>
<Row>
<h3 :style="titleStyle">Input</h3>
</Row>
<Row :gutter="16" :style="rowStyle">
<Col :span="12">
<Input aria-label="输入框" placeholder="输入框" />
<br />
<br />
<Input aria-label="禁用的输入框" disabled placeholder="输入框" />
<br />
<br />
<Input aria-label="带前缀的输入框" showClear>
<template #prefix>Prefix</template>
</Input>
<br />
<br />
<Input aria-label="带后缀的输入框" showClear>
<template #suffix>
<TypographyText strong :style="{ margin: '0 8px' }" type="secondary">Suffix</TypographyText>
</template>
</Input>
<br />
<br />
<TextArea aria-label="文本框" :maxCount="100" placeholder="文本框" />
<br />
<br />
<div :style="flexStyle">
<Switch aria-label="已开启的开关" defaultChecked :style="{ marginRight: '8px' }" />
<Switch aria-label="已关闭的开关" :style="{ marginRight: '8px' }" />
<Switch aria-label="禁用的开关" defaultChecked disabled :style="{ marginRight: '8px' }" />
</div>
<div :style="flexStyle">
<Checkbox defaultChecked :style="{ marginRight: '8px' }">多选框</Checkbox>
<Checkbox defaultChecked disabled :style="{ marginRight: '8px' }">禁用的多选框</Checkbox>
<Checkbox disabled :style="{ marginRight: '8px' }">禁用的多选框</Checkbox>
</div>
<div :style="{ ...flexStyle, marginBottom: 0 }">
<Radio defaultChecked :style="{ marginRight: '8px' }">单选框</Radio>
<Radio defaultChecked disabled :style="{ marginRight: '8px' }">禁用的单选框</Radio>
<Radio disabled :style="{ marginRight: '8px' }">禁用的单选框</Radio>
</div>
</Col>
<Col :span="12">
<DatePicker :style="{ width: '100%' }" @change="(_date, dateString) => console.log(dateString)" />
<br />
<br />
<TimePicker :style="{ width: '100%' }" />
<br />
<br />
<Select aria-label="选择器-单选" placeholder="选择器-单选" :style="{ width: '100%' }">
<Select.Option value="abc">抖音</Select.Option>
<Select.Option value="hotsoon">火山</Select.Option>
<Select.Option disabled value="pipixia">皮皮虾</Select.Option>
<Select.Option value="xigua">西瓜视频</Select.Option>
</Select>
<br />
<br />
<Select aria-label="选择器-禁用" disabled placeholder="选择器-禁用" :style="{ width: '100%' }">
<Select.Option value="abc">抖音</Select.Option>
<Select.Option value="hotsoon">火山</Select.Option>
<Select.Option disabled value="pipixia">皮皮虾</Select.Option>
<Select.Option value="xigua">西瓜视频</Select.Option>
</Select>
<br />
<br />
<Select aria-label="选择器-多选" multiple placeholder="选择器-多选" :style="{ width: '100%' }">
<Select.Option value="abc">抖音</Select.Option>
<Select.Option value="hotsoon">火山</Select.Option>
<Select.Option disabled value="pipixia">皮皮虾</Select.Option>
<Select.Option value="xigua">西瓜视频</Select.Option>
</Select>
<br />
<br />
<Cascader placeholder="级联选择器" :style="{ width: '100%' }" :treeData="treeData" />
</Col>
</Row>
<Row>
<h3 :style="titleStyle">Navigation</h3>
</Row>
<Row :style="rowStyle">
<Breadcrumb>
<Breadcrumb.Item>Semi-ui</Breadcrumb.Item>
<Breadcrumb.Item>Breadcrumb</Breadcrumb.Item>
<Breadcrumb.Item>Default</Breadcrumb.Item>
</Breadcrumb>
<Nav :items="navItems" mode="horizontal">
<template #icon="{ item }">
<component :is="navIconOf(item)" />
</template>
</Nav>
<br />
<br />
<Pagination showSizeChanger :total="80" />
<br />
<Steps :current="1">
<Steps.Step>
<template #title>Finished</template>
<template #description>This is a description.</template>
</Steps.Step>
<Steps.Step>
<template #title>In Progress</template>
<template #description>This is a description.</template>
</Steps.Step>
<Steps.Step>
<template #title>Waiting</template>
<template #description>This is a description.</template>
</Steps.Step>
</Steps>
<br />
<Steps :current="1" status="error">
<Steps.Step>
<template #title>Finished</template>
<template #description>This is a description</template>
</Steps.Step>
<Steps.Step>
<template #title>In Process</template>
<template #description>This is a description</template>
</Steps.Step>
<Steps.Step>
<template #title>Waiting</template>
<template #description>This is a description</template>
</Steps.Step>
</Steps>
</Row>
<Row>
<h3 :style="titleStyle">Display</h3>
</Row>
<Row :style="rowStyle">
<div :style="{ display: 'flex' }">
<div :style="{ padding: '8px' }">
<Badge :count="5" theme="solid">
<Avatar color="blue" shape="square" :style="badgeStyle">XZ</Avatar>
</Badge>
</div>
<div :style="{ padding: '8px' }">
<Badge :count="5" theme="light">
<Avatar color="cyan" shape="square" :style="badgeStyle">YB</Avatar>
</Badge>
</div>
<div :style="{ padding: '8px' }">
<Badge :count="5" theme="inverted">
<Avatar color="indigo" shape="square" :style="badgeStyle">LX</Avatar>
</Badge>
</div>
<div :style="{ padding: '8px' }">
<Badge dot theme="solid">
<Avatar color="light-blue" shape="square" :style="badgeStyle">YZ</Avatar>
</Badge>
</div>
<div :style="{ padding: '8px' }">
<Badge dot theme="light">
<Avatar color="teal" shape="square" :style="badgeStyle">HW</Avatar>
</Badge>
</div>
<div :style="{ padding: '8px', borderRadius: '4px', backgroundColor: 'var(--semi-color-fill-0)' }">
<Badge dot theme="inverted">
<Avatar color="green" shape="square" :style="badgeStyle">XM</Avatar>
</Badge>
</div>
</div>
<br />
<div>
<Tag color="grey" :style="tagStyle">grey tag</Tag>
<Tag color="blue" :style="tagStyle">blue tag</Tag>
<Tag color="blue" :style="tagStyle" type="ghost">ghost tag</Tag>
<Tag color="blue" :style="tagStyle" type="solid">solid tag</Tag>
<Tag color="red" :style="tagStyle">red tag</Tag>
<Tag color="green" :style="tagStyle">green tag</Tag>
<Tag color="orange" :style="tagStyle">orange tag</Tag>
<Tag color="teal" :style="tagStyle">teal tag</Tag>
<Tag color="violet" :style="tagStyle">violet tag</Tag>
<Tag color="white" :style="tagStyle">white tag</Tag>
</div>
<br />
<div :style="{ display: 'flex', alignItems: 'center' }">
<Popover :style="{ padding: '8px' }">
<Tag :style="{ marginRight: '8px' }">I am Popover</Tag>
<template #content>hi semi-design</template>
</Popover>
<Tooltip>
<Tag :style="{ marginRight: '8px' }">I am Tooltip</Tag>
<template #content>hi semi-design</template>
</Tooltip>
<Rating :defaultValue="3" size="small" :style="{ marginRight: '8px' }" />
</div>
<br />
<Timeline>
<Timeline.Item type="ongoing">
<template #time>2019-07-14 10:35</template>
审核中
</Timeline.Item>
<Timeline.Item type="success">
<template #time>2019-06-13 16:17</template>
发布成功
</Timeline.Item>
<Timeline.Item type="error">
<template #time>2019-05-14 18:34</template>
审核失败
</Timeline.Item>
</Timeline>
</Row>
<Row>
<h3 :style="titleStyle">Feedback</h3>
</Row>
<Row :style="rowStyle">
<Button :style="buttonStyle" type="primary" @click="Notification.success(opts())"> 成功信息的通知 </Button>
<Button :style="buttonStyle" @click="Notification.info(opts())">提示信息的通知</Button>
<Button :style="buttonStyle" type="warning" @click="Notification.warning(opts())"> 警告信息的通知 </Button>
<Button :style="buttonStyle" type="danger" @click="Notification.error(opts())">失败信息的通知</Button>
<Button aria-label="Vigo 图标通知" :style="buttonStyle" @click="vigoNotice()">
<template #icon>
<IconVigoLogo />
</template>
</Button>
<Button aria-label="粉色 Vigo 图标通知" :style="buttonStyle" @click="vigoNotice('pink')">
<template #icon>
<IconVigoLogo />
</template>
</Button>
<br />
<Button :style="buttonStyle" type="primary" @click="Modal.success(opts())">成功信息的弹窗</Button>
<Button :style="buttonStyle" @click="Modal.info(opts())">提示信息的弹窗</Button>
<Button :style="buttonStyle" type="warning" @click="Modal.warning(opts())">警告信息的弹窗</Button>
<Button :style="buttonStyle" type="danger" @click="Modal.error(opts())">失败信息的弹窗</Button>
<br />
<Button :style="buttonStyle" type="primary" @click="Toast.success(opts())">成功信息的提示</Button>
<Button :style="buttonStyle" @click="Toast.info(opts())">提示信息的提示</Button>
<Button :style="buttonStyle" type="warning" @click="Toast.warning(opts())">警告信息的提示</Button>
<Button :style="buttonStyle" type="danger" @click="Toast.error(opts())">失败信息的提示</Button>
<br />
<br />
<Spin>
<template #tip>I am loading...</template>
<div
:style="{
backgroundColor: 'var(--semi-color-primary-light-default)',
border: '1px solid var(--semi-color-primary)',
borderRadius: '4px',
padding: '16px 10px',
}"
>
<p>Here are some texts.</p>
<p>And more texts on the way.</p>
</div>
</Spin>
</Row>
</ConfigProvider>
</div>
</template>嵌套使用
ConfigProvider 可以嵌套。内层只覆盖显式传入的属性,没传的属性(direction、locale、timeZone、getPopupContainer、responsiveObserve、responsiveMap)继承外层。属性值为 undefined 视为没传;locale={null} 是显式传入,会清除外层的 locale,交给其内部的 LocaleProvider 或默认语言。
direction 为 rtl 的 ConfigProvider 内可以用 direction="ltr" 把子树切回从左到右,内层组件的逻辑和样式都按 ltr 处理。
代码
<script setup lang="ts">
import en_US from '@fibrous/semi-foundation/locale/source/en_US';
import { ConfigConsumer, ConfigProvider } from '@fibrous/semi-ui-vue';
</script>
<template>
<ConfigProvider direction="ltr" :locale="en_US" timeZone="Asia/Tokyo">
<ConfigConsumer #default="{ locale, timeZone, direction }">
<div :style="{ margin: '8px' }">
外层:locale = {{ locale?.code ?? '未设置' }},timeZone = {{ String(timeZone) }},direction =
{{ direction }}
</div>
</ConfigConsumer>
<ConfigProvider :timeZone="8">
<ConfigConsumer #default="{ locale, timeZone, direction }">
<div :style="{ margin: '8px' }">内层只传 timeZone,其余继承外层:locale = {{ locale?.code ?? '未设置' }},timeZone = {{ String(timeZone) }},direction = {{ direction }}</div>
</ConfigConsumer>
</ConfigProvider>
</ConfigProvider>
</template>API 参考
ConfigProvider
Props
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| direction | 文本方向,可选 ltr 或 rtl。未传时继承外层 ConfigProvider,最外层默认为 ltr。 | "ltr" | "rtl" | undefined |
| timeZone | 时间类组件使用的时区:数字(距 UTC 的小时偏移)、GMT±HH:MM 字符串或 IANA 标识。数字和 GMT 写法是全年固定的偏移。未传时继承外层。 | string | number | undefined |
| locale | 多语言配置,优先级高于 LocaleProvider。未传时继承外层 ConfigProvider;没有 ConfigProvider 设置时由 LocaleProvider 决定,两者都没有时使用 zh_CN。传 null 清除外层的 locale。 | Locale | null | undefined |
| getPopupContainer | 返回弹层容器的函数,只影响仍通过 Portal 渲染的 Modal、SideSheet、ImagePreview,容器需要设置 position: relative。未传时继承外层,最外层为 document.body。 | Type(() => HTMLElement) | undefined |
| responsiveObserve | 是否开启响应式断点监听。关闭时不注册任何 matchMedia 监听;开启后在首次订阅时注册,无订阅时注销。未传时继承外层,最外层为 false。 | boolean | undefined |
| responsiveMap | 自定义响应式断点,key 为 xs、sm、md、lg、xl、xxl,value 为 media query 字符串。按内容比较,内联写对象不会重新注册监听;未传时继承外层,最外层使用 defaultResponsiveMap。 | ResponsiveMap | undefined |
Events
| 事件 | 说明 | 回调参数 |
|---|---|---|
| 无 |
Slots
| 插槽 | 说明 | 作用域参数 |
|---|---|---|
| default | 受该配置影响的内容。显式传入的 direction 与外层不同时(含最外层),内容外包一层带 dir 属性的 div。 | any |
Exposes
| 名称 | 说明 | 类型 |
|---|---|---|
| 无 |
ConfigProvider.defaultResponsiveMap 与具名导出 defaultResponsiveMap 是默认断点配置。locale 的用法同 LocaleProvider 中 locale 参数的用法。
ConfigConsumer
Props
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| 无 |
Events
| 事件 | 说明 | 回调参数 |
|---|---|---|
| 无 |
Slots
| 插槽 | 说明 | 作用域参数 |
|---|---|---|
| default | 作用域插槽,参数为当前生效的配置(ContextValue);在 ConfigProvider 内还包含 screens 与 onBreakpoint,没有 ConfigProvider 时为空对象。 | ContextValue |
Exposes
| 名称 | 说明 | 类型 |
|---|---|---|
| 无 |
useConfig
useConfig(): ComputedRef<ContextValue> 返回当前生效的配置,没有 ConfigProvider 时为空对象。ContextValue 包含上表的 direction、timeZone、locale、getPopupContainer、responsiveObserve、responsiveMap,以及只读的 screens(各断点的命中情况)和 onBreakpoint(订阅函数,见上文「订阅 API」)。
时区标识
- 数字,例如
1、-9.5,代表距离 UTC 的时间偏移,单位为小时,可以为负数或小数; - 字符串,例如
GMT-09:30、GMT+08:00这样的以"GMT"开头的表征偏移字符串,也可以为 IANA 标识,如Asia/Shanghai、America/Los_Angeles等。
数字和 GMT-09:30 这类写法表示全年固定的偏移,不随夏令时变化。例如 -3.5 和 GMT-03:30 全年都是 UTC-03:30,时间格式中的时区名(z)显示为 GMT-03:30。
需要跟随某个地区的夏令时,请使用 IANA 标识。这里可以查看 IANA 标识列表,以及时区是否有夏令时。
FAQ
- ConfigProvider中没有提供全局自定义prefix classname的功能,有类似需求如何实现(例如SDK中使用了Semi,期望打包的dom样式不带.semi-xx前缀,以免被宿主的全局 CSS 影响)?
- 由于 prefixCls 需要同时被组件层的 js/css 消费,Semi 将此开关放在了webpack plugin的配置项中,而不是作为ConfigProvider的配置项。
- 如果你使用webpack,请在
SemiWebpackPlugin的参数中进行配置
# webpack配置示例
const SemiWebpackPlugin = require('@fibrous/semi-webpack-plugin').default;
module.exports = {
+ plugins: [new SemiWebpackPlugin({ prefixCls: 'imes' })],
}
semiGlobal
除了 ConfigProvider外,你还可以通过 semiGlobal 配置覆盖全局组件的默认 Props。
在 semiGlobal.config.overrideDefaultProps 可配置组件默认 Props。非函数类型的默认值在实例首次缺省该属性时读取并缓存;函数类型的默认值(如 getPopupContainer)由各组件在需要时读取,时机因组件而异。全局配置不是响应式的,修改它不会让已创建的实例更新。因此建议在创建应用之前设置,放在站点入口处。需要为单个 app 使用独立的配置时,用 app.provide(semiGlobalKey, { config: { overrideDefaultProps } }),semiGlobalKey 同样从 @fibrous/semi-ui-vue 导入。
id、insetLabelId、wrapperId、addonId、extraId 这类每个实例唯一的属性不能经全局默认值设置:类型里没有这些键,运行时也忽略。
比如下方配置就是将所有的 Button 默认设置为 warning,Select 默认开启 filter 等
import { semiGlobal } from '@fibrous/semi-ui-vue';
semiGlobal.config.overrideDefaultProps = {
Button: {
type: 'warning',
},
Select: {
filter: true,
},
Tooltip: {
trigger: 'click',
},
};