vue3 + ts + pinia + router + eslint 项目创建起步流程

vue3 + ts + pinia + router + eslint 项目起步流程

创建项目

目标:使用 vite 初始化项目

核心步骤:

  • 初始化项目
yarn create vue
或
npm init vue
  • 一顿操作
√ Project name: ... vue3-ts-pinia-router-eslint
√ Add TypeScript? ... Yes ✅
√ Add JSX Support? ... Yes ✅
√ Add Vue Router for Single Page Application development? ... Yes ✅
√ Add Pinia for state management? ... Yes ✅
√ Add Vitest for Unit Testing? ... No ❌
√ Add Cypress for both Unit and End-to-End testing? ... No ❌
√ Add ESLint for code quality? ... Yes ✅
√ Add Prettier for code formatting? ... Yes ✅
  • 进入到 vue3-ts-pinia-router-eslint 项目中,安装依赖包
yarn
  • eslint 格式化项目文件
yarn lint
  • 启动项目
yarn dev

创建 Vue3 项目命令对比

Vue3 基础阶段命令

  • 能使用,但是配置太简单了,学习 Vue3 基础可以,项目还需要额外配置很多东西,效率低。
yarn create vite

Vue3 项目阶段命令

  • Vue3 官方推荐方式,可以根据项目情况按需选择配置,推荐使用。
yarn create vue

Node 版本问题

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

01-项目起步-目录调整

  1. 删除 src 目录所有文件

  2. 创建 src/App.vue

    <template>
      <h1>Hello vue3 + ts</h1>
    </template>
    
  3. 创建 src/main.ts

    import { createApp } from "vue";
    import App from "./App.vue";
    
    const app = createApp(App);
    
    app.mount("#app");
    

02-项目起步-请求工具库axios

  1. 安装npm i axios -S

  2. src/App.vue

    <script setup lang="ts">
    // 导入 axios 实例
    import { onMounted } from "vue";
    import request from "./utils/request";
    // 在组件挂载完毕后
    onMounted(async () => {
      // 发送请求
      const res = await request.get("/home/banner");
      console.log(res);
    });
    </script>
    
    <template>
      <h1>Hello vue3 + ts</h1>
    </template>
    
  3. src/utils/request.ts

    import axios from "axios";
    
    // 创建 axios 实例
    const instance = axios.create({
      baseURL: "http://pcapi-xiaotuxian-front-devtest.itheima.net/",
      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;
    

03-项目起步-统一VSCode配置和格式化配置

新建.editorconfig文件

用于跨不同的编辑器和 IDE 为多个开发人员维护一致的编码风格的配置文件

# 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
editorconfig 属性
  1. charset 编码格式

    • 值为latin1utf-8utf-8-bomutf-16beutf-16le
  2. root

    • 顶级配置文件
  3. indent_style 缩进风格

    • 空格space
    • Tab键tab
  4. indent_size 缩进大小

    • 2 or 4
  5. end_of_line 换行符类型

    • 换行lf
    • 回车cr
    • 回车换行crlf

    Dos和Windows采用回车+换行(cr+lf)来表示换行
    UNIX和Linux采用换行符(lf)来表示换行
    MAC OS采用回车符(cr)来表示换行

  6. insert_final_newline

    • true —> 以换行符结尾
  7. trim_trailing_whitespac

    • 删除换行符之前的任何空白字符 true

新建 .gitattributes文件

用于定义每种文件的属性,方便 git 帮我们统一管理

* text eol=lf
*.txt text eol=lf
* text eol=lf
  • 对git任何文件,进行行尾规范化 ,使用 lf 换行
*.txt text eol=lf
  • 对于.txt文件,标记为文本文档,并进行行尾规范化 ,检出工作目录时,行尾保持为lf

.gitignore文件

取消忽略 .vscode 文件

- .vscode/*

.prettierrc文件

统一团队代码格式,同时在vscode — setting.json注释掉自己的格式(可留着字体大小

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

.vscode/extensions.json

推荐下载的 vscode 插件

{
    "recommendations": [
    "vue.volar",
    "vue.vscode-typescript-vue-plugin",
    "dbaeumer.vscode-eslint",
    "esbenp.prettier-vscode",
    "usernamehw.errorlens",
    "editorconfig.editorconfig"
  ]
}

.vscode/settings.json文件

{
  "[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.tabSize": 2,
  // 保存时格式化
  "editor.formatOnSave": true,
  "editor.codeActionsOnSave": {
    "source.fixAll": true,
    "source.fixAll.eslint": true
  },
  // 文件行尾符号
  "files.eol": "\n",
  // 是否以紧凑形式展示文件夹
  "explorer.compactFolders": false
}

04-项目起步-样式处理-less和mixin

安装 less npm i less -S
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);
  }
}
src/assets/styles/variables.less
// 主题
@xtxColor: #27ba9b;
// 辅助
@helpColor: #e26237;
// 成功
@sucColor: #1dc779;
// 警告
@warnColor: #ffb302;
// 价格
@priceColor: #cf4444;
src/App.vue



05-项目起步-vite配置自动导入less

变量是有作用域的,只是在单个文件引入,其他文件不可用(如果只是样式的话不需要这个步骤)

vite.config.ts

// defineConfig 节点

// css 配置
  css: {
    // https://cn.vitejs.dev/config/shared-options.html#css-preprocessoroptions
    // 预处理器选项
    preprocessorOptions: {
      // less
      less: {
        // 自动添加代码
        additionalData: `
            @import "@/assets/styles/variables.less";
            @import "@/assets/styles/mixins.less";
          `,
      },
      },
    },

src/App.vue

- @import './assets/styles/variables.less';
- @import './assets/styles/mixins.less';

06-项目起步-样式重置和公共样式

安装 npm i normalize.css -S

src/main.ts

// 全局导入 normalize.css 让所有标签在不同浏览器风格统一 (PS:如果用组件库,内部集成了就不用额外安装)
import 'normalize.css'

// 全局导入 公共的样式   如:版心类名
import '@/assets/styles/common.less';

src/assets/styles/common.less

@import url('./variables.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-color: #f5f5f5;
}

.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;
  }
}

你可能感兴趣的:(Vue,vue.js,javascript,前端)