style: css修改; fix: 详情页面显示 空字段修改,eslint修改

This commit is contained in:
jzp 2025-11-12 15:43:39 +08:00
parent 61d98f78b0
commit bb958ce2fe
24 changed files with 4699 additions and 133 deletions

7
components.d.ts vendored
View File

@ -1,8 +1,11 @@
/* eslint-disable */
// @ts-nocheck
// biome-ignore lint: disable
// oxlint-disable
// ------
// Generated by unplugin-vue-components
// Read more: https://github.com/vuejs/core/pull/3399
// biome-ignore lint: disable
export {}
/* prettier-ignore */
@ -20,6 +23,7 @@ declare module 'vue' {
VanNoticeBar: typeof import('vant/es')['NoticeBar']
VanPopover: typeof import('vant/es')['Popover']
VanPopup: typeof import('vant/es')['Popup']
VanRate: typeof import('vant/es')['Rate']
VanSearch: typeof import('vant/es')['Search']
VanStepper: typeof import('vant/es')['Stepper']
VanSwipe: typeof import('vant/es')['Swipe']
@ -27,5 +31,6 @@ declare module 'vue' {
VanSwitch: typeof import('vant/es')['Switch']
VanTab: typeof import('vant/es')['Tab']
VanTabs: typeof import('vant/es')['Tabs']
VanUploader: typeof import('vant/es')['Uploader']
}
}

15
env.d.ts vendored
View File

@ -1 +1,16 @@
/// <reference types="vite/client" />
declare module '*.vue' {
import type { Component } from 'vue'
const component: Component
export default component
}
declare module '*.css'
declare module '*.scss'
declare module '*.sass'
declare module '*.less'
declare module '*.png'
declare module '*.jpg'
declare module '*.jpeg'
declare module '*.svg'

View File

@ -2,31 +2,34 @@ import { globalIgnores } from 'eslint/config'
import { defineConfigWithVueTs, vueTsConfigs } from '@vue/eslint-config-typescript'
import pluginVue from 'eslint-plugin-vue'
import skipFormatting from '@vue/eslint-config-prettier/skip-formatting'
const path = require('path')
import path from 'node:path'
import { fileURLToPath } from 'node:url'
// To allow more languages other than `ts` in `.vue` files, uncomment the following lines:
// import { configureVueProject } from '@vue/eslint-config-typescript'
// configureVueProject({ scriptLangs: ['ts', 'tsx'] })
// More info at https://github.com/vuejs/eslint-config-typescript/#advanced-setup
const tsconfigRootDir = path.dirname(fileURLToPath(import.meta.url))
export default defineConfigWithVueTs(
{
name: 'app/files-to-lint',
files: ['**/*.{ts,mts,tsx,vue}'],
},
{
languageOptions: {
parserOptions: {
sconfigRootDir: path.resolve(__dirname),
project: './tsconfig.json',
requireConfigFile: false,
},
},
},
{ name: 'app/files-to-lint', files: ['**/*.{ts,mts,tsx,vue}'] },
globalIgnores(['**/dist/**', '**/dist-ssr/**', '**/coverage/**']),
pluginVue.configs['flat/essential'],
vueTsConfigs.recommended,
skipFormatting,
{
languageOptions: {
parserOptions: {
tsconfigRootDir,
project: ['./tsconfig.json'],
extraFileExtensions: ['.vue']
}
},
rules: {
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-empty-object-type': 'off',
'@typescript-eslint/no-unused-expressions': 'off',
'vue/multi-word-component-names': 'off'
}
},
)

View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<link rel="icon" href="/favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vite App</title>
<title></title>
</head>
<body>
<div id="app"></div>

4396
pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load Diff

46
src/api/types/shop.ts Normal file
View File

@ -0,0 +1,46 @@
export type PrDetailType = {
adminCategoryId1: 146
adminCategoryId2: 147
appCategoryId1: 48
appCategoryId2: 56
createTime: 1762760434000
defaultSort: 0
frontPage: 1
id: 73
isDelete: 0
isFlash: 0
isNew: 1
isTest: 0
mainImageUrl: 'https://heyuimage.ihzhy.com/prd/202511/9a77567562f87caf.jpg?key=xxxxxxx'
modifyTime: 1762760434000
realSaleCount: 0
showPromotionPrice: 0
showSaleCount: 0
showSalePrice: 0
status: 'online'
title: 'Akoya双珠海水戒指'
vvSkuList: SkuType[]
vvProductDetailList: []
vvProductPropertyList: []
}
export type SkuType = {
createTime: number
id: 364
isDelete: 0
modifyTime: 1762760434000
productId: 73
promotionPrice: 0
showSaleCount: 0
stock: 0
}
export type ProductDetailImagesType = {
createTime: 1762760434000
detail: 'https://heyuimage.ihzhy.com/prd/202511/304182481ebfc9ab.jpg?key=xxxxxxx'
id: 187
isDelete: 0
modifyTime: 1762760434000
productId: 73
type: 1
}

128
src/auto-import.d.ts vendored
View File

@ -6,70 +6,70 @@
// biome-ignore lint: disable
export {}
declare global {
const EffectScope: typeof import('vue')['EffectScope']
const computed: typeof import('vue')['computed']
const createApp: typeof import('vue')['createApp']
const customRef: typeof import('vue')['customRef']
const defineAsyncComponent: typeof import('vue')['defineAsyncComponent']
const defineComponent: typeof import('vue')['defineComponent']
const effectScope: typeof import('vue')['effectScope']
const getCurrentInstance: typeof import('vue')['getCurrentInstance']
const getCurrentScope: typeof import('vue')['getCurrentScope']
const getCurrentWatcher: typeof import('vue')['getCurrentWatcher']
const h: typeof import('vue')['h']
const inject: typeof import('vue')['inject']
const isProxy: typeof import('vue')['isProxy']
const isReactive: typeof import('vue')['isReactive']
const isReadonly: typeof import('vue')['isReadonly']
const isRef: typeof import('vue')['isRef']
const isShallow: typeof import('vue')['isShallow']
const markRaw: typeof import('vue')['markRaw']
const nextTick: typeof import('vue')['nextTick']
const onActivated: typeof import('vue')['onActivated']
const onBeforeMount: typeof import('vue')['onBeforeMount']
const onBeforeRouteLeave: typeof import('vue-router')['onBeforeRouteLeave']
const onBeforeRouteUpdate: typeof import('vue-router')['onBeforeRouteUpdate']
const onBeforeUnmount: typeof import('vue')['onBeforeUnmount']
const onBeforeUpdate: typeof import('vue')['onBeforeUpdate']
const onDeactivated: typeof import('vue')['onDeactivated']
const onErrorCaptured: typeof import('vue')['onErrorCaptured']
const onMounted: typeof import('vue')['onMounted']
const onRenderTracked: typeof import('vue')['onRenderTracked']
const onRenderTriggered: typeof import('vue')['onRenderTriggered']
const onScopeDispose: typeof import('vue')['onScopeDispose']
const onServerPrefetch: typeof import('vue')['onServerPrefetch']
const onUnmounted: typeof import('vue')['onUnmounted']
const onUpdated: typeof import('vue')['onUpdated']
const onWatcherCleanup: typeof import('vue')['onWatcherCleanup']
const provide: typeof import('vue')['provide']
const reactive: typeof import('vue')['reactive']
const readonly: typeof import('vue')['readonly']
const ref: typeof import('vue')['ref']
const resolveComponent: typeof import('vue')['resolveComponent']
const shallowReactive: typeof import('vue')['shallowReactive']
const shallowReadonly: typeof import('vue')['shallowReadonly']
const shallowRef: typeof import('vue')['shallowRef']
const showToast: typeof import('vant/es')['showToast']
const toRaw: typeof import('vue')['toRaw']
const toRef: typeof import('vue')['toRef']
const toRefs: typeof import('vue')['toRefs']
const toValue: typeof import('vue')['toValue']
const triggerRef: typeof import('vue')['triggerRef']
const unref: typeof import('vue')['unref']
const useAttrs: typeof import('vue')['useAttrs']
const useCssModule: typeof import('vue')['useCssModule']
const useCssVars: typeof import('vue')['useCssVars']
const useId: typeof import('vue')['useId']
const useLink: typeof import('vue-router')['useLink']
const useModel: typeof import('vue')['useModel']
const useRoute: typeof import('vue-router')['useRoute']
const useRouter: typeof import('vue-router')['useRouter']
const useSlots: typeof import('vue')['useSlots']
const useTemplateRef: typeof import('vue')['useTemplateRef']
const watch: typeof import('vue')['watch']
const watchEffect: typeof import('vue')['watchEffect']
const watchPostEffect: typeof import('vue')['watchPostEffect']
const watchSyncEffect: typeof import('vue')['watchSyncEffect']
const EffectScope: typeof import('vue').EffectScope
const computed: typeof import('vue').computed
const createApp: typeof import('vue').createApp
const customRef: typeof import('vue').customRef
const defineAsyncComponent: typeof import('vue').defineAsyncComponent
const defineComponent: typeof import('vue').defineComponent
const effectScope: typeof import('vue').effectScope
const getCurrentInstance: typeof import('vue').getCurrentInstance
const getCurrentScope: typeof import('vue').getCurrentScope
const getCurrentWatcher: typeof import('vue').getCurrentWatcher
const h: typeof import('vue').h
const inject: typeof import('vue').inject
const isProxy: typeof import('vue').isProxy
const isReactive: typeof import('vue').isReactive
const isReadonly: typeof import('vue').isReadonly
const isRef: typeof import('vue').isRef
const isShallow: typeof import('vue').isShallow
const markRaw: typeof import('vue').markRaw
const nextTick: typeof import('vue').nextTick
const onActivated: typeof import('vue').onActivated
const onBeforeMount: typeof import('vue').onBeforeMount
const onBeforeRouteLeave: typeof import('vue-router').onBeforeRouteLeave
const onBeforeRouteUpdate: typeof import('vue-router').onBeforeRouteUpdate
const onBeforeUnmount: typeof import('vue').onBeforeUnmount
const onBeforeUpdate: typeof import('vue').onBeforeUpdate
const onDeactivated: typeof import('vue').onDeactivated
const onErrorCaptured: typeof import('vue').onErrorCaptured
const onMounted: typeof import('vue').onMounted
const onRenderTracked: typeof import('vue').onRenderTracked
const onRenderTriggered: typeof import('vue').onRenderTriggered
const onScopeDispose: typeof import('vue').onScopeDispose
const onServerPrefetch: typeof import('vue').onServerPrefetch
const onUnmounted: typeof import('vue').onUnmounted
const onUpdated: typeof import('vue').onUpdated
const onWatcherCleanup: typeof import('vue').onWatcherCleanup
const provide: typeof import('vue').provide
const reactive: typeof import('vue').reactive
const readonly: typeof import('vue').readonly
const ref: typeof import('vue').ref
const resolveComponent: typeof import('vue').resolveComponent
const shallowReactive: typeof import('vue').shallowReactive
const shallowReadonly: typeof import('vue').shallowReadonly
const shallowRef: typeof import('vue').shallowRef
const showToast: typeof import('vant/es').showToast
const toRaw: typeof import('vue').toRaw
const toRef: typeof import('vue').toRef
const toRefs: typeof import('vue').toRefs
const toValue: typeof import('vue').toValue
const triggerRef: typeof import('vue').triggerRef
const unref: typeof import('vue').unref
const useAttrs: typeof import('vue').useAttrs
const useCssModule: typeof import('vue').useCssModule
const useCssVars: typeof import('vue').useCssVars
const useId: typeof import('vue').useId
const useLink: typeof import('vue-router').useLink
const useModel: typeof import('vue').useModel
const useRoute: typeof import('vue-router').useRoute
const useRouter: typeof import('vue-router').useRouter
const useSlots: typeof import('vue').useSlots
const useTemplateRef: typeof import('vue').useTemplateRef
const watch: typeof import('vue').watch
const watchEffect: typeof import('vue').watchEffect
const watchPostEffect: typeof import('vue').watchPostEffect
const watchSyncEffect: typeof import('vue').watchSyncEffect
}
// for type re-export
declare global {

View File

@ -0,0 +1,17 @@
import variables from "@/styles/variables.module.scss";
export const useDesign = () => {
const lessVariables = variables;
/**
* @param scope
* @returns -
*/
const getPrefixCls = (scope: string) => {
return `${lessVariables.namespace}-${scope}`;
};
return {
variables: lessVariables,
getPrefixCls,
};
};

View File

@ -12,6 +12,7 @@ import App from './App.vue'
import router from './router'
import GetUserInfo from './utils/getUserInfo'
import '@/styles/index.scss'
const app = createApp(App)
app.use(createPinia().use(piniaPluginPersistedstate))
@ -19,6 +20,8 @@ app.use(router)
app.mount('#app')
!location.host.startsWith('app') && new VConsole()
if (!location.host.startsWith('app')) {
new VConsole()
}
GetUserInfo.getInstance()

View File

@ -6,58 +6,85 @@ const router = createRouter({
{
path: '/demo',
name: 'demo',
meta: {
title: "测试入口"
},
// route level code-splitting
// this generates a separate chunk (About.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import('../views/demo/index.vue'),
component: () => import('@/views/demo/index.vue'),
},
{
path: '/commodity-detail',
name: 'commodity-detail',
meta: {
title: "商品详情",
section: "/commodity"
},
// route level code-splitting
// this generates a separate chunk (About.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import('../views/commodity-detail/index.vue'),
component: () => import('@/views/commodity-detail/index.vue'),
},
{
path: '/order',
name: 'order',
meta: {
title: "我的订单",
section: "/order"
},
// route level code-splitting
// this generates a separate chunk (About.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import('../views/order/index.vue'),
component: () => import('@/views/order/index.vue'),
},
{
path: '/order/detail',
name: 'order/detail',
meta: {
title: "订单详情",
section: "/order"
},
// route level code-splitting
// this generates a separate chunk (About.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import('../views/order/detail.vue'),
component: () => import('@/views/order/detail.vue'),
},
{
path: '/search-container',
name: 'search-container',
meta: {
title: "搜索",
section: "/search"
},
// route level code-splitting
// this generates a separate chunk (About.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import('../views/search-container/index.vue'),
component: () => import('@/views/search-container/index.vue'),
},
{
path: '/review/center',
name: 'review/center',
meta: {
title: "评价中心",
section: "/review"
},
// route level code-splitting
// this generates a separate chunk (About.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import('../views/review/center.vue'),
component: () => import('@/views/review/center.vue'),
},
{
path: '/review/write',
name: 'review/write',
meta: {
title: "填写评价",
section: "/review"
},
// route level code-splitting
// this generates a separate chunk (About.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import('../views/review/write.vue'),
component: () => import('@/views/review/write.vue'),
},
],
})

0
src/styles/app.scss Normal file
View File

0
src/styles/color.scss Normal file
View File

0
src/styles/common.scss Normal file
View File

1
src/styles/index.scss Normal file
View File

@ -0,0 +1 @@
@import './var.scss'

4
src/styles/var.scss Normal file
View File

@ -0,0 +1,4 @@
:root{
--app-footer-bg-height: 40px;
--app-footer-bg-color: #fff;
}

View File

@ -0,0 +1,12 @@
// 命名空间
$namespace: v;
// el命名空间
$elNamespace: vant;
// 主色调
$colorPrimary: #3e7bfb;
:export {
namespace: #{$namespace};
elNamespace: #{$elNamespace};
}

View File

@ -5,8 +5,8 @@
<div class="mb-8">
<div class="cart-wrap">
<p class="flex justify-between" @click="showAddressList = true">
<van-icon name="location-o" class="mr-1" /><span class="max-w-12 mr-1">{{ curAddressData.buyerName }}</span>
<b class="font- flex-1">{{ curAddressData.province + curAddressData.city + curAddressData.district + curAddressData.detail }}</b
<van-icon name="location-o" class="mr-1" /><span class="max-w-12 mr-1">{{ curAddressData?.buyerName }}</span>
<b class="font- flex-1">{{ (curAddressData?.province ?? '') + (curAddressData?.city ?? '') + (curAddressData?.district ?? '') + (curAddressData?.detail?? '') }}</b
><van-icon name="arrow" />
</p>
</div>
@ -15,7 +15,7 @@
<img class="w-16 h-16 mr-4" style="border-radius: 0.04rem" :src="curPageData.imageUrl" alt="" />
<div>
<p>
¥<span>{{ curPageData.price }}</span>
¥<span>{{ curPageData?.price }}</span>
</p>
<p>
<van-stepper v-model="formData.num" input-width=".4rem" button-size=".2rem" min="1" :max="curPageData.num" />
@ -27,12 +27,12 @@
<h4>{{ key }}</h4>
<div class="cagetory">
<p
v-for="item in arr"
:key="item.propertyId"
:class="{ 'theme-border-color theme-color': item.propertyId === curPropertyIds.find((it) => it.productPropertyName === key).id }"
@click="onChooseProperty(item, key)"
v-for="v in arr"
:key="v.propertyId"
:class="{ 'theme-border-color theme-color': v.propertyId === curPropertyIds.find((it) => it.productPropertyName === key).id }"
@click="onChooseProperty(v, key)"
>
{{ item.label }}
{{ v?.label }}
</p>
</div>
</template>
@ -52,12 +52,12 @@ import { requestPayment } from '@/utils/wx-minprogram'
const model = defineModel<boolean>()
const showAddressList = defineModel<boolean>('showAddressList')
const props = defineProps<{ list: any[]; curAddressData: Recordable<any>; scene: 'order' | 'cart' }>()
const skuData = ref({}) // skukeyvalue{ : [{ ''}]}
const commodityData = ref({}) // valueskuId(keyid)
const curPropertyIds = ref([]) // id[{ id: 1, name: ''},{id: 2, name: ''}] name
const curPageData = ref({ price: '', imageUrl: '', num: 0 }) //
const formData = ref({ skuId: NaN, num: 1 })
const props = defineProps<{ list: Array<any>; curAddressData: Recordable<any>; scene: 'order' | 'cart' }>()
const skuData = ref<any>({}) // skukeyvalue{ : [{ ''}]}
const commodityData = ref<any>({}) // valueskuId(keyid)
const curPropertyIds = ref<any>([]) // id[{ id: 1, name: ''},{id: 2, name: ''}] name
const curPageData = ref<any>({ price: '', imageUrl: '', num: 0 }) //
const formData = ref<any>({ skuId: NaN, num: 1 })
watch(model, (val) => {
if (val) {
@ -93,15 +93,15 @@ const handleGetSkuList = (list: any[]) => {
return { result, commodityMap, firstShopIds }
}
const onChooseProperty = (item, categoryName) => {
curPropertyIds.value.find((it) => it.productPropertyName === categoryName).id = item.propertyId
const onChooseProperty = (v, categoryName) => {
curPropertyIds.value.find((it) => it.productPropertyName === categoryName).id = v.propertyId
const { pageData, skuId } = handleGetPageData(commodityData.value, curPropertyIds.value)
curPageData.value = pageData
formData.value = { skuId, num: 1 }
}
const handleGetPageData = (commodityData, curPropertyIds) => {
const data = commodityData[curPropertyIds.map((item) => item.id).join('_')]
return { pageData: { price: data.price, imageUrl: data.imageUrl, num: data.num }, skuId: data.id }
return { pageData: { price: data?.price, imageUrl: data?.imageUrl, num: data?.num }, skuId: data?.id }
}
const onSubmit = async () => {

View File

@ -1,5 +1,5 @@
<template>
<div id="commodity-detail">
<div id="commodity-detail" :class="[prefixCls]">
<header class="h-70 bg-[#aaa]">
<van-swipe class="my-swipe" :autoplay="3000" indicator-color="white">
<van-swipe-item><img class="h-full w-full" :src="detail.mainImg" alt="" /></van-swipe-item>
@ -25,7 +25,7 @@
<b>用户评价({{ reviews.length }}+)</b><span @click="onShowAllReview">全部评价 ></span>
</h3>
<div class="mt-5">
<review-single :data="reviews[0]" />
<review-single v-if="reviews.length > 0" :data="reviews[0]" />
</div>
</div>
<div class="wrap">
@ -44,7 +44,7 @@
<instruction-info class="mt3" />
</div>
</main>
<footer class="flex fixed bottom-0 left-0 w-full h-10 justify-between items-center pr-2 box-border bg-white">
<footer class="flex fixed bottom-0 left-0 w-full h-[--app-footer-bg-height] justify-between items-center pr-2 box-border bg-[var(--app-footer-bg-color)]">
<div class="flex items-center w-[1.4rem] justify-around">
<p class="icon-wrap">
<van-icon name="phone-o" size=".14rem" />
@ -83,11 +83,17 @@
import api from '@/api'
import allReview from './components/all-review.vue'
import reviewSingle from './components/review-single.vue'
import infoTable from './components/info-table.vue'
// import infoTable from './components/info-table.vue'
import instructionInfo from './components/instruction-info.vue'
import shoppingCart from './components/shopping-cart.vue'
import shoppingCart from './components/shopping-cart.vue'
import addressList from './components/address-list.vue'
import addressForm from './components/address-form.vue'
import { useDesign } from '@/hooks/web/useDesign.ts'
const { getPrefixCls } = useDesign()
const prefixCls = getPrefixCls("commodity-detail")
const detail = reactive({
mainImg: '',
@ -97,15 +103,15 @@ const detail = reactive({
title: '',
})
const showShopCart = ref(false) //
const showShopCart = ref<boolean>(false) //
const cartType = ref<'order' | 'cart'>('order')
const showAllReview = ref(false) //
const showAddressList = ref(false) //
const showAddAddressFormDialog = ref(false) // form
const showAllReview = ref<boolean>(false) //
const showAddressList = ref<boolean>(false) //
const showAddAddressFormDialog = ref<boolean>(false) // form
const addressFormType = ref<'add' | 'edit'>('add')
const isUpDateAddressList = ref(false) //
const editAddressData = ref({}) //
const curAddressData = ref({}) //
const isUpDateAddressList = ref<boolean>(false) //
const editAddressData = ref<any>({}) //
const curAddressData = ref<any>({}) //
const route = useRoute()
const init = () => {
@ -137,6 +143,8 @@ const skuList = ref([])
//
const handleGetCommodityDetail = (productId: number) => {
api.shop.getCommodityDetail.post<any>({ productId }).then((res) => {
detail.mainImg = res.data.mainImageUrl
detail.video = res.data.videoUrl
detail.subImgs = res.data.vvProductDetailList.filter((item) => item.type === 1)?.map((item) => item.detail)
@ -155,6 +163,12 @@ init()
</script>
<style scope lang="scss">
$prefix-cls: #{$namespace}-commodity-detail;
.#{$prefix-cls} {
padding-bottom: calc(var(--app-footer-bg-height) + 10px);
}
#commodity-detail {
background: #f2f2f2;
.my-swipe {

View File

@ -57,6 +57,7 @@ const orderDetail = ref({
#order-detail {
.product-name {
display: -webkit-box;
line-clamp: 1;
-webkit-line-clamp: 1;
-webkit-box-orient: vertical;
overflow: hidden;

View File

@ -1,6 +1,6 @@
{
"extends": "@vue/tsconfig/tsconfig.dom.json",
"include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
"include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"],
"exclude": ["src/**/__tests__/*"],
"compilerOptions": {
"strict": false,

View File

@ -1,11 +1,23 @@
{
"files": [],
"references": [
{
"path": "./tsconfig.node.json"
},
{
"path": "./tsconfig.app.json"
"extends": "@vue/tsconfig/tsconfig.dom.json",
"include": [
"env.d.ts",
"types/**/*.d.ts",
"src/**/*.ts",
"src/**/*.tsx",
"src/**/*.vue",
"vite.config.ts",
"vitest.config.ts",
"eslint.config.ts"
],
"exclude": ["src/**/__tests__/*"],
"compilerOptions": {
"strict": false,
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
"typeRoots": ["./node_modules/@types", "./types"],
"paths": {
"@/*": ["./src/*"],
"#/*": ["./types/*"]
}
}
]
}

View File

@ -9,7 +9,6 @@
"strict": false,
"moduleResolution": "Bundler",
"types": ["node"],
"baseUrl": "./",
"paths": {
"@/*": ["src/*"],
"#/*": ["types/*"]

View File

@ -6,7 +6,7 @@ import vue from '@vitejs/plugin-vue'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { VantResolver } from '@vant/auto-import-resolver'
import vueDevTools from 'vite-plugin-vue-devtools'
// import vueDevTools from 'vite-plugin-vue-devtools'
// https://vite.dev/config/
export default defineConfig({
@ -45,7 +45,18 @@ export default defineConfig({
css: {
preprocessorOptions: {
scss: {
additionalData: `@use "@/assets/variables.scss" as *;`,
additionalData: (source, fp) => {
const id = String(fp).replace(/\\/g, '/'); // 兼容 Windows 路径
// 避免给自身注入,尤其是 tokens/variables 文件本体
if (
id.endsWith('/assets/variables.scss') ||
id.endsWith('/styles/variables.module.scss')
) {
return source;
}
// 只注入纯 Sass 变量文件(不要注入 .module.scss
return `@use "@/assets/variables.scss" as *; @use "@/styles/variables.module.scss" as *; ${source}`;
},
},
},
},