Skip to content

Commit a98c5d4

Browse files
committed
feat: add empty, update veui, update Iframe component
1 parent 0f7f234 commit a98c5d4

File tree

15 files changed

+494
-115
lines changed

15 files changed

+494
-115
lines changed

Diff for: assets/styles/post.styl

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ margin-y($top, $bottom = $top)
5454
font-size 36px
5555

5656
small
57-
vertical-align 0.1em
57+
margin-left 0.25em
5858
color #999
5959

6060
h2

Diff for: components/OneIframe.vue

+39-30
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,11 @@
1-
<template>
2-
<fragment>
3-
<iframe
4-
ref="iframe"
5-
class="one-iframe"
6-
/>
7-
<slot/>
8-
</fragment>
9-
</template>
10-
111
<script>
12-
import { Fragment } from 'vue-frag'
2+
import Vue from 'vue'
133
144
export default {
155
name: 'one-iframe',
16-
components: {
17-
Fragment
18-
},
196
props: {
20-
globalStyle: String
7+
globalStyle: String,
8+
live: Boolean
219
},
2210
watch: {
2311
globalStyle (value) {
@@ -27,41 +15,55 @@ export default {
2715
}
2816
},
2917
beforeDestroy () {
30-
if (this.contents) {
31-
this.contents.forEach(node => {
32-
this.$refs.iframe.parentNode.appendChild(node)
33-
})
34-
}
35-
3618
if (this.mo) {
3719
this.mo.disconnect()
3820
}
3921
},
4022
mounted () {
4123
const links = document.querySelectorAll('link[rel=stylesheet]')
4224
const styles = document.querySelectorAll('style')
43-
const { iframe } = this.$refs
44-
const { body, head } = iframe.contentDocument
45-
this.contents = this.$el.frag.filter(node => node !== iframe);
46-
[...links, ...styles].forEach(node => {
25+
const { head } = this.$el.contentDocument
26+
27+
;[...links, ...styles].forEach(node => {
4728
const clone = node.cloneNode(true)
4829
head.appendChild(clone)
4930
})
5031
51-
this.contents.forEach(node => {
52-
body.appendChild(node)
53-
})
54-
5532
if (this.globalStyle) {
5633
const style = document.createElement('style')
5734
style.textContent = this.globalStyle
5835
head.appendChild(style)
5936
this.style = style
6037
}
6138
62-
this.watchLiveStyle(head)
39+
this.renderContents()
40+
41+
if (this.live) {
42+
this.watchLiveStyle(head)
43+
}
44+
},
45+
beforeUpdate () {
46+
this.app.contents = Object.freeze(this.$slots.default)
6347
},
6448
methods: {
49+
renderContents () {
50+
const contents = this.$slots.default
51+
const body = this.$el.contentDocument.body
52+
const el = document.createElement('div')
53+
body.appendChild(el)
54+
55+
this.app = new Vue({
56+
el,
57+
data () {
58+
return {
59+
contents: Object.freeze(contents)
60+
}
61+
},
62+
render (h) {
63+
return h('div', this.contents)
64+
}
65+
})
66+
},
6567
watchLiveStyle (head) {
6668
this.liveStyle = document.createComment('')
6769
head.appendChild(this.liveStyle)
@@ -84,6 +86,13 @@ export default {
8486
})
8587
this.mo.observe(document.head, { childList: true })
8688
}
89+
},
90+
render (h) {
91+
return h('iframe', {
92+
class: {
93+
'one-iframe': true
94+
}
95+
})
8796
}
8897
}
8998
</script>

Diff for: components/OneLive.vue

+1
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@
7070
>
7171
<one-iframe
7272
v-if="browser"
73+
live
7374
global-style="body { margin: 0 !important; } body > article { margin: 24px 36px; } .veui-layout { min-width: auto !important; }"
7475
>
7576
<v-live-preview

Diff for: one/docs/components/column.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
| ``filter-options`` | `Array<Object>` | - | 筛选选项列表,项目的类型为 `{label, value, options, disabled, ...}`,可参考 [`Select`](./select) 组件的 [`options`](./select#props-options) 属性。 |
2828
| ``filter-title`` | `string=` | - | 筛选下拉的标题。 |
2929
| ``allowed-orders`` | `Array` | `[false, 'desc', 'asc']` | [^allowed-orders] |
30-
| ``tooltip`` | `boolean | ((item: Object) => string)` | - | 是否当内容溢出时自动显示悬浮提示。默认显示所属 `Table` 组件 [`data`](./table#props-data) 属性数据项中 [`field`](#props-field) 属性对应的字段值。传入函数时,`item` 参数为整个 data 数据项,返回的字符串将作为提示内容展示。 |
30+
| ``tooltip`` | `boolean | ((item: Object) => string)` | - | 是否当内容溢出时自动显示悬浮提示。默认显示当前单元格的 `textContent`。传入函数时,`item` 参数为整个 data 数据项,返回的字符串将作为提示内容展示。 |
3131

3232
^^^sortable
3333
本列是否支持排序。

Diff for: one/docs/components/empty.md

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# Empty <small>空状态</small>
2+
3+
## 示例
4+
5+
### 默认
6+
7+
[[ demo src="/demo/empty/default.vue" ]]
8+
9+
### 页面级
10+
11+
[[ demo src="/demo/empty/hero.vue" ]]
12+
13+
### 局部状态
14+
15+
[[ demo src="/demo/empty/spot.vue" ]]
16+
17+
### 自定义
18+
19+
[[ demo src="/demo/empty/custom.vue" ]]
20+
21+
## API
22+
23+
### 属性
24+
25+
| 名称 | 类型 | 默认值 | 描述 |
26+
| -- | -- | -- | -- |
27+
| ``ui`` | `string=` | - | [^ui] |
28+
| ``image`` | `Object | false=` | - | 插图内容配置。不传时将输出默认插图;传入 `Object` 时,字段将作为 `<img>` 元素的属性输出;传入 `false` 时将隐藏插图。如果为默认插槽传入了内容,此属性会被忽略。 |
29+
| ``title`` | `string=` | - | 空状态标题。 |
30+
| ``desc`` | `string | false=` | - | 空状态描述。传入 `false` 时将隐藏描述。 |
31+
32+
^^^ui
33+
预设样式。
34+
35+
+++枚举值
36+
|| 描述 |
37+
| -- | -- |
38+
| `s` | 小尺寸空状态。全局插图不适合小尺寸样式。 |
39+
| `m` | 中尺寸空状态。 |
40+
+++
41+
^^^
42+
43+
### 插槽
44+
45+
| 名称 | 描述 |
46+
| -- | -- |
47+
| ``default`` | 插图内容。默认情况下会展示“没有数据”对应的插图。 |
48+
| ``title`` | 标题区。 |
49+
| ``desc`` | 描述区。 |
50+
| ``actions`` | 操作区。 |

Diff for: one/docs/demo/directives/tooltip/overflow.vue

+5-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<article>
33
<section>
44
<div
5-
v-tooltip.overflow="loremIpsum"
5+
v-tooltip.overflow
66
class="item"
77
>
88
{{ loremIpsum }}
@@ -45,3 +45,7 @@ export default {
4545
text-overflow: ellipsis;
4646
}
4747
</style>
48+
49+
<docs>
50+
当无绑定值或不提供 `content` 参数时,将自动展示被绑定元素的 `textContent` 内容。
51+
</docs>

Diff for: one/docs/demo/empty/custom.vue

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
<template>
2+
<article>
3+
<section>
4+
<h4>内置 <code>&lt;img&gt;</code> 标签</h4>
5+
<veui-empty
6+
:image="image"
7+
title="找不到对应的内容"
8+
desc="请检查输入的网址是否正确"
9+
/>
10+
</section>
11+
<section>
12+
<h4>任意内容</h4>
13+
<veui-empty
14+
ui="s"
15+
title="未知错误"
16+
:desc="false"
17+
>
18+
<veui-icon
19+
name="exclamation-circle-solid"
20+
style="height: 96px; color: rebeccapurple;"
21+
/>
22+
</veui-empty>
23+
</section>
24+
</article>
25+
</template>
26+
27+
<script>
28+
import { Empty, Icon } from 'veui'
29+
import 'veui-theme-dls-icons/exclamation-circle-solid'
30+
31+
export default {
32+
components: {
33+
'veui-empty': Empty,
34+
'veui-icon': Icon
35+
},
36+
data () {
37+
return {
38+
image: {
39+
src: 'http://ecma.bdimg.com/public01/one-design/597ed72aff7a9fbacf23ba79b43aa61d.png',
40+
width: 296,
41+
height: 197,
42+
alt: '404 illustration provided by unDraw'
43+
}
44+
}
45+
}
46+
}
47+
</script>
48+
49+
<style lang="less" scoped>
50+
section {
51+
display: flex;
52+
flex-direction: column;
53+
align-items: center;
54+
55+
& + & {
56+
margin-top: 20px;
57+
}
58+
}
59+
60+
h4 {
61+
align-self: flex-start;
62+
}
63+
</style>

Diff for: one/docs/demo/empty/default.vue

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<template>
2+
<article>
3+
<veui-empty/>
4+
</article>
5+
</template>
6+
7+
<script>
8+
import { Empty } from 'veui'
9+
10+
export default {
11+
components: {
12+
'veui-empty': Empty
13+
}
14+
}
15+
</script>
16+
17+
<style scoped>
18+
article {
19+
display: flex;
20+
flex-direction: column;
21+
align-items: center;
22+
}
23+
</style>

Diff for: one/docs/demo/empty/hero.vue

+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
<template>
2+
<article>
3+
<section>
4+
<veui-select
5+
v-model="current"
6+
class="picker"
7+
ui="s"
8+
:options="options"
9+
overlay-style="--dls-dropdown-max-display-items: 4;"
10+
/>
11+
</section>
12+
<veui-empty
13+
title="没有权限"
14+
>
15+
<component :is="illustrations[current]"/>
16+
<template #desc>
17+
请联系管理员为你添加权限
18+
<veui-button ui="strong text">
19+
发送邮件
20+
</veui-button>
21+
</template>
22+
<template #actions>
23+
<veui-button ui="primary">
24+
回到首页
25+
</veui-button>
26+
</template>
27+
</veui-empty>
28+
</article>
29+
</template>
30+
31+
<script>
32+
import { Empty, Button, Select } from 'veui'
33+
import * as illustrations from 'dls-illustrations-vue'
34+
35+
const illustrationNames = [
36+
'IllustrationBlank',
37+
'IllustrationClientError',
38+
'IllustrationForbidden',
39+
'IllustrationNoResults',
40+
'IllustrationNotFound',
41+
'IllustrationReviewError',
42+
'IllustrationReviewPending',
43+
'IllustrationReviewSuccess',
44+
'IllustrationServerError'
45+
]
46+
47+
export default {
48+
components: {
49+
'veui-empty': Empty,
50+
'veui-button': Button,
51+
'veui-select': Select
52+
},
53+
data () {
54+
return {
55+
illustrations,
56+
current: 'IllustrationForbidden'
57+
}
58+
},
59+
computed: {
60+
options () {
61+
return illustrationNames.map(name => ({
62+
label: name,
63+
value: name
64+
}))
65+
}
66+
}
67+
}
68+
</script>
69+
70+
<style scoped>
71+
article {
72+
display: flex;
73+
flex-direction: column;
74+
align-items: center;
75+
gap: 30px;
76+
}
77+
78+
section {
79+
align-self: flex-start;
80+
}
81+
82+
.picker {
83+
width: 240px;
84+
}
85+
</style>

0 commit comments

Comments
 (0)