简体中文 繁體中文 English 日本語 Deutsch 한국 사람 بالعربية TÜRKÇE português คนไทย Français

站内搜索

搜索

活动公告

11-02 12:46
10-23 09:32
通知:本站资源由网友上传分享,如有违规等问题请到版务模块进行投诉,将及时处理!
10-23 09:31
10-23 09:28
通知:签到时间调整为每日4:00(东八区)
10-23 09:26

Vue.js全面拥抱TypeScript支持为前端开发带来类型安全新体验

3万

主题

423

科技点

3万

积分

大区版主

木柜子打湿

积分
31916

三倍冰淇淋无人之境【一阶】财Doro小樱(小丑装)立华奏以外的星空【二阶】⑨的冰沙

发表于 2025-9-30 02:50:02 | 显示全部楼层 |阅读模式 [标记阅至此楼]

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
1. 引言:Vue.js与TypeScript的完美结合

Vue.js作为一款流行的前端框架,以其简洁的API、灵活的组件系统和强大的功能赢得了广大开发者的喜爱。而TypeScript作为JavaScript的超集,通过添加静态类型定义,大大提高了代码的可维护性和可读性。Vue.js对TypeScript的全面支持,为前端开发带来了类型安全的新体验,使得开发者能够构建更加健壮、可维护的应用程序。

2. Vue.js对TypeScript支持的演进历程

2.1 早期支持

在Vue.js 2.x版本中,对TypeScript的支持相对有限。开发者需要借助vue-class-component和vue-property-decorator等库来使用TypeScript,这种基于装饰器的语法虽然能够提供类型支持,但与Vue的Options API风格存在一定的差异。
  1. import { Vue, Component } from 'vue-property-decorator'
  2. @Component
  3. export default class MyComponent extends Vue {
  4.   // 数据
  5.   message: string = 'Hello, TypeScript!'
  6.   
  7.   // 计算属性
  8.   get reversedMessage(): string {
  9.     return this.message.split('').reverse().join('')
  10.   }
  11.   
  12.   // 方法
  13.   greet(): void {
  14.     alert(`Message: ${this.message}`)
  15.   }
  16. }
复制代码

2.2 Vue 3的重大改进

Vue 3的发布标志着对TypeScript支持的全面提升。新版本使用TypeScript重写了核心库,提供了更好的类型推断和IDE支持。同时,引入了Composition API,使得TypeScript与Vue的结合更加自然和流畅。
  1. import { defineComponent, ref, computed } from 'vue'
  2. export default defineComponent({
  3.   setup() {
  4.     const message = ref<string>('Hello, TypeScript!')
  5.    
  6.     const reversedMessage = computed<string>(() => {
  7.       return message.value.split('').reverse().join('')
  8.     })
  9.    
  10.     function greet(): void {
  11.       alert(`Message: ${message.value}`)
  12.     }
  13.    
  14.     return {
  15.       message,
  16.       reversedMessage,
  17.       greet
  18.     }
  19.   }
  20. })
复制代码

2.3<script setup>语法糖

Vue 3.2引入了<script setup>语法糖,进一步简化了TypeScript在Vue组件中的使用:
  1. <script setup lang="ts">
  2. import { ref, computed } from 'vue'
  3. const message = ref<string>('Hello, TypeScript!')
  4. const reversedMessage = computed<string>(() => {
  5.   return message.value.split('').reverse().join('')
  6. })
  7. function greet(): void {
  8.   alert(`Message: ${message.value}`)
  9. }
  10. </script>
复制代码

3. 在Vue.js项目中集成TypeScript

3.1 创建支持TypeScript的Vue项目

使用Vue CLI或Vite创建支持TypeScript的Vue项目非常简单:
  1. # 安装Vue CLI
  2. npm install -g @vue/cli
  3. # 创建新项目,选择Manually select features,然后选择TypeScript
  4. vue create my-vue-ts-project
复制代码
  1. # 使用Vite创建Vue + TypeScript项目
  2. npm create vite@latest my-vue-ts-project -- --template vue-ts
复制代码

3.2 配置TypeScript

项目创建后,会有一个tsconfig.json文件,用于配置TypeScript编译选项:
  1. {
  2.   "compilerOptions": {
  3.     "target": "esnext",
  4.     "useDefineForClassFields": true,
  5.     "module": "esnext",
  6.     "moduleResolution": "node",
  7.     "strict": true,
  8.     "jsx": "preserve",
  9.     "sourceMap": true,
  10.     "resolveJsonModule": true,
  11.     "isolatedModules": true,
  12.     "esModuleInterop": true,
  13.     "lib": ["esnext", "dom"],
  14.     "skipLibCheck": true
  15.   },
  16.   "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
  17.   "references": [{ "path": "./tsconfig.node.json" }]
  18. }
复制代码

3.3 类型声明文件

为了让TypeScript能够正确识别.vue文件,需要创建类型声明文件shims-vue.d.ts:
  1. declare module '*.vue' {
  2.   import type { DefineComponent } from 'vue'
  3.   const component: DefineComponent<{}, {}, any>
  4.   export default component
  5. }
复制代码

4. TypeScript在Vue.js中的具体应用场景

4.1 组件Props的类型定义

在Vue 3中,可以使用defineProps宏来定义props的类型:
  1. <script setup lang="ts">
  2. interface Props {
  3.   title: string
  4.   count?: number
  5.   isActive?: boolean
  6.   user?: {
  7.     id: number
  8.     name: string
  9.   }
  10. }
  11. const props = withDefaults(defineProps<Props>(), {
  12.   count: 0,
  13.   isActive: false
  14. })
  15. </script>
复制代码

或者使用运行时声明:
  1. <script setup lang="ts">
  2. const props = defineProps({
  3.   title: {
  4.     type: String,
  5.     required: true
  6.   },
  7.   count: {
  8.     type: Number,
  9.     default: 0
  10.   },
  11.   isActive: {
  12.     type: Boolean,
  13.     default: false
  14.   },
  15.   user: {
  16.     type: Object as () => { id: number; name: string },
  17.     default: null
  18.   }
  19. })
  20. </script>
复制代码

4.2 组件Emits的类型定义

使用defineEmits宏来定义emits的类型:
  1. <script setup lang="ts">
  2. // 基于事件的类型
  3. const emit = defineEmits<{
  4.   (e: 'change', id: number): void
  5.   (e: 'update', value: string): void
  6. }>()
  7. // 或者使用更简洁的语法
  8. const emit = defineEmits(['change', 'update'])
  9. function handleChange() {
  10.   emit('change', 1)
  11.   emit('update', 'new value')
  12. }
  13. </script>
复制代码

4.3 Ref和Reactive的类型定义

使用ref和reactive时,可以显式指定类型或让TypeScript自动推断:
  1. <script setup lang="ts">
  2. import { ref, reactive } from 'vue'
  3. // 显式指定类型
  4. const count = ref<number>(0)
  5. const message = ref<string>('Hello')
  6. // 自动推断类型
  7. const name = ref('Vue') // 自动推断为Ref<string>
  8. // reactive对象的类型定义
  9. interface User {
  10.   id: number
  11.   name: string
  12.   email?: string
  13. }
  14. const user = reactive<User>({
  15.   id: 1,
  16.   name: 'John Doe'
  17. })
  18. // 嵌套reactive对象
  19. const state = reactive({
  20.   user: {
  21.     id: 1,
  22.     name: 'John'
  23.   } as User,
  24.   settings: {
  25.     theme: 'dark',
  26.     notifications: true
  27.   }
  28. })
  29. </script>
复制代码

4.4 计算属性的类型定义

计算属性可以显式指定返回类型,也可以让TypeScript自动推断:
  1. <script setup lang="ts">
  2. import { ref, computed } from 'vue'
  3. const firstName = ref<string>('John')
  4. const lastName = ref<string>('Doe')
  5. // 显式指定返回类型
  6. const fullName = computed<string>(() => {
  7.   return `${firstName.value} ${lastName.value}`
  8. })
  9. // 自动推断返回类型
  10. const greeting = computed(() => {
  11.   return `Hello, ${firstName.value}!`
  12. })
  13. </script>
复制代码

4.5 生命周期钩子的类型定义

Vue 3的生命周期钩子已经内置了类型定义,可以直接使用:
  1. <script setup lang="ts">
  2. import { onMounted, onUpdated, onUnmounted } from 'vue'
  3. onMounted(() => {
  4.   console.log('Component is mounted')
  5. })
  6. onUpdated(() => {
  7.   console.log('Component is updated')
  8. })
  9. onUnmounted(() => {
  10.   console.log('Component is unmounted')
  11. })
  12. </script>
复制代码

4.6 自定义组合式函数的类型定义

创建自定义组合式函数时,可以充分利用TypeScript的类型系统:
  1. // useCounter.ts
  2. import { ref, computed } from 'vue'
  3. export function useCounter(initialValue: number = 0) {
  4.   const count = ref<number>(initialValue)
  5.   
  6.   const increment = (): void => {
  7.     count.value++
  8.   }
  9.   
  10.   const decrement = (): void => {
  11.     count.value--
  12.   }
  13.   
  14.   const reset = (): void => {
  15.     count.value = initialValue
  16.   }
  17.   
  18.   const double = computed<number>(() => count.value * 2)
  19.   
  20.   return {
  21.     count,
  22.     increment,
  23.     decrement,
  24.     reset,
  25.     double
  26.   }
  27. }
复制代码

然后在组件中使用:
  1. <script setup lang="ts">
  2. import { useCounter } from './useCounter'
  3. const { count, increment, decrement, reset, double } = useCounter(10)
  4. </script>
复制代码

4.7 Vuex/Pinia的类型定义

对于状态管理,TypeScript提供了强大的类型支持。以Pinia为例:
  1. // stores/counter.ts
  2. import { defineStore } from 'pinia'
  3. export const useCounterStore = defineStore('counter', {
  4.   state: () => ({
  5.     count: 0,
  6.     name: 'Counter'
  7.   }),
  8.   getters: {
  9.     doubleCount: (state) => state.count * 2,
  10.     // 使用this访问其他getters
  11.     doublePlusOne(): number {
  12.       return this.doubleCount + 1
  13.     }
  14.   },
  15.   actions: {
  16.     increment() {
  17.       this.count++
  18.     },
  19.     reset() {
  20.       this.count = 0
  21.     }
  22.   }
  23. })
复制代码

或者使用更TypeScript友好的setup语法:
  1. // stores/counter.ts
  2. import { defineStore } from 'pinia'
  3. import { ref, computed } from 'vue'
  4. export const useCounterStore = defineStore('counter', () => {
  5.   const count = ref<number>(0)
  6.   const name = ref<string>('Counter')
  7.   
  8.   const doubleCount = computed<number>(() => count.value * 2)
  9.   const doublePlusOne = computed<number>(() => doubleCount.value + 1)
  10.   
  11.   function increment(): void {
  12.     count.value++
  13.   }
  14.   
  15.   function reset(): void {
  16.     count.value = 0
  17.   }
  18.   
  19.   return { count, name, doubleCount, doublePlusOne, increment, reset }
  20. })
复制代码

4.8 路由的类型定义

Vue Router也提供了完整的TypeScript支持:
  1. // router/index.ts
  2. import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'
  3. const routes: Array<RouteRecordRaw> = [
  4.   {
  5.     path: '/',
  6.     name: 'Home',
  7.     component: () => import('../views/Home.vue')
  8.   },
  9.   {
  10.     path: '/about',
  11.     name: 'About',
  12.     component: () => import('../views/About.vue')
  13.   },
  14.   {
  15.     path: '/user/:id',
  16.     name: 'User',
  17.     component: () => import('../views/User.vue'),
  18.     props: true
  19.   }
  20. ]
  21. const router = createRouter({
  22.   history: createWebHistory(),
  23.   routes
  24. })
  25. export default router
复制代码

在组件中使用路由:
  1. <script setup lang="ts">
  2. import { useRoute, useRouter } from 'vue-router'
  3. const route = useRoute()
  4. const router = useRouter()
  5. // 访问路由参数
  6. const userId = route.params.id as string
  7. // 导航到其他路由
  8. function navigateToUser(id: string): void {
  9.   router.push({ name: 'User', params: { id } })
  10. }
  11. </script>
复制代码

5. 类型安全带来的好处

5.1 减少运行时错误

TypeScript的静态类型检查可以在编译阶段捕获许多潜在的错误,而不是等到运行时才发现问题。例如:
  1. // 没有TypeScript的情况
  2. function add(a, b) {
  3.   return a + b
  4. }
  5. add('hello', 'world') // 返回'helloworld',可能不是期望的结果
  6. // 使用TypeScript
  7. function add(a: number, b: number): number {
  8.   return a + b
  9. }
  10. add('hello', 'world') // 编译时报错:类型'string'的参数不能赋给类型'number'的参数
复制代码

5.2 提高代码可维护性

类型定义使得代码更加自文档化,开发者可以更容易地理解代码的预期行为和数据结构:
  1. interface User {
  2.   id: number
  3.   name: string
  4.   email: string
  5.   age?: number
  6. }
  7. function displayUserInfo(user: User): void {
  8.   console.log(`ID: ${user.id}, Name: ${user.name}, Email: ${user.email}`)
  9.   if (user.age !== undefined) {
  10.     console.log(`Age: ${user.age}`)
  11.   }
  12. }
复制代码

5.3 增强IDE支持

TypeScript提供了更好的IDE支持,包括代码补全、类型提示、重构等功能,大大提高了开发效率:
  1. <script setup lang="ts">
  2. interface Product {
  3.   id: number
  4.   name: string
  5.   price: number
  6.   category: string
  7. }
  8. const product = ref<Product>({
  9.   id: 1,
  10.   name: 'Laptop',
  11.   price: 999.99,
  12.   category: 'Electronics'
  13. })
  14. // IDE会提供product.value的属性补全
  15. console.log(product.value.) // .id, .name, .price, .category
  16. </script>
复制代码

5.4 更好的重构体验

当需要重构代码时,TypeScript的类型系统可以帮助开发者识别所有受影响的地方:
  1. // 原始接口
  2. interface User {
  3.   id: number
  4.   name: string
  5.   email: string
  6. }
  7. // 重构后
  8. interface User {
  9.   id: number
  10.   firstName: string
  11.   lastName: string
  12.   email: string
  13. }
  14. // TypeScript会标记所有使用.name的地方,提示需要更新为.firstName和.lastName
复制代码

6. 实际项目中的最佳实践

6.1 使用严格的TypeScript配置

在tsconfig.json中启用严格的类型检查:
  1. {
  2.   "compilerOptions": {
  3.     "strict": true,
  4.     "noImplicitAny": true,
  5.     "strictNullChecks": true,
  6.     "strictFunctionTypes": true,
  7.     "strictBindCallApply": true,
  8.     "strictPropertyInitialization": true,
  9.     "noImplicitThis": true,
  10.     "alwaysStrict": true,
  11.     // 其他选项...
  12.   }
  13. }
复制代码

6.2 为组件Props定义清晰的接口
  1. <script setup lang="ts">
  2. interface Props {
  3.   title: string
  4.   items: Array<{
  5.     id: number
  6.     name: string
  7.     description?: string
  8.   }>
  9.   loading?: boolean
  10.   onItemClick?: (item: { id: number; name: string }) => void
  11. }
  12. const props = withDefaults(defineProps<Props>(), {
  13.   loading: false
  14. })
  15. </script>
复制代码

6.3 使用泛型提高代码复用性
  1. // utils/useApi.ts
  2. import { ref } from 'vue'
  3. export function useApi<T>(url: string) {
  4.   const data = ref<T | null>(null)
  5.   const error = ref<string | null>(null)
  6.   const loading = ref<boolean>(false)
  7.   async function fetch(): Promise<void> {
  8.     loading.value = true
  9.     try {
  10.       const response = await fetch(url)
  11.       data.value = await response.json() as T
  12.     } catch (err) {
  13.       error.value = err instanceof Error ? err.message : 'Unknown error'
  14.     } finally {
  15.       loading.value = false
  16.     }
  17.   }
  18.   return { data, error, loading, fetch }
  19. }
  20. // 在组件中使用
  21. interface User {
  22.   id: number
  23.   name: string
  24.   email: string
  25. }
  26. const { data, error, loading, fetch } = useApi<User[]>('/api/users')
复制代码

6.4 使用工具类型简化类型定义

TypeScript提供了许多实用的工具类型,如Partial、Pick、Omit等:
  1. interface User {
  2.   id: number
  3.   name: string
  4.   email: string
  5.   age: number
  6.   address: {
  7.     street: string
  8.     city: string
  9.     country: string
  10.   }
  11. }
  12. // 使用Partial创建所有属性都是可选的类型
  13. type UserUpdate = Partial<User>
  14. // 使用Pick选择特定属性
  15. type UserSummary = Pick<User, 'id' | 'name' | 'email'>
  16. // 使用Omit排除特定属性
  17. type UserWithoutAddress = Omit<User, 'address'>
  18. // 使用Record创建键值对类型
  19. type UserDictionary = Record<number, User>
复制代码

6.5 为API响应定义类型
  1. // types/api.ts
  2. export interface ApiResponse<T> {
  3.   data: T
  4.   success: boolean
  5.   message?: string
  6.   errors?: string[]
  7. }
  8. export interface PaginatedResponse<T> {
  9.   items: T[]
  10.   total: number
  11.   page: number
  12.   pageSize: number
  13.   totalPages: number
  14. }
  15. // 使用示例
  16. interface User {
  17.   id: number
  18.   name: string
  19.   email: string
  20. }
  21. async function fetchUsers(): Promise<ApiResponse<PaginatedResponse<User>>> {
  22.   const response = await fetch('/api/users')
  23.   return response.json()
  24. }
复制代码

6.6 使用类型守卫缩小类型范围
  1. // 类型守卫函数
  2. function isUser(obj: any): obj is User {
  3.   return typeof obj.id === 'number' &&
  4.          typeof obj.name === 'string' &&
  5.          typeof obj.email === 'string'
  6. }
  7. // 使用类型守卫
  8. function processUserData(data: unknown): void {
  9.   if (isUser(data)) {
  10.     // 在这个块中,TypeScript知道data是User类型
  11.     console.log(`User: ${data.name}, Email: ${data.email}`)
  12.   } else {
  13.     console.error('Invalid user data')
  14.   }
  15. }
复制代码

6.7 使用枚举或联合类型替代魔法字符串
  1. // 使用枚举
  2. enum UserRole {
  3.   ADMIN = 'admin',
  4.   EDITOR = 'editor',
  5.   VIEWER = 'viewer'
  6. }
  7. interface User {
  8.   id: number
  9.   name: string
  10.   role: UserRole
  11. }
  12. // 使用联合类型
  13. type Status = 'pending' | 'processing' | 'completed' | 'failed'
  14. interface Task {
  15.   id: number
  16.   title: string
  17.   status: Status
  18. }
复制代码

7. 常见问题与解决方案

7.1 处理第三方库的类型问题

对于没有内置TypeScript支持的第三方库,可以通过以下方式解决:

许多流行的库都有对应的类型声明包,通常以@types/开头:
  1. npm install --save-dev @types/lodash @types/moment
复制代码

如果没有现成的类型声明包,可以创建自己的类型声明文件:
  1. // src/types/third-party-library.d.ts
  2. declare module 'third-party-library' {
  3.   export function doSomething(input: string): number
  4.   export interface Options {
  5.     enabled?: boolean
  6.     maxItems?: number
  7.   }
  8.   export function configure(options: Options): void
  9. }
复制代码

7.2 处理Vue模板中的类型问题

在Vue模板中,TypeScript的类型检查可能会受到限制。可以使用以下方法增强类型安全:
  1. <template>
  2.   <!-- 这样会有类型检查 -->
  3.   <MyComponent :title="pageTitle" :items="userList" />
  4.   
  5.   <!-- 这样没有类型检查 -->
  6.   <MyComponent title="Page Title" items="[]" />
  7. </template>
  8. <script setup lang="ts">
  9. import { ref } from 'vue'
  10. import MyComponent from './MyComponent.vue'
  11. const pageTitle = ref<string>('Home Page')
  12. const userList = ref<Array<{id: number, name: string}>>([])
  13. </script>
复制代码
  1. <template>
  2.   <input ref="inputRef" type="text">
  3. </template>
  4. <script setup lang="ts">
  5. import { ref, onMounted } from 'vue'
  6. const inputRef = ref<HTMLInputElement | null>(null)
  7. onMounted(() => {
  8.   if (inputRef.value) {
  9.     inputRef.value.focus()
  10.   }
  11. })
  12. </script>
复制代码

7.3 处理异步操作和Promise的类型

处理异步操作时,正确使用Promise的类型可以避免许多问题:
  1. // 定义API函数的返回类型
  2. async function fetchUser(id: number): Promise<User> {
  3.   const response = await fetch(`/api/users/${id}`)
  4.   if (!response.ok) {
  5.     throw new Error('Failed to fetch user')
  6.   }
  7.   return response.json()
  8. }
  9. // 使用async/await处理错误
  10. async function displayUser(id: number): Promise<void> {
  11.   try {
  12.     const user = await fetchUser(id)
  13.     console.log(`User: ${user.name}`)
  14.   } catch (error) {
  15.     console.error('Error fetching user:', error instanceof Error ? error.message : 'Unknown error')
  16.   }
  17. }
复制代码

7.4 处理事件处理函数的类型

为事件处理函数提供正确的类型定义:
  1. <template>
  2.   <input @input="handleInput" @change="handleChange" />
  3.   <button @click="handleClick">Click me</button>
  4. </template>
  5. <script setup lang="ts">
  6. function handleInput(event: Event): void {
  7.   const target = event.target as HTMLInputElement
  8.   console.log('Input value:', target.value)
  9. }
  10. function handleChange(event: Event): void {
  11.   const target = event.target as HTMLInputElement
  12.   console.log('Input changed:', target.value)
  13. }
  14. function handleClick(event: MouseEvent): void {
  15.   console.log('Button clicked at:', event.clientX, event.clientY)
  16. }
  17. </script>
复制代码

7.5 处理Vue组件的ref类型

使用模板引用时,正确指定组件类型:
  1. <template>
  2.   <MyComponent ref="myComponentRef" />
  3. </template>
  4. <script setup lang="ts">
  5. import { ref, onMounted } from 'vue'
  6. import MyComponent from './MyComponent.vue'
  7. // 使用InstanceType获取组件实例类型
  8. const myComponentRef = ref<InstanceType<typeof MyComponent> | null>(null)
  9. onMounted(() => {
  10.   if (myComponentRef.value) {
  11.     // 可以访问组件的方法和属性
  12.     myComponentRef.value.doSomething()
  13.   }
  14. })
  15. </script>
复制代码

8. 未来展望

8.1 Vue 3与TypeScript的深度融合

随着Vue 3的不断发展,我们可以预期Vue与TypeScript的融合将更加深入。Vue团队已经明确表示TypeScript是一等公民,未来的API设计和功能更新都会优先考虑TypeScript的支持。

8.2 更好的类型推断和IDE支持

未来的Vue版本可能会提供更强大的类型推断能力,减少显式类型注解的需要。同时,IDE支持也将不断改进,提供更好的开发体验。

8.3 工具链的改进

Vue CLI、Vite等工具链将继续改进对TypeScript的支持,提供更快的构建速度和更好的开发体验。

8.4 生态系统的发展

随着Vue与TypeScript的结合越来越紧密,我们可以预期整个生态系统(包括UI库、插件、工具等)都会提供更好的TypeScript支持。

9. 结论

Vue.js全面拥抱TypeScript支持为前端开发带来了类型安全的新体验。通过静态类型检查,开发者可以在编码阶段捕获潜在的错误,提高代码的可维护性和可读性。Vue 3的发布标志着对TypeScript支持的全面提升,从核心库的重写到Composition API的引入,再到<script setup>语法糖的推出,都使得TypeScript与Vue的结合更加自然和流畅。

在实际项目中,通过遵循最佳实践,如使用严格的TypeScript配置、为组件Props定义清晰的接口、使用泛型提高代码复用性、为API响应定义类型等,可以充分发挥TypeScript的优势,构建更加健壮、可维护的应用程序。

虽然在使用TypeScript的过程中可能会遇到一些挑战,如处理第三方库的类型问题、处理Vue模板中的类型问题等,但通过适当的解决方案,这些挑战都可以被克服。

随着Vue 3和TypeScript的不断发展,我们可以预期它们将更加深度融合,为前端开发带来更好的类型安全体验。作为开发者,我们应该积极拥抱这一趋势,在项目中充分利用TypeScript的优势,提高代码质量和开发效率。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

频道订阅

频道订阅

加入社群

加入社群

联系我们|TG频道|RSS

Powered by Pixtech

© 2025 Pixtech Team.