添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
"*.{js,jsx,vue,ts,tsx}": [ "npm run lint", // "git add" 之前的版本需要手动把 lint 过程中修改的代码手动 add,新版本不需要了

vite-plugin-eslint

npm install vite-plugin-eslint --save-dev

  • vite.config.ts
  • import { defineConfig } from 'vite'
    import vue from '@vitejs/plugin-vue'
    import eslintplugin from 'vite-plugin-eslint'
    // https://vitejs.dev/config/
    export default defineConfig({
      plugins: [vue(),eslintplugin({'配置参数'})]
    

    commit 提交规范

    Commit message 和 Change log 编写指南
    Install commitlint

  • 要让 TypeScript 正确推断 Vue 组件选项中的类型,需要使用 defineComponent 全局方法定义组件:
  • import { defineComponent } from 'vue'
    const Component = defineComponent({
      // 已启用类型推断
    //如果你使用的是[单文件组件](https://v3.cn.vuejs.org/guide/single-file-component.html),则通常会被写成:
    <script lang="ts">
    import { defineComponent } from 'vue'
    export default defineComponent({
      // 已启用类型推断
    </script>
    

    vue3中ts相关写法

    Vue3 中的<script setup>语法

    vue3支持三种写法

  • Option Api
  • Composition API
  • <script setup> (Composition API 的语法糖)
  • defineProps,defineEmits,defineExpose,withDefaults 为全局的 可以不import 直接使用

    eslint配置 .eslintrc.js 中配置则不会对此进行引入校验

    module.exports = {
      globals: {
        defineProps: 'readonly',
        defineEmits: 'readonly',
        defineExpose: 'readonly',
        withDefaults: 'readonly'
    

    script-setup用法
    该连接为github仓库连接 可能网络问题打不开

    script-setup用法 一个中文博客

    配置转换JSX和TSX

    vite中JSX

  • npm i @vitejs/plugin-vue-jsx --save-dev
    vite.config.ts配置
  • import { defineConfig } from 'vite'
    import vue from '@vitejs/plugin-vue'
    import vueJsx from '@vitejs/plugin-vue-jsx'
    // https://vitejs.dev/config/
    export default defineConfig({
      plugins: [
        vue(),
        vueJsx({
          //配置选项
    
    <template>
    </template>
    <script setup lang="tsx">
     const abc = <h1>abc</h1>
    </script>
    

    单独一个组件文件 text.tsx

    //函数式组件
    export default () => {
      return (
          <h1>text函数式组件</h1>
    //需要有状态的组件 options API
    import { defineComponent } from '@vue/runtime-core'
    export default defineComponent({
      props:{
        msg:{
          type:String
      render(){
        return (
          <div>{ this.msg }</div>
    //需要有状态的组件 组合式 API
    import { defineComponent,ref } from '@vue/runtime-core'
    interface PropsType {
      msg:string
    export default defineComponent({
      props:{
        msg:{
          type:String
      setup(){
        const count = ref (0)
        return (props:PropsType ) => (
            <p>{props.msg}</p>
            <p>{count}</p>
    

    初始化VueRouter

  • 安装vue-router
  • npm install vue-router@4

    // src\router\index.ts
    import { createRouter, RouteRecordRaw, createWebHashHistory } from 'vue-router'
    const routes: RouteRecordRaw[] = [
        path: '/',
        component: () => import('../views/home/index.vue')
        path: '/login',
        component: () => import('../views/login/index.vue')
    const router = createRouter({
      history: createWebHashHistory(),
      routes
    export default router
    
    // src\main.ts
    import { createApp } from 'vue'
    import router from './router'
    import App from './App.vue'
    createApp(App).use(router).mount('#app')
    

    初始化 Vuex

  • 安装Vuex
  • npm install vuex@next --save

    // src\store\index.ts
    import { createStore } from 'vuex'
    const store = createStore({
      state: {},
      getters: {},
      mutations: {},
      actions: {},
      modules: {}
    export default store
    
    // src\main.ts
    import { createApp } from 'vue'
    import App from './App.vue'
    import router from './router'
    import store from './store'
    createApp(App)
      .use(router)
      .use(store)
      .mount('#app')
    

    结合ts优化后

    //store/index.ts
    import { createStore, useStore as baseUseStore, Store } from 'vuex'
    import { InjectionKey } from 'vue'
    export interface State {
      count: number
    // 定义 injection key
    export const key: InjectionKey<Store<State>> = Symbol('store')
    export const store = createStore<State>({
      state: {
        count: 0
      mutations: {
        increment(state) {
          state.count++
    // 定义自己的 `useStore` 组合式函数 //调用该 useStore 可以推断出state属性及类型
    export function useStore() {
      return baseUseStore(key)
    export default store
    
    // vuex.d.ts
    import { ComponentCustomProperties } from 'vue'
    import { Store } from 'vuex'
    import { State } from './store/index'
    declare module '@vue/runtime-core' {
      // 声明自己的 store state
      // interface State {
      //   count: number
      // 为 `this.$store` 提供类型声明
      interface ComponentCustomProperties {
        $store: Store<State>
    

    配置模块路径别名

    vite不自带@等路径别名

    import xxx from '@/views/xxx.vue'  //不支持src别名@符  所以要手动配置
    
    // vite.config.ts
    import { defineConfig } from 'vite'
    import vue from '@vitejs/plugin-vue'
    // 注意:在 ts 模块中加载 node 核心模块需要安装 node 的类型补充模块:npm i -D @types/node
    import path from 'path'
    // https://vitejs.dev/config/
    export default defineConfig({
      resolve: {
        alias: {
          '@': path.resolve(__dirname, './src')
    
    // tsconfig.json   
    //所有以@开头的都指向src
      "compilerOptions": {
        "baseUrl": ".",
        "paths": {
          "@/*": ["src/*"]
    
    // js
    import xxx from '@/api/xxx.ts'
    // html
    <img src="@/assets/logo.png">
    // css
    @import url("@/styles/index.scss");
    background: url("@/assets/logo.png");
    

    CSS样式管理

    vite css配置 文档
    Vite 也同时提供了对 .scss, .sass, .less, .styl 和 .stylus 文件的内置支持。没有必要为它们安装特定的 Vite 插件,但必须安装相应的预处理器依赖:

    # .scss and .sass
    npm install -D sass
    # .less
    npm install -D less
    # .styl and .stylus
    npm install -D stylus
    

    如果是用的是单文件组件,可以通过 <style lang="sass">(或其他预处理器)自动开启。

  • 注意事项:
  • ● Vite 为 Sass 和 Less 改进了 @import 解析,以保证 Vite 别名也能被使用。
    ● 另外,url() 中的相对路径引用的,与根文件不同目录中的 Sass/Less 文件会自动变基以保证正确性。
    ● 由于 Stylus API 限制,@import 别名和 URL 变基不支持 Stylus。
    ● 你还可以通过在文件扩展名前加上 .module 来结合使用 CSS modules 和预处理器,例如 style.module.scss。

    深度作用操作符新语法::deep(<inner-selector>)
    样式目录结构

    variables.scss # 全局 Sass 变量
    mixin.scss # 全局 mixin
    common.scss # 全局公共样式
    transition.scss # 全局过渡动画样式
    index.scss # 组织统一导出

    全局样式都写在 src/styles 目录下,每个页面自己对应的样式都写在自己的 .vue 文件之中。

    // index.scss
    @import './variables.scss';
    @import './mixin.scss';
    @import './transition.scss';
    @import './common.scss';
    

    然后在 main.ts 中导入 index.scss:

    //main.ts  这里仅仅是加载了全局样式,并不能实现在组件内直接使用全局变量样式
    import "./styles/index.scss"
    

    在单独组件里使用全局变量 需要单独加载

    //xxx.vue
    <style lang="scss" scoped>
    @import '@/styles/variables.scss';
    .font{
      color:$color;
    </style>
    

    要想在全局单文件中不用单独引入就可以使用scss全局变量 需要配置使用全局样式
    配置使用全局样式变量
    css-preprocessoroptions
    vite.config.ts

    import { defineConfig } from 'vite'
    import vue from '@vitejs/plugin-vue'
    import vueJsx from '@vitejs/plugin-vue-jsx'
    import path from 'path'
    // https://vitejs.dev/config/
    export default defineConfig({
      plugins: [
        vue(),
        vueJsx({
          // 配置选项
      resolve: {
        alias: {
          '@': path.join(__dirname, 'src')//绝对路径
      css: {
        preprocessorOptions: {
          // 给 sass-loader 传递选项
          sass: {
            // @/ 是 src/ 的别名
            // 所以这里假设你有 `src/variables.sass` 这个文件
            // 注意:在 sass-loader v8 中,这个选项名是 "prependData"
            additionalData: `@import "@/styles/variables.scss"`
          // 默认情况下 `sass` 选项会同时对 `sass` 和 `scss` 语法同时生效
          // 因为 `scss` 语法在内部也是由 sass-loader 处理的
          // 但是在配置 `prependData` 选项的时候
          // `scss` 语法会要求语句结尾必须有分号,`sass` 则要求必须没有分号
          // 在这种情况下,我们可以使用 `scss` 选项,对 `scss` 语法进行单独配置
          scss: {
            additionalData: `@import "~@/variables.scss";`
          // 给 less-loader 传递 Less.js 相关选项
          less: {
            // http://lesscss.org/usage/#less-options-strict-units `Global Variables`
            // `primary` is global variables fields name
            globalVars: {
              primary: '#fff'
    

    自动注册全局组件

    glob-impor
    全局组件放在 components 目录下

    - components
        + foo
        + index.vue
        + index.ts
      + bar
        + index.vue
        + index.ts
    - main.ts
    
    // main.ts
    const app = createApp(App)
    const modules = import.meta.globEager('./components/**/index.ts')
    for (const path in modules) {
      app.use(modules[path].default)
    
    // components/foo/index.ts
    import { App } from '@vue/runtime-dom'
    import Component from './index.vue'
    export default {
      install (app: App) {
        app.component('Foo', Component)
    
    // components/bar/index.ts
    import { App } from '@vue/runtime-dom'
    import Component from './index.vue'
    export default {
      install (app: App) {
        app.component('Bar', Component)
    

    服务端交互

    **基于axios封装请求模块

  • 安装axios
  • npm i axios

    //src/utils/request.ts
    import axios from 'axios'
    const request = axios.create({
      baseURL: '' //基础请求路径
    // 请求拦截器
    request.interceptors.request.use(
      config => {
        // 统一设置用户身份 Token
        return config
      error => {
        return Promise.reject(error)
    // 响应拦截器
    request.interceptors.response.use(
      response => {
        // 统一处理响应错误,例如 token 无效、服务端异常等
        return response
      err => {
        return Promise.reject(err)
    export default request
     * 公共基础接口封装
    import request from '@/utils/request'
    export const getLoginInfo = () => {
      return request({
        method: 'GET',
        url: '/login/info'
     * 组件中使用
    import { getLoginInfo } from '@/api/common'
    import { onMounted } from '@vue/runtime-core'
    onMounted(() => {
      getLoginInfo().then(res => {
        console.log(res)
    

    多环境 baseURL

    环境变量和模式

    # .env.development
    # 开发模式下加载的环境变量
    VITE_API_BASEURL=http://a.com
    
    # .env.production
    # 生产模式下加载的环境变量
    VITE_API_BASEURL=http://b.com
    
    // src\utils\request.ts
    const request = axios.create({
      // localhost:8080/xxx
      // abc.com/xxx
      // test.com/xxx
      baseURL: import.meta.env.VITE_API_BASEURL
    
    //env.d.ts中对类型声明
    /// <reference types="vite/client" />
    declare module '*.vue' {
      import { DefineComponent } from 'vue'
      // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types
      const component: DefineComponent<{}, {}, any>
      export default component
    interface ImportMetaEnv {
      VITE_API_BASEURL: string
      // 更多环境变量...
    
  • 在服务端配置 CORS。
  • 配置开发服务器代理,比如 vite-server.proxy
  • 在服务端配置 CORS。
  • 配置生产服务器代理,比如 nginx。
  • CORS 全称为 Cross Origin Resource Sharing(跨域资源共享)。这种方案对于前端来说没有什么工作量,和正常发送请求写法上没有任何区别,工作量基本都在后端(其实也没啥工作量,就是配置一些 HTTP 协议)。

  • 跨源资源共享(CORS)
  • 跨域资源共享 CORS 详解
  • 服务器代理
    可能有些后端开发人员觉得配置 CORS 麻烦不想搞,那纯前端也是有解决方案的。

    在开发模式下可以下使用开发服务器的 proxy 功能,比如 vite - server.proxy

    但这种方法在生产环境是不能使用的。在生产环境中需要配置生产服务器(比如 nginx、Apache 等)进行反向代理。在本地服务和生产服务配置代理的原理都是一样的,通过搭建一个中转服务器来转发请求规避跨域的问题。

    target: 'http://jsonplaceholder.typicode.com', changeOrigin: true, rewrite: (path) => path.replace(/^\/api/, '') // 正则表达式写法 '^/fallback/.*': { target: 'http://jsonplaceholder.typicode.com', changeOrigin: true, rewrite: (path) => path.replace(/^\/fallback/, '') // 使用 proxy 实例 '/api': { target: 'http://jsonplaceholder.typicode.com', changeOrigin: true, configure: (proxy, options) => { // proxy 是 'http-proxy' 的实例