vue3项目构建、vscode配置

926 阅读5分钟

vue3项目搭建以及vs配置

1. 初始化项目

yarn create vue  或者  npm init vue

2.选择第三方模块以及eslint

Project name: ... my-vue3ts-project   // 项目名称Add TypeScript? ... Yes         // 选择TypeScriptAdd JSX Support? ... Yes       // Javascript和XML结合的一种格式Add Vue Router for Single Page Application development? ... Yes  // 路由Add Pinia for state management? ...  Yes  // piniaAdd Vitest for Unit Testing? ... No   // 不选Add Cypress for both Unit and End-to-End testing? ... No  // 不选Add ESLint for code quality? ... Yes  // 使用EslintAdd Prettier for code formatting? ... Yes  // 代码格式化

3.进入项目中安装npm包

yarn: 
1. yarn  // 安装npm包
2. yarn lint  // eslint监测语法
3. yarn dev  // 启动项目

npm:
1. npm install // 安装npm包
2. npm run lint // eslint监测语法
3. npm run dev  // 启动项目

4. yarn安装npm包出现报错问题?

  • yarn create vue 的依赖包要求Node 16+以上,或者14.17.0` 版本,建议大家升级 Node 版本。

image.png

  • 注意npm构建的项目不会出现此问题

5. 封装axios

  • 安装axios
yarn add axios  或   npm i axios 
  • 在src目录下新建utils文件夹,新建文件request.ts (src/utils/request.ts)
import axios from 'axios'

// 创建 axios 实例
const instance = axios.create({
  baseURL: '基础路径',
  timeout: 50000
})

// 添加请求拦截器
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

6. 导入共用的less变量以及mixins

  • 安装less
yarn add less  或者  npm i less
  • 新建变量 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);
  }
}

7. Vite 配置 - 自动导入样式(less变量,混入配置)

  • 思考一:为什么要自动导入样式?
  • 上边定义的变量是需要时引入文件,变量和函数都是对于文件来说都是局部的,如果不自动导入样式,需要一个一个导入文件内
  • 修改vite.config.ts文件,增加内容
export default defineConfig({
// ...省略
  css: {
    // https://cn.vitejs.dev/config/#css-preprocessoroptions
    preprocessorOptions: {
      less: {
        additionalData: `
          @import "@/assets/styles/variables.less";
          @import "@/assets/styles/mixins.less";
        `,
      },
    },
  },
})
  • vite添加自动导入样式之后,组件只要有用到less,都会自动导入less变量和混入配置

8. 引入重置样式,统一标签样式(引入normalize.css)

  • vue2后台管理以及移动端项目没有引入,是因为使用了第三方ui库,第三方ui库底层已经引入了normalize.css
    前台pc商城面向客户注重用户体验,不使用第三方组件库,一些组件和按钮都是自己封装的
    所以需要主动引入
  • 安装 normalize.css

  • yarn add normalize.css  或者  npm i normalize.css
    
  • 在main.js中导入

  • import { createApp } from 'vue'
    import App from './App.vue' 
    import 'normalize.css'   // 引入
    
    createApp(App).mount('#app')
    
  • 通过效果会发现,h1ul 等样式还是保留的,但不一致的样式已经被重置了,确保不同的浏览器统一标签样式

9. 样式处理-公共样式

  • **目标:**能够给项目设置通用的样式。虽然有了重置样式,但是项目中依旧需要项目的通用样式。
  • 新建文件 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.ts 导入即可。

  • import { createApp } from 'vue'
    import App from './App.vue'
    
    import 'normalize.css'
    import '@/assets/styles/common.less'   // 引入
    
    createApp(App).mount('#app')
    

VsCode 配置参考

工作区插件

  • 工作区插件:.vscode\extensions.json
{
  "recommendations": [
    "vue.volar",
    "vue.vscode-typescript-vue-plugin",
    "dbaeumer.vscode-eslint",
    "esbenp.prettier-vscode",
    "usernamehw.errorlens"
  ]
}

工作区设置

  • 工作区设置: .vscode\settings.json
    • 指定格式化程序
    • eslint 配置
    • 行尾配置
    • 空格缩进个数
    • 等...
{
  "[typescript]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[vue]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "eslint.enable": true,
  "eslint.run": "onType",
  "eslint.options": {
    "extensions": [
      ".js",
      ".ts",
      ".vue",
      ".jsx",
      ".tsx"
    ]
  },
  // 操作时作为单词分隔符的字符
  "editor.wordSeparators": "`~!@#%^&*()=+[{]}\\|;:'\",.<>/?",
  "editor.codeActionsOnSave": {
    "source.fixAll": true,
    "source.fixAll.eslint": true
  },
  // 一个制表符等于的空格数
  "editor.tabSize": 2,
  "files.eol": "\n",
  "explorer.compactFolders": false
}

格式化配置

根目录下新建文件: .prettierrc

{
  "semi": true,
  "singleQuote": true,
  "tabWidth": 2,
  "printWidth": 80
}

根目录下新建文件:.gitattributes

git提交会默认改变行尾,所以需要指定

* text eol=lf
*.txt text eol=lf

根目录下新建文件:.editorconfig

# editorconfig.org
root = true

[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
quote_type = single