08、vite+vue3+ts初始化项目遇到的坑

1、确保node版本

node版本:v16+
vite官网也给出了建议:

Vite 需要 Node.js 版本 14.18+,16+。然而,有些模板需要依赖更高的 Node 版本才能正常运行,当你的包管理器发出警告时,请注意升级你的 Node 版本。

2、使用命令行创建vite项目

我一般是使用yarn,然后根据命令给出的提示一步一步选择自己要的配置就行了

npm create vite@latest
//or
yarn create vite

这样一个项目就初始化完成了,下面我们来对项目进行一些基础配置

3、配置less或者scss

在这里我选择的是less,首先安装less

//安装less
yarn add less

安装之后,可以直接使用less文件和在style里面使用less.

4、自定义ant-design-vue主题

yarn add ant-design-vue

在main.ts里面引入

//main.ts
import { createApp } from 'vue'
import Antd from 'ant-design-vue';
import './assets/styles/global.less'
import './assets/styles/theme-file.less' //这里是自定义主题的less文件
import App from './App.vue'

const app=createApp(App)
app.use(Antd)
app.mount('#app')

//theme-file.less
@import 'ant-design-vue/dist/antd.less';
@primary-color: #5365e1;

注意:这样使用项目会报错导致无法运行,需要vite.config.ts里面加一个配置

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue()],
  css: {
    preprocessorOptions: {
      less: {
        javascriptEnabled: true //开启 JavaScript 就可以了
      }
    }
  },
})

这样主题色就可以修改了,效果如下:


image.png

5、引入App.vue文件会报错

需要在src/vite-env.d.ts里面加入下面的代码:

declare module '*.vue' {
  import type { DefineComponent } from 'vue'
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types
  const component: DefineComponent<{}, {}, any>
  export default component
}

image.png

6、直接引入ts文件报错

image.png

vite.config.ts里面加入下面的代码

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue()],
  css: {
    preprocessorOptions: {
      less: {
        javascriptEnabled: true
      }
    }
  },
  resolve: {
    //添加别名
    alias: {
        '@': resolve(__dirname, './src') 
    },
    extensions: ['.mjs', '.js', '.mts', '.ts', '.jsx', '.tsx', '.json'] //加入这段代码
  }
})

7、v-loading自定义指令封装

//loading.ts
import { render, VNode, createVNode,createApp  } from 'vue'
import Loading from './index.vue'
const vnode= createVNode(Loading) as VNode

 const vLoading = {
  // 在绑定元素的父组件 及他自己的所有子节点都挂载完成后调用
  mounted: (el: HTMLElement, binding: any) => {
    el.style.position = 'relative'
    render(vnode, el)
  },
  // 在绑定元素的父组件 及他自己的所有子节点都更新后调用
  updated: (el: HTMLElement, binding: any) => {
    if (binding.value) {
      vnode.component?.exposed.show()
      // vnode?.component?.exposed.show()
    } else {
      vnode?.component?.exposed.hide()
    }
  },
  // 绑定元素的父组件卸载后调用
  unmounted: () => {
    vnode?.component?.exposed.hide()
  },
}

export default vLoading

//loading.vue
<template>
  <div v-if="isShow" class="loading-box">
    <div class="mask"></div>
    <div class="loading-content-box">
      <img :src="loadingImg" />
      <div class="tip">加载中...</div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import loadingImg from '@/assets/images/loading.png'
// defineProps({
//   tip: {
//     type: String,
//     default() {
//       return '加载中...'
//     }
//   },
//   maskBackground: {
//     type: String,
//     default() {
//       return 'rgba(0, 0, 0, 0.8)'
//     }
//   },
//   loadingColor: {
//     type: String,
//     default() {
//       return 'rgba(255, 255, 255, 1)'
//     }
//   },
//   textColor: {
//     type: String,
//     default() {
//       return 'rgba(255, 255, 255, 1)'
//     }
//   }
// })
const isShow = ref(false)
const show = () => {
  isShow.value = true
}
const hide = () => {
  isShow.value = false
}
defineExpose({
  show,
  hide,
  isShow
})
</script>
<style lang="less" scoped>
.loading-box {
  position: absolute;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
  width: 100%;
  height: 100%;
  overflow: hidden;
  z-index: 9999;
  .n-spin {
    color: #ccc;
  }
  .mask {
    width: 100%;
    height: 100%;
    background: rgba(255, 255, 255, 0.5);
  }
  .loading-content-box {
    position: absolute;
    left: 0;
    top: 0;
    right: 0;
    bottom: 0;
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    img {
      width: 30px;
      animation: rotate 1.5s linear infinite;
    }
  }
  .tip {
    font-size: 14px;
    margin-top: 8px;
  }
}
@keyframes rotate {
  to {
    transform: rotate(360deg);
  }
}
</style>

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容