diff --git a/src/popup/container.tsx b/src/popup/container.tsx
index 80f2bb6d7..e2c01677d 100644
--- a/src/popup/container.tsx
+++ b/src/popup/container.tsx
@@ -2,7 +2,42 @@ import Vue from 'vue';
import { getAttach } from '../utils/dom';
import props from './props';
+function isContentRectChanged(rect1: DOMRectReadOnly, rect2: DOMRectReadOnly) {
+ if (!rect1 || !rect2) return;
+ if (['width', 'height', 'x', 'y'].some((k) => rect1[k] !== rect2[k])) {
+ return true;
+ }
+ return false;
+}
+
const Ref = Vue.extend({
+ data() {
+ return {
+ contentRect: null as DOMRectReadOnly,
+ };
+ },
+ mounted() {
+ if (window?.ResizeObserver && this.$el) {
+ const el = this.$el;
+ const vm = this as any;
+ const ro = new ResizeObserver((entries = []) => {
+ const { contentRect } = entries[0] || {};
+ if (isContentRectChanged(contentRect, vm.contentRect)) {
+ vm.contentRect = contentRect;
+ vm.$emit('resize', { ...contentRect });
+ return;
+ }
+ // omit initial change
+ if (!vm.contentRect) {
+ vm.contentRect = contentRect;
+ }
+ });
+ ro.observe(el);
+ this.$on('hook:destroyed', () => {
+ ro.unobserve(el);
+ });
+ }
+ },
render() {
const children = this.$slots.default || [];
if (children.length > 1 || !children[0]?.tag) {
@@ -68,6 +103,6 @@ export default Vue.extend({
},
},
render() {
- return [{this.$slots.default}];
+ return [ this.$emit('refResize', ev)}>{this.$slots.default}];
},
});
diff --git a/src/popup/popup.tsx b/src/popup/popup.tsx
index 0467f7406..fcb46e067 100644
--- a/src/popup/popup.tsx
+++ b/src/popup/popup.tsx
@@ -53,6 +53,10 @@ export default Vue.extend({
/** if a trusted action (opening or closing) is prevented, increase this flag */
visibleState: 0,
mouseInRange: false,
+ /**
+ * mark popup as clicked when mousedown
+ * consume this flag right after click event bubbles up to document
+ */
contentClicked: false,
refClicked: false,
};
@@ -328,17 +332,24 @@ export default Vue.extend({
directives: destroyOnClose
? undefined
: [
- {
- name: 'show',
- rawName: 'v-show',
- value: visible,
- expression: 'visible',
- } as VNodeDirective,
+ {
+ name: 'show',
+ rawName: 'v-show',
+ value: visible,
+ expression: 'visible',
+ } as VNodeDirective,
],
on: {
mousedown: () => {
this.contentClicked = true;
},
+ mouseup: () => {
+ // make sure to execute after document click is triggered
+ setTimeout(() => {
+ // make sure flag is consumed
+ this.contentClicked = false;
+ });
+ },
...(hasTrigger.hover && {
mouseenter: this.onMouseEnter,
mouseleave: this.onMouseLeave,
@@ -374,6 +385,11 @@ export default Vue.extend({
this.updateOverlayStyle();
}
}}
+ onRefResize={() => {
+ if (visible) {
+ this.updatePopper();
+ }
+ }}
parent={this}
visible={visible}
attach={this.attach}
diff --git a/src/select/select.tsx b/src/select/select.tsx
index 9ee91fe4a..d6991d998 100644
--- a/src/select/select.tsx
+++ b/src/select/select.tsx
@@ -673,7 +673,7 @@ export default mixins(getConfigReceiverMixins('select')).exte
{loading && {loadingTextSlot}
}
- {!loading && !displayOptions.length && !showCreateOption && {emptySlot}}
+ {!loading && !displayOptions.length && !showCreateOption && {emptySlot}
}
{!this.hasOptions && displayOptions.length && !loading ? (
this.renderDataWithOptions()
) : (
@@ -685,37 +685,46 @@ export default mixins(getConfigReceiverMixins('select')).exte
);
},
- },
+ /**
+ * Parse options from slots before popup, execute only once
+ */
+ initOptions() {
+ if (this.realOptions.length || this.isInited) return;
- updated() {
- if (this.realOptions.length || this.isInited) return;
+ const children = renderTNodeJSX(this, 'default');
+ if (children) {
+ this.realOptions = parseOptions(children);
+ this.isInited = true;
+ }
- // Parse options from slots before popup, execute only once
- const children = renderTNodeJSX(this, 'default');
- if (children) {
- this.realOptions = parseOptions(children);
- this.isInited = true;
- }
+ function parseOptions(vnodes: VNode[]): TdOptionProps[] {
+ if (!vnodes) return [];
+ return vnodes.reduce((options, vnode) => {
+ const { componentOptions } = vnode;
+ if (componentOptions?.tag === 't-option') {
+ const propsData = componentOptions.propsData as any;
+ return options.concat({
+ label: propsData.label,
+ value: propsData.value,
+ disabled: propsData.disabled,
+ content: componentOptions.children ? () => componentOptions.children : propsData.content,
+ default: propsData.default,
+ });
+ }
+ if (componentOptions?.tag === 't-option-group') {
+ return options.concat(parseOptions(componentOptions.children));
+ }
+ return options;
+ }, []);
+ }
+ },
+ },
- function parseOptions(vnodes: VNode[]): TdOptionProps[] {
- if (!vnodes) return [];
- return vnodes.reduce((options, vnode) => {
- if (vnode.componentOptions.tag === 't-option') {
- const propsData = vnode.componentOptions.propsData as any;
- return options.concat({
- label: propsData.label,
- value: propsData.value,
- disabled: propsData.disabled,
- content: propsData.content,
- default: propsData.default,
- });
- }
- if (vnode.componentOptions.tag === 't-option-group') {
- return options.concat(parseOptions(vnode.componentOptions.children));
- }
- return options;
- }, []);
- }
+ mounted() {
+ this.initOptions();
+ },
+ updated() {
+ this.initOptions();
},
render(): VNode {
diff --git a/test/ssr/__snapshots__/ssr.test.js.snap b/test/ssr/__snapshots__/ssr.test.js.snap
index 66da774e1..673d19e96 100644
--- a/test/ssr/__snapshots__/ssr.test.js.snap
+++ b/test/ssr/__snapshots__/ssr.test.js.snap
@@ -10636,6 +10636,83 @@ exports[`ssr snapshot test renders ./examples/table/demos/custom-cell.vue correc
`;
+exports[`ssr snapshot test renders ./examples/table/demos/custom-col.vue correctly 1`] = `
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 序号 |
+ 平台 |
+ 类型 |
+ 默认值 |
+ 是否必传 |
+ 详情信息 |
+
+
+
+
+ 0 |
+ 共有 |
+ String |
+ - |
+ 是 |
+ 读取 0 个数据的嵌套信息值 |
+
+
+ 1 |
+ 私有 |
+ Number |
+ 0 |
+ 否 |
+ 读取 1 个数据的嵌套信息值 |
+
+
+ 2 |
+ 共有 |
+ Array |
+ [] |
+ 否 |
+ 读取 2 个数据的嵌套信息值 |
+
+
+ 3 |
+ 私有 |
+ Object |
+ {} |
+ 否 |
+ 读取 3 个数据的嵌套信息值 |
+
+
+ 4 |
+ 共有 |
+ String |
+ - |
+ 是 |
+ 读取 4 个数据的嵌套信息值 |
+
+
+
+
+
+
+
+`;
+
exports[`ssr snapshot test renders ./examples/table/demos/custom-header.vue correctly 1`] = `