vue3+vite+Ts 项目如何配置?

464 阅读6分钟

配套资源

想要开发一个项目首先需要拿到配套的资源(接口文档),然后确定你需要使用哪些技术栈来实现你想要的效果

第一步

我这边用一个前台的项目举例

我这边用到的技术栈有以下几个
项目基于vue技术来实现,大概会使用以下技术:
  • vue3.0 (使用组合api的方式来开发)
  • vite开发
  • axios (请求接口)
  • vue-router (单页路由)
  • pinia (状态管理)
  • normalize.css (初始化样式)
  • @vueuse/core (组合api常用工具库) 重要
  • 算法 Power Set
  • dayjs (日期处理)
  • vee-validate (表单校验)

说明: 由于前台项目,没有合适的UI组件库(没有适用vue3.0的ui库),不会使用组件库。

第二步

创建项目

  • 创建一个文件夹然后 输入cmd 或 【win+R】打开黑窗口 使用 vite 初始化项目
(1)yarn create vite 或 npm create vite
(2) 输入项目名字

image.png

(3) 选择创建项目的类型,选择vue即可

image.png

(4) 选择创建vue项目类型,选择vue-ts

image.png

(5) 启动项目

image.png

   cd 项目名称 跳转到你创建的项目文件夹下我这里的项目名称是 vite-demo 所以输入 cd vite-demo 即可
   然后输入  yarn 或 npm i  下载依赖包等待依赖包下载好了之后运行 yarn dev 或 npm run dev 
   

image.png

  • 复制这段链接在浏览器打开

image.png

  • 打开的页面是上面这样的就代表项目创建成功

注意点:vscode插件说明

  vue2中需要安装插件`vetur`,可以实现组件高亮。但是vue3的一些语法在vetur中报错。
  vue3中需要安装插件`volar`,提供了更加强大的功能。
  所以,使用功能vue3,需要卸载`vetur`插件,安装`volar`插件。 

image.png

目录调整

修改文件
  • main.ts删除引入样式 import './style.css'
  • App.vue删除无用的内容
删除文件
  • src/components/HelloWorld.vue HelloWorld 组件
  • src/assets/logo.png vue 默认的 logo
新增文件夹
  • utils 用于存放工具相关
  • assets/images 用于存放图片相关
  • assets/styles 用于存放样式相关
  • router 用于存放路由相关
  • store用于存放数据相关
  • views用于存放页面级别的组件
  • types用于存放 ts 的公共类型

使用 git 管理项目

  • 初始化项目:git init
  • 将代码添加到暂存区: git add .
  • 提交代码 git commit -m '初始化提交'
  • 码云上创建项目rabbit-vue3-ts,选择开源
  • 设置仓库别名
git remote add origin https://gitee.com/T-liangsang/vite-demo.git

image.png

  • 推送到远程仓库
git push -u origin master

axios 封装

  • 安装 axios
yarn add axios 或 npm i axios
  • 新建 src/utils/request.ts 模块,代码如下
import axios from 'axios'// 备用接口地址: http://pcapi-xiaotuxian-front-devtest.itheima.net/
const instance = axios.create({
  baseURL: 'http://pcapi-xiaotuxian-front.itheima.net/',
  timeout: 5000
})
​
// 添加请求拦截器
instance.interceptors.request.use(
  function (config) {
    // 在发送请求之前做些什么
    return config
  },
  function (error) {
    // 对请求错误做些什么
    return Promise.reject(error)
  }
)
​
// 添加响应拦截器
instance.interceptors.response.use(
  function (response) {
    return response
  },
  function (error) {
    // 对响应错误做点什么
    return Promise.reject(error)
  }
)
​
export default instance
  • App.vue文件中进行测试
<template>
  <div>app组件</div>
</template><script lang="ts" setup>
import request from './utils/request'
const test = async () => {
  const res = await request.get('/home/index')
  console.log(res)
}
test()
</script>

配置路劲别名

  • vite.config.ts中增加配置
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
//const path = require('path')
//修改为
import path form 'path'// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: {
      '@': path.resolve(__dirname, './src')
    }
  }
})

需要安装node的类型声明文件

yarn add @types/node -D
  • 修改tsconfig.json,增加如下配置
{
  "compilerOptions": {
    // ...
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"]
     }
  }
}

注意:修改完 vite.config.ts 文件需要重启

样式处理-less 变量与 mixins

目标: 能够使用 less 变量定义项目中常用的颜色,使用 mixins 定义项目中常用的样式

核心步骤

  • 变量 src/assets/styles/variables.less
// 主题
@xtxColor: #27ba9b;
// 辅助
@helpColor: #e26237;
// 成功
@sucColor: #1dc779;
// 警告
@warnColor: #ffb302;
// 价格
@priceColor: #cf4444;
  • 混入 src/assets/styles/mixins.less
// 鼠标经过上移阴影动画
.hoverShadow () {
  transition: all 0.5s;
  &:hover {
    transform: translate3d(0, -3px, 0);
    box-shadow: 0 3px 8px rgba(0, 0, 0, 0.2);
  }
}
  • 在 app.vue 中测试
<style lang="less" scoped>
// 必须导入variables.less
@import '@/assets/styles/variables.less';
@import '@/assets/styles/mixins.less';
h1 {
  background-color: @warnColor;
  .hoverShadow();
}
</style>
  • 需要安装less的依赖包
yarn add less -D
  • 问题:variables.lessmixins.less两个 less 文件是需要在多个组件中去使用的。但是如果组件中不导入,直接使用会报错。

样式处理 - 自动导入

  • 修改vite.config.ts文件,增加内容
export default defineConfig({
  css: {
    preprocessorOptions: {
      less: {
        additionalData: `
          @import "@/assets/styles/variables.less";
          @import "@/assets/styles/mixins.less";
        `
      }
    }
  }
})
  • 修改 app.vue 中的代码
<style lang="less" scoped>
h1 {
  background-color: @warnColor;
  .hoverShadow();
}
</style>
  • 重启服务,查看效果

样式处理 - 重置样式

  • 安装 normalize.css 样式重置的库, 将浏览器中的一些默认样式, 进行重置统一
yarn add normalize.css
  • 使用 normalize.css

main.js 导入 normalize.css 即可。

import { createApp } from 'vue'
import App from './App.vue'
​
+ import 'normalize.css'createApp(App).mount('#app')
  • 在 app.vue 中测试
<template>
  <div>
    <router-view />
    <p>哈哈哈</p>
    <ul>
      <li>123</li>
      <li>456</li>
    </ul>
    <h1>这是大标题</h1>
  </div>
</template>

通过效果会发现,h1 ul 等样式还是保留的,但是不一致的样式已经被重置了

样式处理 - 公共样式

  • 新建文件 src/assets/styles/common.less
// 按照网站自己的需求,提供公用的样式
* {
  box-sizing: border-box;
}
​
html {
  height: 100%;
  font-size: 14px;
}
body {
  height: 100%;
  color: #333;
  min-width: 1240px;
  font: 1em/1.4 'Microsoft Yahei', 'PingFang SC', 'Avenir', 'Segoe UI', 'Hiragino Sans GB',
    'STHeiti', 'Microsoft Sans Serif', 'WenQuanYi Micro Hei', sans-serif;
}
​
ul,
h1,
h3,
h4,
p,
dl,
dd {
  padding: 0;
  margin: 0;
}
​
a {
  text-decoration: none;
  color: #333;
  outline: none;
}
​
i {
  font-style: normal;
}
​
input[type='text'],
input[type='search'],
input[type='password'],
input[type='checkbox'] {
  padding: 0;
  outline: none;
  border: none;
  -webkit-appearance: none;
  &::placeholder {
    color: #ccc;
  }
}
​
img {
  max-width: 100%;
  max-height: 100%;
  vertical-align: middle;
  //  background: #ebebeb;
}
​
ul {
  list-style: none;
}
​
#app {
  background: #f5f5f5;
  // 不能选中文字
  user-select: none;
}
​
.container {
  width: 1240px;
  margin: 0 auto;
  position: relative;
}
​
// 一行省略
.ellipsis {
  white-space: nowrap;
  text-overflow: ellipsis;
  overflow: hidden;
}
// 二行省略
.ellipsis-2 {
  word-break: break-all;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
}
​
.fl {
  float: left;
}
​
.fr {
  float: right;
}
​
.clearfix:after {
  content: '.';
  display: block;
  visibility: hidden;
  height: 0;
  line-height: 0;
  clear: both;
}
​
// 闪动画
.shan {
  &::after {
    content: '';
    position: absolute;
    animation: shan 1.5s ease 0s infinite;
    top: 0;
    width: 30%;
    height: 100%;
    background: linear-gradient(
      to left,
      rgba(255, 255, 255, 0) 0,
      rgba(255, 255, 255, 0.3) 50%,
      rgba(255, 255, 255, 0) 100%
    );
    transform: skewX(-45deg);
  }
}
@keyframes shan {
  0% {
    left: -100%;
  }
  100% {
    left: 120%;
  }
}
​
// 离开淡出动画
.fade {
  &-leave {
    &-active {
      position: absolute;
      width: 100%;
      transition: opacity 0.5s 0.2s;
      z-index: 1;
    }
    &-to {
      opacity: 0;
    }
  }
}
​
// 1. 离开,透明度  1---->0    位移 0---->30
// 2. 进入,透明度  0---->1    位移 30---->0
// 执行顺序,先离开再进入
.pop {
  &-leave {
    &-from {
      opacity: 1;
      transform: none;
    }
    &-active {
      transition: all 0.5s;
    }
    &-to {
      opacity: 0;
      transform: translateX(20px);
    }
  }
  &-enter {
    &-from {
      opacity: 0;
      transform: translateX(20px);
    }
    &-active {
      transition: all 0.5s;
    }
    &-to {
      opacity: 1;
      transform: none;
    }
  }
}
​
// 表单
.xtx-form {
  padding: 50px 0;
  &-item {
    display: flex;
    align-items: center;
    width: 700px;
    margin: 0 auto;
    padding-bottom: 25px;
    .label {
      width: 180px;
      padding-right: 10px;
      text-align: right;
      color: #999;
      ~ .field {
        margin-left: 0;
      }
    }
    .field {
      width: 320px;
      height: 50px;
      position: relative;
      margin-left: 190px;
      .icon {
        position: absolute;
        left: 0;
        top: 0;
        width: 40px;
        height: 50px;
        text-align: center;
        line-height: 50px;
        color: #999;
        ~ .input {
          padding-left: 40px;
        }
      }
      .input {
        border: 1px solid #e4e4e4;
        width: 320px;
        height: 50px;
        line-height: 50px;
        padding: 0 10px;
        &.err {
          border-color: @priceColor;
        }
        &:focus,
        &:active {
          border-color: @xtxColor;
        }
      }
    }
    .error {
      width: 180px;
      padding-left: 10px;
      color: @priceColor;
    }
  }
  .submit {
    width: 320px;
    height: 50px;
    border-radius: 4px;
    background: @xtxColor;
    height: 50px;
    line-height: 50px;
    text-align: center;
    font-size: 16px;
    color: #fff;
    display: block;
    margin: 0 auto;
  }
}
  • main.js 导入即可。
import { createApp } from 'vue'
import App from './App.vue'
import 'normalize.css'
+ import '@/assets/styles/common.less'
createApp(App).mount('#app')

Layout模块

  • 路由配置 (1)安装依赖包
yarn add vue-router

(2)创建组件views/layout/index.vue

<script lang="ts" setup name="Layout"></script>
<template>
  <div>layout组件</div>
</template><style lang="less" scoped></style>

(3)创建组件views/login/index.vue

<script lang="ts" setup name="Login"></script>
<template>
  <div>login组件</div>
</template><style lang="less" scoped></style>

(4)创建文件router/index.ts

import { createRouter, createWebHashHistory } from 'vue-router'
import Layout from '@/views/layout/index.vue'
const router = createRouter({
  history: createWebHashHistory(),
  routes: [
    {
      path: '/',
      component: Layout
    },
    {
      path: '/login',
      component: () => import('@/views/login/index.vue')
    }
  ]
})
export default router

(5)在main.ts中导入

import { createApp } from 'vue'
import App from './App.vue'
import 'normalize.css'
import '@/assets/styles/common.less'
import router from './router'const app = createApp(App)
app.use(router)
app.mount('#app')

(6)修改App.vue

<template>
  <RouterView></RouterView>
</template>

2.name的说明

github.com/vbenjs/vite…

(1)安装

yarn add vite-plugin-vue-setup-extend -D

(2)配置 vite.config.js中

import vueSetupExtend from 'vite-plugin-vue-setup-extend'export default defineConfig({
  plugins: [vue(), vueSetupExtend()],
})

注意: name属性要生效.script标签中要有内容

以上内容仅供参考 实际操作以自己的项目需求为准