...
 
Commits (5)
    https://gitcode.net/qq_39019768/test_git/-/commit/92e2cd8865aefcf288e30d5514d25a0005cea035 vite 2023-03-15T09:14:59+08:00 wuyb@phxg.cn wyb123456 https://gitcode.net/qq_39019768/test_git/-/commit/fe94754e9a36d966c198381c5133699b8998d482 Merge branch 'master' of https://gitcode.net/qq_39019768/test_git 2023-03-15T09:18:44+08:00 wuyb@phxg.cn wyb123456 Conflicts: vite-demo/src/router/backRouter.js https://gitcode.net/qq_39019768/test_git/-/commit/426d9ae9e06736f21ddc4afe7e548aa1e9b40403 vite 路由 2023-03-15T19:13:45+08:00 wuyb@phxg.cn wyb123456 https://gitcode.net/qq_39019768/test_git/-/commit/8679ce0858beeb1dd7712fff2c3c0934f49358af vite 路由 2023-03-16T08:50:32+08:00 wuyb@phxg.cn wyb123456 https://gitcode.net/qq_39019768/test_git/-/commit/b07700a1fffbd39aa3b6169fc3afc5ed844f1f14 Merge branch 'master' of https://gitcode.net/qq_39019768/test_git 2023-03-16T08:53:32+08:00 wuyb@phxg.cn wyb123456 Conflicts: vite-demo/src/router/backRouter.js vite-demo/src/router/baseRouter.js vite-demo/src/store/modules/permission.js vite-demo/src/views/layout/sidebar/index.vue
......@@ -12,6 +12,7 @@
"axios": "^0.26.1",
"echarts": "^5.3.2",
"element-plus": "^2.2.12",
"file-saver": "^2.0.5",
"js-cookie": "^3.0.1",
"less": "^4.1.2",
"mavon-editor": "^2.10.4",
......@@ -22,8 +23,10 @@
"sass": "^1.50.0",
"scss": "^0.2.4",
"vue": "^3.2.25",
"vue-json-excel": "^0.3.0",
"vue-router": "^4.0.14",
"vuex": "^4.0.2"
"vuex": "^4.0.2",
"xlsx": "^0.17.0"
},
"devDependencies": {
"@types/node": "^18.15.3",
......
......@@ -24,6 +24,9 @@ app.component('ElDatePicker', ElDatePicker)
app.component('ElSelect', ElSelect)
app.component('ElInput', ElInput)
app.component('ElAlert', ElAlert)
// import JsonExcel from "vue-json-excel";
// app.component('downloadExcel',JsonExcel)
app.use(Antd)
app.use(router)
......
import axios from 'axios'
import Encrypt from 'utils/crypto'
import config from 'config/defaultSettings'
import httpErrorConfig from 'config/httpErrorConfig'
import Message from 'ant-design-vue/es/message'
import notification from 'ant-design-vue/es/notification'
// import { setErrorLog } from 'api/pubApi';
import { sessionClear, sessionRead, getDate, unzip } from 'utils/util'
import { resetRouter } from '@/router'
import store from '@/store'
/* const addErrorLog = errorInfo => {
setErrorLog(errorInfo).then(() => {});
}; */
class HttpRequest {
constructor() {
this.queue = {}
this.encrypt = new Encrypt()
this.key = ''
this.outLoginTimer = null
this.args = null // 未加密参数
this.argsOnSecret = null // 加密参数
// 来源平台和版本
this.platform = config.platform
this.version = config.version
// 初始化配置全局提示框
notification.config({
placement: 'bottomRight'
})
}
getInsideConfig() {
const config = {
// 请求头信息
headers: {
// 'Content-Type': 'application/json',
Accept: '*/*'
}
}
return config
}
destroy(option) {
delete this.queue[option.url]
}
interceptors(instance, options) {
// 请求拦截
instance.interceptors.request.use(
config => {
const { isToken, isEncrypt, otherToken, isRequestTip, isZip } = options
config.isRequestTip = isRequestTip
const token = store.getters.token
if (!token && isToken !== false) {
this.outLogin()
console.error('token不能为空')
return
}
// if (otherHeaders) {
// config.headers['Content-Type'] = 'application/x-www-form-urlencoded'
// }
// 请求头,拼接otherToken
if (otherToken) {
config.headers._OtherToken_ = otherToken
}
// 请求头,拼接token
if (isToken !== false) {
config.headers._ImpToken_ = token
}
// 控制后台返回参数是否压缩
if (isZip) {
config.headers._CompressType_ = 'gzip'
}
const currHours = getDate(new Date().getTime(), 'hours')
if (sessionRead(currHours) === currHours) {
delete config.headers._CompressType_
}
/**
* 拦截上行参数,加密
*/
// 生成key 加密传入后台
if (isEncrypt !== false && sessionRead(currHours) !== currHours) {
this.key = this.encrypt.rndStr(16)
const secretKey = this.encrypt.keyJsencrypt(this.key)
config.headers._secretKey_ = secretKey
}
// 加密上行参数
let params = config.data
if (params) {
params.platform = store.state.user.platform || this.platform
params.version = this.version
if (isEncrypt !== false && sessionRead(currHours) !== currHours) {
params = this.cloneParams(params)
}
config.data = params
this.argsOnSecret = params
}
this.queue[options.url] = true
return config
},
error => {
return Promise.reject(error)
}
)
// 响应拦截
instance.interceptors.response.use(
res => {
const { isRequestTip, isZip } = res.config
this.destroy(options)
// 拦截响应,弹出对应信息
const jsonData = res.data
if (
jsonData &&
jsonData.code &&
jsonData.code !== 200 &&
jsonData.code !== 430 &&
jsonData.code !== 4000 &&
isRequestTip !== false
) {
const codeLen = jsonData.code.length
const message = jsonData.message || jsonData.data.detail
// 新版本业务代码
if (codeLen === 6) {
if (Number(jsonData.code) > 0) {
// 业务成功
Message.info(message)
} else {
Message.warning(message)
}
} else {
// 老版本业务代码
if (
Number(jsonData.code) === 508 ||
Number(jsonData.code) === 401 ||
Number(jsonData.code) === 510 ||
Number(jsonData.code) === 607
) {
/*
* 508 TOKEN无效
* 401 访问未授权 跳转到登录页面
* 510 授权过期 跳转到登录页面
*/
notification.warning({
message: '警告',
description: Number(jsonData.code) === 607 ? `${jsonData.data.detail},3秒钟后退出系统!` : `${message},3秒钟后退出系统!`
})
if (this.outLoginTimer) {
clearTimeout(this.outLoginTimer)
}
this.outLoginTimer = setTimeout(() => {
this.outLogin()
}, 3000)
} else {
if (jsonData && jsonData.code && jsonData.code === 413 && isZip) {
// jsonData.data = JSON.parse(unzip(jsonData.data.gzip));
Message.info('操作失败')
// return false
} else {
Message.info(message)
}
}
}
}
const currHours = getDate(new Date().getTime(), 'hours')
if (jsonData && jsonData.code && jsonData.code === 200 && isZip && sessionRead(currHours) !== currHours) {
jsonData.data = JSON.parse(unzip(jsonData.data.gzip))
}
return jsonData
},
error => {
this.destroy(options)
const errorInfo = error.response
if (errorInfo) {
// 添加404错误日志
if (errorInfo.status === 404) {
/* const args = this.args;
const argsOnSecret = this.argsOnSecret;
const headers = errorInfo.headers;
const reqUrl = error.config.url;
const secretKey = error.config.headers._secretKey_;
const token = error.config.headers._ImpToken_;
const params = {
args: JSON.stringify(args),
argsOnSecret: JSON.stringify(argsOnSecret),
headers: JSON.stringify(headers),
reqUrl,
secretKey,
token
}; */
// addErrorLog(params);
}
// http请求错误弹窗显示
httpErrorConfig.content.content.forEach(item => {
if (item.code === errorInfo.status) {
notification.info({
message: '提示',
description: item.tip
})
}
})
} else {
console.error(error)
}
return Promise.reject(error)
}
)
}
request(options) {
// 请求配置
// if (process.env.NODE_ENV === 'development')
axios.defaults.timeout = 300000
const instance = axios.create()
options = Object.assign(this.getInsideConfig(), options)
this.interceptors(instance, options)
return instance(options)
}
// 上行参数 clone
cloneParams(params) {
this.args = params
const tempParams = JSON.parse(JSON.stringify(params))
return this.isArrayOrMap(tempParams)
}
// 判断数据对象是MAP还是ARRAY
isArrayOrMap(data) {
if (Object.prototype.toString.call(data) === '[object Array]') {
return this.dataArray(data)
} else if (Object.prototype.toString.call(data) === '[object Object]') {
return this.dataMap(data)
}
}
// MAP类型分解加密
dataMap(dataMap) {
for (const item in dataMap) {
if (Object.prototype.toString.call(dataMap[item]) === '[object Array]') {
this.dataArray(dataMap[item])
} else if (
Object.prototype.toString.call(dataMap[item]) === '[object Object]'
) {
this.dataMap(dataMap[item])
} else {
dataMap[item] =
dataMap[item] === null || dataMap[item] === undefined
? ''
: dataMap[item]
dataMap[item] = this.encrypt.encrypt(dataMap[item], this.key)
}
}
return dataMap
};
// ARRAY类型分解加密
dataArray(dataArray) {
for (let i = 0; i < dataArray.length; i++) {
if (Object.prototype.toString.call(dataArray[i]) === '[object Array]') {
this.dataArray(dataArray[i])
} else if (
Object.prototype.toString.call(dataArray[i]) === '[object Object]'
) {
this.dataMap(dataArray[i])
} else {
dataArray[i] =
dataArray[i] === null || dataArray[i] === undefined
? ''
: dataArray[i]
dataArray[i] = this.encrypt.encrypt(dataArray[i], this.key)
}
}
return dataArray
};
outLogin() {
window.location.hash = '#/user/login'
sessionClear()
resetRouter()
// 清空vuex中的路由
store.commit('CLRAR_ROUTERS')
};
}
export default HttpRequest
import axios from 'axios'
import type {AxiosInstance, AxiosRequestConfig, AxiosResponse} from 'axios'
import construct = Reflect.construct;
type baseType = string | number | boolean
type keyType = baseType | Array<baseType> | object
interface RandomKey {
[key: string]: keyType
}
interface dataObjAny {
[index: string]: RandomKey
}
export class Request {
instace: AxiosResponse
baseConfig: AxiosRequestConfig
construct(config: AxiosRequestConfig) {
this.instace = axios.create(Object.assign(this.baseConfig, config))
}
public request(url: string, data: dataObjAny, params: any): Promise<AxiosResponse> {
return new Promise((resolve, reject) => {
})
}
}
\ No newline at end of file
// https://juejin.cn/post/7113475007598034951
import axios from 'axios'
import type {AxiosInstance, AxiosRequestConfig, AxiosResponse} from 'axios'
console.log('axios', axios);
type Result<T> = {
code: number
message: string
result: T
}
export class Request {
// axios 实例
instance: AxiosInstance
// 基础配置 url和超市时间
baseConfig: AxiosRequestConfig = {
baseURL: '/api',
timeout: 60000
}
constructor(config: AxiosRequestConfig) {
this.instance = axios.create(Object.assign(this.baseConfig, config))
// 拦截器
this.instance.interceptors.response.use(
(config: AxiosRequestConfig) => {
// token as string 类型断言
const token = localStorage.getItem('token') as string
if (token) {
config.headers!.Authorization = token
}
return config
},
(err: any) => {
return Promise.reject(err)
}
)
// 响应
this.instance.interceptors.response.use(
(res: AxiosResponse) => {
return res.data
},
(err: any) => {
let message = ''
switch (err.response.status) {
case 400:
message = "参数有误(400)";
break;
case 401:
message = "未授权,请重新登录(401)";
// 这里可以做清空storage并跳转到登录页的操作
break;
case 403:
message = "拒绝访问(403)";
break;
case 404:
message = "请求出错(404)";
break;
case 408:
message = "请求超时(408)";
break;
case 500:
message = "服务器错误(500)";
break;
case 501:
message = "服务未实现(501)";
break;
case 502:
message = "网络错误(502)";
break;
case 503:
message = "服务不可用(503)";
break;
case 504:
message = "网络超时(504)";
break;
case 505:
message = "HTTP版本不受支持(505)";
break;
default:
message = `连接出错(${err.response.status})!`;
}
return Promise.reject(err.response)
}
)
}
// 请求方法
public request(config: AxiosRequestConfig): Promise<AxiosResponse> {
return this.instance.request(config)
}
public get<T = any>(url: string, config?: AxiosRequestConfig): Promise<AxiosResponse<Result<T>>> {
return this.instance.get(url, config)
}
public post<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<AxiosResponse<Result<T>>> {
return this.instance.post(url, data, config);
}
public put<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<AxiosResponse<Result<T>>> {
return this.instance.put(url, data, config);
}
public delete<T = any>(url: string, config?: AxiosRequestConfig): Promise<AxiosResponse<Result<T>>> {
return this.instance.delete(url, config);
}
}
export default new Request({})
\ No newline at end of file
import axios from 'axios'
import {message} from 'ant-design-vue'
import {
handleChangeRequestHeader,
handleConfigureAuth,
handleAuthError,
handleGeneralError,
handleNetworkError
} from './tools'
type Fn = (data: FcResponse<any>) => unknown
interface IAnyObj {
[index: string]: string
}
// 返回值
interface FcResponse<T> {
errno: string,
errmsg: string,
data: T
}
// 拦截
axios.interceptors.request.use((config) => {
config = handleChangeRequestHeader(config)
config = handleConfigureAuth(config)
return config
})
// 响应
axios.interceptors.response.use((response) => {
if (response.status != 200) return Promise.reject(response.data)
handleAuthError(response.data.errno)
handleGeneralError(response.data.errno, response.data.errmsg)
return response
}, (err) => {
handleNetworkError(err.response.status)
Promise.reject(err.response)
})
const get = <T>(url: string, params: IAnyObj = {}, clearFn?: Fn): Promise<[any, FcResponse<T> | undefined]> => {
return new Promise((resolve => {
axios.get(url, {params}).then((result) => {
let res: FcResponse<T>
if (clearFn != undefined) {
res = clearFn(result.data) as unknown as FcResponse<T>
} else {
res = result.data as FcResponse<T>
}
resolve([null, res as FcResponse<T>])
}).catch((err) => {
resolve([err, undefined])
})
}))
}
export const Post = <T, >(url: string, data: IAnyObj, params: IAnyObj = {}): Promise<[any, FcResponse<T> | undefined]> => {
return new Promise((resolve) => {
axios
.post(url, data, {params})
.then((result) => {
resolve([null, result.data as FcResponse<T>])
})
.catch((err) => {
resolve([err, undefined])
})
})
}
// header头上其他参数
export const handleRequestHeader = (config) => {
config['xxx'] = 'xxx'
return config
}
// 鉴权
export const handleAuth = (config) => {
config.header['token'] = localStorage.getItem('token')
return config
}
// 错误处理
export const handleNetworkError = (errStatus) => {
let errMessage = '未知错误'
if (errStatus) {
switch (errStatus) {
case 400:
errMessage = '错误的请求'
break
case 401:
errMessage = '未授权,请重新登录'
break
case 403:
errMessage = '拒绝访问'
break
case 404:
errMessage = '请求错误,未找到该资源'
break
case 405:
errMessage = '请求方法未允许'
break
case 408:
errMessage = '请求超时'
break
case 500:
errMessage = '服务器端出错'
break
case 501:
errMessage = '网络未实现'
break
case 502:
errMessage = '网络错误'
break
case 503:
errMessage = '服务不可用'
break
case 504:
errMessage = '网络超时'
break
case 505:
errMessage = 'http版本不支持该请求'
break
default:
errMessage = `其他连接错误 --${errStatus}`
}
} else {
errMessage = `无法连接到服务器!`
}
new Error(errMessage)
}
// 响应
export const handleAuthError = (errno) => {
const authErrMap: any = {
'10031': '登录失效,需要重新登录', // token 失效
'10032': '您太久没登录,请重新登录~', // token 过期
'10033': '账户未绑定角色,请联系管理员绑定角色',
'10034': '该用户未注册,请联系管理员注册用户',
'10035': 'code 无法获取对应第三方平台用户',
'10036': '该账户未关联员工,请联系管理员做关联',
'10037': '账号已无效',
'10038': '账号未找到',
}
if (authErrMap.hasOwnProperty(errno)) {
console.error(authErrMap[errno])
// 授权错误,登出账户
// logout()
return false
}
return true
}
export const handleGeneralError = (err, errmsg) => {
if (err.errno !== '0') {
console.error(err.errmsg)
return false
}
return true
}
// import { userApi } from "./path/user"
// import { shoporderApi } from "./path/shoporder"
let userApi
let shoporderApi
export const api = {
...userApi,
...shoporderApi
}
import {get} from "./api/server"
export function getUserInfo(id) {
get().then()
}
export function getUserName(id) {
}
// export const userApi = {
// getUserInfo,
// getUserName
// }
\ No newline at end of file
......@@ -76,7 +76,6 @@ const {visibile} = toRefs(state)
const setVisibil = (isVisibile) => {
state.visibile = isVisibile
}
const confirmBtnClick = () => {
......
<template>
<a-space direction="vertical" style="width: 100%">
<a-button @click="bindModalShow">新增</a-button>
<a-button @click="bindE">导出</a-button>
<a-table :columns="columns" :data-source="dataSource"
:rowKey="(row,index) => index">
<template #name="{ text }">{{ text }}</template>
......
<template>
<div>todoList</div>
<input type="text" v-model="text">
<button @click="add">添加</button>
<button @click="clearChecked">清理</button>
<ul>
<li v-for="(item,index) in lists">
<input type="checkbox" v-model="item.checked">
<span>{{item.text}}</span>
<button @click="del(idnex)">删除</button>
</li>
</ul>
<div>
<lable>
全选
<input type="checkbox" v-model="isAll">
{{checkedNum}}/{{lists.length}}
</lable>
</div>
</template>
<script lang="ts" setup>
import {ref, computed} from 'vue';
interface TodoItem { // 定义 todo 事项类型
msg: string // 要做的事
done: boolean // 是否完成
}
let lists = ref<TodoItem[]>([])
let text: string = ref('')
const checkedNum = computed(() => {
return lists.value.filter(item => item.checked).length
})
const isAll = computed<boolean>({
get: () => {
return checkedNum.length === lists.value.length
},
set: (val: boolean) => {
lists.value.map(item => {
item.checked = val
})
}
})
const add = () => {
if (text.value) {
lists.value.push({
text: text.value,
checked: false
})
text.value = ''
}
}
const del = (index: number) => {
lists.value.splice(index, 1)
}
const clearChecked = () => {
lists.value = lists.value.filter(item => {
if (!item.checked) {
return item
}
})
}
</script>
<style scoped>
</style>
\ No newline at end of file
vue3 ts demo
\ No newline at end of file
<template>
<div id="app">
<el-button type="success" @click="onexcel">导出excel</el-button>
</div>
</template>
<script>
import fileSaverfrom from 'file-saver'
import XLSX from 'xlsx'
export default {
methods: {
//需要导出的JSON数据
onexcel() {
const data = {
'基本信息': this.baseData(),
'历史信息': this.history1(),
};
let columnHeaders = {
'基本信息': {
'data0': '主管单位或镇街道',
'data1': '单位',
'data2': '分管领导',
'data3': '职务',
'data4': '固定电话',
'data5': '移动电话',
'data6': '任职时间',
},
'历史信息': {
'extra': '主管单位或镇街道',
'data0': '单位',
'data1': '分管领导',
'data2': '职务',
'data3': '固定电话',
'data4': '移动电话',
'data5': '任职时间',
'data6': '离职时间'
},
}
// //设置字段宽度
let wscols = [{wch: 12}, {wch: 12}, {wch: 12}, {wch: 12}, {wch: 12}, {wch: 12}, {wch: 12}, {wch: 12}, {wch: 12}, {wch: 12}, {wch: 12}, {wch: 12}, {wch: 12}, {wch: 12}];
// 默认表头数据样式
const HEAD_STYLE = {
fill: {
fgColor: { rgb: 'FFA3F4B1' }, // 背景色只支持16进制
bgcolor: { rgb: "ffff00" }
},
font: {
name: '宋体',
sz: 11,
bold: true,
color: { rgb: 'FFFF0000' }
// 这种颜色表示方式 前面的两个FF表示不透明,后面的为16进制的颜色值,如下博文
// https://segmentfault.com/a/1190000019679572?utm_source=tag-newest
},
border: {
bottom: {
style: 'thin',
color: { rgb: 'FF000000' }
},
right: {
style: 'thin',
color: { rgb: 'FF000000' }
}
}
}
let sheetNames = [];
let sheetsList = {};
const wb = XLSX.utils.book_new();
for (let key in data) {
sheetNames.push(key);
console.log('sheetNames',sheetNames);
let columnHeader = columnHeaders[key] // 此处是每个sheet的表头
console.log('columnHeader',columnHeader);
let temp = this.transferData(data[key], columnHeader);
console.log('temp',temp);
sheetsList[key] = XLSX.utils.aoa_to_sheet(temp);
sheetsList[key]["!cols"] = wscols;
sheetsList[key]["!merges"] = HEAD_STYLE;
}
wb["SheetNames"] = sheetNames;
wb["Sheets"] = sheetsList;
console.log('sheetsList',sheetsList);
XLSX.writeFile(wb, "通讯录.xlsx");
},
transferData(data, columnHeader) {
console.log('data, columnHeader',data, columnHeader);
let content = [], header = [];
for (let i in columnHeader) {
header.push(columnHeader[i])
}
content.push(header);
data.forEach((item, index) => {
let arr = [];
for (let i in columnHeader) {
arr.push(item[i])
}
content.push(arr);
});
console.log('content',content);
return content;
},
baseData() {
return [
{
data0: '虹桥街道',
data1: '大数据中心',
data2: '',
data3: '副主任',
data4: '025-88888888',
data5: '13000000000',
data6: '2019-12-14',
}, {
data0: '崇川街道',
data1: '大数据中心',
data2: '',
data3: '科长',
data4: '025-88888888',
data5: '13000000000',
data6: '2019-11-14',
},
];
},
history1() {
return [
{
extra: '虹桥街道',
data0: '',
data1: '主任',
data2: '025-88888888',
data3: '13000000000',
data4: '2019-11-14',
data5: '2019-12-14'
},
{
extra: '虹桥街道',
data0: '',
data1: '副主任',
data2: '025-88888888',
data3: '13000000000',
data4: '2019-12-14',
data5: ''
},
{
extra: '虹桥街道',
data0: '',
data1: '副主任',
data2: '025-88888888',
data3: '13000000000',
data4: '2019-12-14',
data5: ''
},
{
extra: '文峰街道',
data0: '',
data1: '主任',
data2: '025-88888888',
data3: '13000000000',
data4: '2019-10-14',
data5: '2019-11-14'
},
{
extra: '文峰街道',
data0: '',
data1: '科长',
data2: '025-88888888',
data3: '13000000000',
data4: '2019-11-14',
data5: ''
},
];
},
},
}
</script>
<template>
<download-excel class="btn btn-default"
:data="json_data"
:fields="json_fields"
worksheet="My Worksheet"
name="filename.xls">
Download Data
</download-excel>
</template>
<script>
export default {
name: "excelJson",
data() {
return {
json_fields: {
"Complete name": "name",
City: "city",
Telephone: "phone.mobile",
"Telephone 2": {
field: "phone.landline",
callback: (value) => {
return `Landline Phone - ${value}`;
},
},
},
json_data: [
{
name: "Tony Peña",
city: "New York",
country: "United States",
birthdate: "1978-03-15",
phone: {
mobile: "1-541-754-3010",
landline: "(541) 754-3010",
},
},
{
name: "Thessaloniki",
city: "Athens",
country: "Greece",
birthdate: "1987-11-23",
phone: {
mobile: "+1 855 275 5071",
landline: "(2741) 2621-244",
},
},
],
json_meta: [
[
{
key: "charset",
value: "utf-8",
},
],
],
}
},
}
</script>
<style scoped>
</style>
\ No newline at end of file
<template>
<a-alert message="md-editor-v3 Markdown编辑器Vue3版本" type="info"></a-alert>
<a-alert message="md-editor-v3 Markdown编辑器Vue3版本" type="info"></a-alert>
<md-editor v-model="text" previewOnly showCodeRowNumber/>
<p>导出</p>
<excel></excel>
<excelJson></excelJson>
</template>
<script>
import excel from './components/excel.vue'
import excelJson from './components/excelJson.vue'
import mdEditorV3 from './md-editor-v3.md?raw'
export default {
name: "editor",
components:{
excel,
excelJson
},
data() {
return {
text: mdEditorV3,
......
<template>
<div>welcome</div>
</template>
<script>
export default {
name: "index",
setup(){
......
......@@ -35,10 +35,12 @@ export default defineConfig({
resolve: {
alias: {
'@': path.resolve(__dirname,'./src'), // 配置组件
'@': path.resolve('src'), // 配置组件
'@com': path.resolve('./src/components'), // 配置组件
'@views': path.resolve(__dirname,'./src/views'), // 配置组件
'@c': path.resolve(__dirname, './src/components'), // 配置组件
// '@img': path.resolve(__dirname, './src/assets') // 配置图片
},
extensions: ['.js', '.ts', '.jsx', '.tsx', '.json', '.vue', '.mjs']
// extensions: ['.js', '.ts', '.jsx', '.tsx', '.json', '.vue', '.mjs']
}
})