Skip to content

Commit d08ce00

Browse files
Copilotliweijie0812
andcommitted
Convert App.vue and theme generator components to script setup
Co-authored-by: liweijie0812 <10710889+liweijie0812@users.noreply.github.com>
1 parent 85eba58 commit d08ce00

File tree

4 files changed

+188
-158
lines changed

4 files changed

+188
-158
lines changed

packages/theme-generator/src/Generator.vue

Lines changed: 51 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818
</div>
1919
</template>
2020

21-
<script>
21+
<script setup>
22+
import { ref, provide, onMounted } from 'vue';
2223
import {
2324
applyThemeFromLocal,
2425
DEFAULT_THEME,
@@ -38,62 +39,58 @@ const activeTabMap = {
3839
size: 4,
3940
};
4041
41-
export default {
42-
name: 'ThemeGenerator',
43-
components: {
44-
PanelDrawer,
45-
Dock,
42+
const props = defineProps({
43+
propsTop: String,
44+
showSetting: {
45+
type: [Boolean, String],
4646
},
47-
props: {
48-
propsTop: String,
49-
showSetting: {
50-
type: [Boolean, String],
51-
},
52-
device: {
53-
type: String,
54-
default: 'web',
55-
},
56-
},
57-
provide() {
58-
return {
59-
device: this.device,
60-
};
61-
},
62-
data() {
63-
return {
64-
activeTabMap,
65-
refresh: false,
66-
visible: 0,
67-
activeTabIdx: activeTabMap.color,
68-
theme: DEFAULT_THEME,
69-
};
70-
},
71-
mounted() {
72-
const localTheme = getOptionFromLocal('color') ?? DEFAULT_THEME.value;
73-
generateNewTheme(localTheme, undefined, this.device);
74-
syncThemeToIframe(this.device);
75-
applyThemeFromLocal(this.device);
76-
},
77-
methods: {
78-
handleChangeTheme(theme) {
79-
this.theme = theme;
80-
},
81-
handleRefreshContent() {
82-
this.refresh = !this.refresh;
83-
},
84-
handleTriggerVisible() {
85-
this.visible = true;
86-
},
87-
handleDrawerVisible(v) {
88-
this.visible = v;
89-
this.$emit('panel-drawer-visible', v);
90-
},
91-
handleClickSetting() {
92-
this.$emit('click-setting');
93-
this.visible = false;
94-
},
47+
device: {
48+
type: String,
49+
default: 'web',
9550
},
51+
});
52+
53+
const emit = defineEmits(['click-setting', 'panel-drawer-visible']);
54+
55+
// Provide device to child components
56+
provide('device', props.device);
57+
58+
// Data
59+
const refresh = ref(false);
60+
const visible = ref(0);
61+
const activeTabIdx = ref(activeTabMap.color);
62+
const theme = ref(DEFAULT_THEME);
63+
64+
// Methods
65+
const handleChangeTheme = (newTheme) => {
66+
theme.value = newTheme;
9667
};
68+
69+
const handleRefreshContent = () => {
70+
refresh.value = !refresh.value;
71+
};
72+
73+
const handleTriggerVisible = () => {
74+
visible.value = true;
75+
};
76+
77+
const handleDrawerVisible = (v) => {
78+
visible.value = v;
79+
emit('panel-drawer-visible', v);
80+
};
81+
82+
const handleClickSetting = () => {
83+
emit('click-setting');
84+
visible.value = false;
85+
};
86+
87+
// Lifecycle hooks
88+
onMounted(() => {
89+
const localTheme = getOptionFromLocal('color') ?? DEFAULT_THEME.value;
90+
generateNewTheme(localTheme, undefined, props.device);
91+
syncThemeToIframe(props.device);
92+
applyThemeFromLocal(props.device);
93+
});
9794
</script>
9895
9996
<style lang="less" scoped>

packages/theme-generator/src/common/SizeSlider/index.vue

Lines changed: 40 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -24,56 +24,51 @@
2424
</div>
2525
</div>
2626
</template>
27-
<script>
27+
<script setup>
28+
import { ref, onMounted } from 'vue';
2829
import { InputNumber as TInputNumber, Slider as TSlider } from 'tdesign-vue';
2930
import { handleAttach } from '../../common/utils';
3031
31-
export default {
32-
name: 'SizeSlider',
33-
props: {
34-
sizeValue: [String, Number],
35-
title: String,
36-
step: Number,
37-
min: Number,
38-
max: Number,
39-
disabled: Boolean,
40-
needInteger: {
41-
type: Boolean,
42-
default: true,
43-
},
44-
},
45-
components: {
46-
TSlider,
47-
TInputNumber,
48-
},
49-
emit: ['changeFontSize'],
50-
data() {
51-
return {
52-
size: null,
53-
};
54-
},
55-
methods: {
56-
format(val) {
57-
return `${val}px`;
58-
},
59-
handleAttach,
60-
handleInputChange(v) {
61-
if (
62-
v === this.size ||
63-
v < this.min ||
64-
v > this.max ||
65-
this.disabled ||
66-
(this.needInteger && !Number.isInteger(Number(v)))
67-
)
68-
return;
69-
this.size = v;
70-
this.$emit('changeFontSize', v);
71-
},
72-
},
73-
mounted() {
74-
this.size = this.needInteger ? parseInt(this.sizeValue, 10) : this.sizeValue;
32+
const props = defineProps({
33+
sizeValue: [String, Number],
34+
title: String,
35+
step: Number,
36+
min: Number,
37+
max: Number,
38+
disabled: Boolean,
39+
needInteger: {
40+
type: Boolean,
41+
default: true,
7542
},
43+
});
44+
45+
const emit = defineEmits(['changeFontSize']);
46+
47+
// Data
48+
const size = ref(null);
49+
50+
// Methods
51+
const format = (val) => {
52+
return `${val}px`;
7653
};
54+
55+
const handleInputChange = (v) => {
56+
if (
57+
v === size.value ||
58+
v < props.min ||
59+
v > props.max ||
60+
props.disabled ||
61+
(props.needInteger && !Number.isInteger(Number(v)))
62+
)
63+
return;
64+
size.value = v;
65+
emit('changeFontSize', v);
66+
};
67+
68+
// Lifecycle hooks
69+
onMounted(() => {
70+
size.value = props.needInteger ? parseInt(props.sizeValue, 10) : props.sizeValue;
71+
});
7772
</script>
7873
<style lang="less" scoped>
7974
.panel {

site/src/App.vue

Lines changed: 48 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -5,61 +5,58 @@
55
</td-doc-layout>
66
</template>
77

8-
<script>
9-
export default {
10-
computed: {
11-
headerStyle () {
12-
const { name } = this.$route
13-
const fixedHeaderList = ['home', 'home-en', 'source', 'source-en', 'trade']
14-
if (fixedHeaderList.includes(name)) {
15-
return {
16-
position: 'fixed',
17-
top: 0,
18-
left: 0,
19-
width: '100%',
20-
zIndex: 1200,
21-
'--bg-color-secondarypage': 'var(--bg-color-navigation)',
22-
'--bg-color-secondarypage-hover': 'var(--bg-color-navigation-hover)',
23-
'--bg-color-secondarypage-select': 'var(--bg-color-navigation-select)'
24-
}
25-
}
26-
return { display: 'none' }
27-
}
28-
},
8+
<script setup>
9+
import { computed, onMounted, onBeforeUnmount, watch } from 'vue';
10+
import { useRoute } from 'vue-router';
2911
30-
mounted () {
31-
window.addEventListener('load', this.handleHashScroll)
32-
},
12+
const route = useRoute();
3313
34-
beforeDestroy () {
35-
window.removeEventListener('load', this.handleHashScroll)
36-
},
14+
// Computed
15+
const headerStyle = computed(() => {
16+
const { name } = route;
17+
const fixedHeaderList = ['home', 'home-en', 'source', 'source-en', 'trade'];
18+
if (fixedHeaderList.includes(name)) {
19+
return {
20+
position: 'fixed',
21+
top: 0,
22+
left: 0,
23+
width: '100%',
24+
zIndex: 1200,
25+
'--bg-color-secondarypage': 'var(--bg-color-navigation)',
26+
'--bg-color-secondarypage-hover': 'var(--bg-color-navigation-hover)',
27+
'--bg-color-secondarypage-select': 'var(--bg-color-navigation-select)'
28+
};
29+
}
30+
return { display: 'none' };
31+
});
32+
33+
// Methods
34+
const handleHashScroll = () => {
35+
const hash = decodeURIComponent(route.hash);
36+
requestAnimationFrame(() => {
37+
const id = hash.slice(1);
38+
const anchorEl = document.getElementById(id);
39+
if (!anchorEl) return;
40+
41+
requestAnimationFrame(() => {
42+
window.scrollTo({ top: anchorEl.offsetTop - 88 });
43+
});
44+
});
45+
};
3746
38-
watch: {
39-
$route: {
40-
immediate: true,
41-
handler (route) {
42-
if (route.meta) {
43-
document.title = route.meta.documentTitle || 'TDesign'
44-
}
45-
}
46-
}
47-
},
47+
// Lifecycle hooks
48+
onMounted(() => {
49+
window.addEventListener('load', handleHashScroll);
50+
});
4851
49-
methods: {
50-
handleHashScroll () {
51-
const { $route } = this
52-
const hash = decodeURIComponent($route.hash)
53-
requestAnimationFrame(() => {
54-
const id = hash.slice(1)
55-
const anchorEl = document.getElementById(id)
56-
if (!anchorEl) return
52+
onBeforeUnmount(() => {
53+
window.removeEventListener('load', handleHashScroll);
54+
});
5755
58-
requestAnimationFrame(() => {
59-
window.scrollTo({ top: anchorEl.offsetTop - 88 })
60-
})
61-
})
62-
}
56+
// Watch
57+
watch(route, (newRoute) => {
58+
if (newRoute.meta) {
59+
document.title = newRoute.meta.documentTitle || 'TDesign';
6360
}
64-
}
61+
}, { immediate: true });
6562
</script>

site/src/pages/design/icon_zh-CN.vue

Lines changed: 49 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -199,12 +199,53 @@
199199
</div>
200200
</template>
201201

202-
<script>
203-
import AllIcons from '@/components/all-icons.vue'
204-
import anchorMixin from '../mixins/anchor'
205-
206-
export default {
207-
components: { AllIcons },
208-
mixins: [anchorMixin]
209-
}
202+
<script setup>
203+
import { ref, onMounted } from 'vue';
204+
import AllIcons from '@/components/all-icons.vue';
205+
206+
// Template refs
207+
const article = ref(null);
208+
209+
// Data (from mixin)
210+
const catalog = ref([]);
211+
212+
// Methods (from mixin)
213+
const genAnchor = () => {
214+
if (!article.value) return;
215+
const articleContent = article.value;
216+
const nodes = ['H2', 'H3'];
217+
const titles = [];
218+
articleContent.childNodes.forEach((e, index) => {
219+
if (nodes.includes(e.nodeName)) {
220+
const id = `header-${index}`;
221+
e.setAttribute('id', id);
222+
titles.push({
223+
id,
224+
title: e.innerHTML,
225+
level: Number(e.nodeName.substring(1, 2)),
226+
nodeName: e.nodeName,
227+
children: []
228+
});
229+
}
230+
});
231+
232+
const isEveryLevel3 = titles.every(t => t.level === 3);
233+
catalog.value = titles.reduce((acc, curr) => {
234+
if (isEveryLevel3) {
235+
acc.push(curr);
236+
} else {
237+
if (curr.level === 2) {
238+
acc.push(curr);
239+
} else if (curr.level === 3) {
240+
acc[acc.length - 1].children.push(curr);
241+
}
242+
}
243+
return acc;
244+
}, []);
245+
};
246+
247+
// Lifecycle hooks
248+
onMounted(() => {
249+
genAnchor();
250+
});
210251
</script>

0 commit comments

Comments
 (0)