Vue3页面模板、样式、TS文件分离

前言

在Vue 3 + TypeScript项目中,将TypeScript相关的代码分离到单独的文件可以提高代码的可维护性和可复用性。

页面或组件的分离

模板

TestView.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
<template>
<div class="test_view_root">
{{ pageMsg }}
</div>
</template>

<script lang="ts" setup>
import { usePage } from "./TestView";

const { pageMsg } = usePage();
</script>

<style src="./TestView.less" lang="less" scoped></style>

TS

TestView.ts

1
2
3
4
5
6
7
8
9
10
11
12
import { ref, onMounted } from "vue";

export function usePage() {
const pageMsg = ref("TestView")

onMounted(() => {
console.info('onMounted', pageMsg.value)
})
return {
pageMsg
}
}

注意

下面的这种方式是不建议的,像onMounted是不会触发的。

在分离的TS中导出

1
2
3
4
5
export const dataList: TNews[] = reactive([])

onMounted(() => {

})

在页面中导入

1
2
3
import {
dataList
} from './NewsManager'

样式

TestView.less

1
2
.test_view_root {
}

setup语法糖

并不是所有的语法都能在分离的TS中写。

有部分 API 和语法通常是在 <script setup> 中使用,如

  • defineProps

  • defineEmits

  • defineModel

示例

defineProps:用来定义组件接收的 props,支持类型推导,让代码在 TypeScript 环境下类型更安全。

1
2
3
4
5
6
7
8
9
10
11
<template>
<div>{{ message }}</div>
</template>

<script setup lang="ts">
import { defineProps } from 'vue';

const props = defineProps({
message: { type: String, default: 'common' }
})
</script>

defineEmits:用于定义组件可以触发的自定义事件,同样支持类型检查。

1
2
3
4
5
6
7
8
9
10
11
<template>
<button @click="emit('customEvent', 'event data')">触发自定义事件</button>
</template>

<script setup lang="ts">
import { defineEmits } from 'vue';

const emit = defineEmits<{
(e: 'customEvent', data: string): void;
}>();
</script>

defineModel:该 API 用于在组件中创建双向数据绑定,允许子组件和父组件之间进行双向数据同步。

1
2
3
4
5
6
7
8
9
10
<template>
<input v-model="modelValue" />
</template>

<script setup lang="ts">
import { defineModel } from 'vue';

const model = defineModel<string>();
const modelValue = model.value;
</script>

怎样分离

模板

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<template>
<div>
<input v-model="modelValue" @input="handleChange($event.target.value)" />
</div>
</template>

<script lang="ts" setup>
import { defineModel } from 'vue';
import { usePage } from './modelLogic.ts';

// 使用 defineModel 创建双向绑定
const model = defineModel<string>();
const modelValue = model.value;

// 调用封装的逻辑函数
const { handleChange } = usePage(model);
</script>

分离的TS

1
2
3
4
5
6
7
8
9
10
11
12
13
import { Ref } from 'vue';

// 定义一个函数来封装与模型相关的逻辑
export function usePage(modelValue: Ref<string | undefined>) {
// 这里可以编写与 modelValue 相关的逻辑
const handleChange = (newValue: string) => {
modelValue.value = newValue;
};

return {
handleChange
};
}

工具类的分离

将一些通用的工具函数提取到单独的 .ts 文件中。

示例步骤

创建工具函数文件:例如,创建一个名为 utils.ts 的文件,定义一些工具函数。

1
2
3
4
// utils.ts
export function formatDate(date: Date): string {
return date.toLocaleDateString();
}

在组件中使用工具函数:在组件中引入并使用 formatDate 函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
<template>
<div>
<p>Formatted Date: {{ formattedDate }}</p>
</div>
</template>

<script lang="ts" setup>
import { ref } from 'vue';
import { formatDate } from './utils.ts';

const currentDate = ref(new Date());
const formattedDate = formatDate(currentDate.value);
</script>

通过以上方法,你可以将不同类型的TypeScript代码分离到单独的文件中,使代码结构更加清晰。