vue3.x+vite的笔记

下载脚手架(根据提示进行操作)

npm init @vitejs/app

vite内部支持less,scss,stylus预处理,不过需要进行本地的下载

npm install -D sass ( less| stylus )

在脚手架中起别名(使用别名后,当前方法不会有提示,对IDE不友好)
  • 在vite.config.js配置文件中进行操作

  • 使用绝对路径


    image.png

    image.png
  • 在页面中引入组件的时候,直接使用

import HelloWorld from '@/HelloWorld.vue'

注意:

1、vite中对于setup可以有两种写法,一种是在script标签上进行写setup,但是接收props要用defineProps({msg: String})这种写法还有emits等,不过不需要进行return导出
2、还有就是在script下写setup,不过需要return导出

使用动态的组件进行切换
  • 首先在当前的父组件中引入子组件,并进行注册
  • 使用component标签进行展示,使用:is进行组件的切换
  • 动态组件之间的传值,我们可以使用computed计算属性加v-bind进行传递
    当前的父组件





helloworld组件




test组件



声明响应式的属性
  • 1、ref
    • 一般用于声明基本数据类型
    • 使用ref声明的变量,操作时需要使用.value进行
    • 使用ref声明的变量是个深度的响应式数据
    • 可以进行一层的解构赋值,不能进行深度的解构,否则数据就不是响应式的数据了(会导致页面的视图不更新)

ref.js文件

  import { ref } from "vue";

export function testRef() {
  let count = ref(0);
  let list = ref({
    arg: { c: 1, obj: { _c: 2 } }
  });

  const testRefBtn = () => {
    count.value++;
    list.value.arg.c++;
    list.value.arg.obj._c++;
  };

  return {
    count,
    list,
    testRefBtn
  };
}
  • 在当前的页面中引入ref.js文件进行解构并导出就可以了


    image.png
  • 2、reactive

    • 一般用来声明引用数据的
    • 使用reactive声明的数据不能使用解构赋值,否则解构出的数据就不是响应式的数据,可以使用toRefs+扩展运算符将数据在转化为ref,然后再进行解构(好像还是只能解构一层,深层次的解构待查资料中)
    • 一般在导出的时候,我们可以使用...扩展运算符进行展开,不过要是用toRefs属性进行包裹

reactivejs

import { reactive } from 'vue'
export function reactiveTest(){
    let r_arr = reactive([]);
    let r_list = reactive({
        r_c:0,
        r_arg:{
            r_num:1,
            r_obj:{
                r_count:2
            }
        }
    })

    const reactiveBtn = () =>{
        r_list.r_c++;
        r_arr.push(r_list.r_c);
        r_list.r_arg.r_num++;
        r_list.r_arg.r_obj.r_count++;
        console.log(r_list);
    }

    return {
        r_arr,
        r_list,
        reactiveBtn
    }
}

推荐使用图片下的第二个红框,使用扩展运算符搭配toRefs进行展开


image.png
  • 3、readonly

    • 可以将ref,reactive等进行声明的响应式变量转化为只读的,不允许用户进行修改,否则会触发警告
    • 是深层次的只读变量
  • 4、isProxy

    • 检查对象是否是由 reactivereadonly 创建的 proxy。
  • 5、isReactive

    • 检查对象是否是由reactive创建的响应式变量
    • 如果是用reactive创建的变量之后又使用readonly进行包裹,那么也会返回true
    • 如果使用reactive创建的变量之后又使用toRefs进行包裹,那么返回false
    • 如果reactive中声明的对象属性是常量,那么返回false,只有声明的变量中有对象或者是数组等引用类型,才会返回true
    let r = reactive([0]);
    let _r = readonly(r);
    let t = toRefs(r)
    console.log('使用reactive+readonly------',isReactive(_r));//todo true
    console.log('使用reactive+toRefs------',isReactive(t));//todo false
  • 6、isReadonly
    • 检查变量是否由readonly创建的变量
    • 由reactive创建在用readonly包裹返回true
    • 有ref创建基本/引用类型+readonly包裹返回true
    • 直接使用readonly创建基本数据类型返回false
    • 直接使用readonly创建引用数据类型返回true
    let r = reactive([0]);
    let _r = readonly(r);
    let t = readonly(0);
    let _t = readonly({num:0});
    let f = ref(0)
    let tt = readonly(f);

    console.log('使用reactive+readonly------',isReadonly(_r));//todo true
    console.log('使用readonly基本类型------',isReadonly(t));//todo false
    console.log('使用readonly引用类型------',isReadonly(_t));//todo true
    console.log('使用readonly+ref------',isReadonly(f));//todo false
    console.log('使用readonly+ref------',isReadonly(tt));//todo true
  • 7、toRaw
    • 就是返回使用reactive或者readonly创建的原始数据(不是响应式的数据)
    • 不推荐经常使用
    let init = [0]
    let r = reactive(init);
    let _to = toRaw(r)

  console.log('使用reactive+toRaw------',_to);//todo [0]
  console.log('使用reactive+toRaw------',_to===init);//todo true
  • 8、markRaw
    • 标记一个对象,使其永远不会转换为 proxy。返回对象本身。
    • 当前声明的对象是原始值,但是对象中的属性是可以在被reactive等转化为响应式的对象的
    • 转化后的响应式的属性值不等于原始的属性值
    let foo = markRaw({
        num:1
    })

    let _r = reactive({
        num:foo.num
    })
  const btn = ()=>{
        foo.num++;
        _r.num++;
        console.log('reactive----------',_r);//Proxy {num: 2}
        console.log('markRaw----------',foo);//{num: 2, __v_skip: true}
  }
  • 9、shallowReactive
    • 也是声明响应式数据的,但是这个可以说是reactive的一种优化
    • reactive声明的数据是深度的响应式,这个属性声明的响应式数据是浅度的
    • 可以对reactive中的数据进行优化
    • 使用这个属性声明的变量在视图上也是可以进行更新的,但是当前变量中的对象或数组等引用数据类型不会是proxy对象(创建一个响应式代理,它跟踪其自身 property 的响应性,但不执行嵌套对象的深层响应式转换 (暴露原始值))
 const noQiao = shallowReactive({
        count2:3,
        obj1:{
          num:3,
          obj2:{
            aa:3
          }
        }
    })
console.log(isReactive(noQiao.obj1))//false。
isReactive只检测引用的数据类型
  • 10、shallowReadonly
    • 创建一个proxy对象,使其自身为可读属性(浅度)
    • 第一层属性为只读,不可进行修改,否则报黄色警告
    • 第二层或者多层嵌套,可以进行修改
    • 当修改嵌套中的属性的时候,页面视图是不会进行更新的
 export function TestshallowReadonly(){
        let test_readonly = shallowReadonly({
            t_n:0,//浅度不可修改
            t_arg:{//深度可进行修改
                t_c:2
            }
        })

        const add3 = ()=>{
            test_readonly.t_n++;
            test_readonly.t_arg.t_c++
            console.log(test_readonly);
        }
       
        return{
            ...toRefs(test_readonly),add3
        }
  }
  • 11、unref

    • 如果参数是一个 ref,则返回内部值,否则返回参数本身。这是 val = isRef(val) ? val.value : val 的语法糖函数。
    • 总之都会返回值,就是返回值的类型不同,一个是普通变量,一个是响应式的变量
  • 12、toRef

    • 会为某个属性创建一个ref响应式链接的数据
    • 有两个属性,一个是当前的值,必须是对象,第二个是对象中的key
    • 可以为reactive数据中的某个属性,单独的在创建一个ref响应式的,也可以让props中的属性为单一的响应式数据
    • 不能将reactive中的数据解构后在使用toRef,会找不到数据
export function testToRef(){

   let reactive_list = reactive({
       re_foo:1,
       re_arg:{
           re_c:2
       },
       re_num:3
   })

   let toref_foo = toRef(reactive_list,'re_foo');


   const add_toref = () =>{
       reactive_list.re_foo++;
       reactive_list.re_arg.re_c++; 
       由于reactive是响应式的,转化为ref也是响应式的,所以当reactive声明的属性进行加的时候,ref中声明的属性是会跟着变得
       console.log('-reactive_list-----------',reactive_list);
       console.log('-----toref_foo----------',toref_foo.value);
   }

   return{
       ...toRefs(reactive_list),
       toref_foo,
       add_toref
   }
 }
  • 13、toRefs

    • 是为当前对象中的每个属性创建一个ref响应式的链接
    • 一般使其包裹reactive声明的变量,这样解构的时候,就不会将数据的响应式丢失
  • 14、isRef

    • 检查当前的变量是否是ref声明的变量
    • 是的话,直接返回true,不是的话,false
    • 跟isReactive不同,ref声明的不管是引用类型,还是基本类型都是可以进行检查的
  • 15、customRef

    • 可以自定义的创建ref响应式的数据
    • 必须是一个工厂函数
    • 有两个参数track,trigger,返回的参数要有get,set对象
//   自定义ref响应式数据
  export function useDebouncedRef(value, delay = 200) {
    let timeout
    return customRef((track, trigger) => {
      return {
        get() {
          track();
          console.log(track());
          console.log(value);
          return value
        },
        set(newValue) {
          clearTimeout(timeout)
          timeout = setTimeout(() => {
            value = newValue
            trigger()
          }, delay)
        }
      }
    })
  }

export default {
  setup() {
    return {
      searchVal : useDebouncedRef(0)
    }
  }
}

  • 16、computed 计算属性
    • 返回一个不可进行修改的ref响应式数据
const count = ref(1)
const plusOne = computed(() => count.value + 1)
const plusTwo = reactive({
    num: count.value*2
})
const plusThree = computed({
  get: () => count.value + 1,
  set: val => {
    count.value = val - 1
  }
})

plusOne.value = 1 //这是设置的时候,value-1
console.log(count.value) // 0
  • 17、watchEffect
    • 这是初始化页面的时候就会进行监听
    • 有两个属性,操作的时机不同flush: 'post'/'async'
    • 也可以直接使用watchPostEffect,watchSyncEffect这两个函数,是上面的别名(刷新的时机不同,详情百度或者看) 官方文档介绍
    • 页面卸载的时候会自动进行停止监听,也可以返回一个函数进行手动停止监听
    const count = ref(0);
    watchEffect(() => {
        console.log(count.value);----0,----1
    })

    setTimeout(() => {
        count.value++;------1
    }, 200);

const stop = watchEffect(() => {
  /* ... */
})

// later
stop()---------可以将这个停止监听的事件放到点击事件中
  • 18、watch
    • 跟watchEffect相比较,他是惰性的
    • 监听reactive声明的变量,使用函数返回的方式
    • 监听ref声明的变量,直接写就可以
    • 可以监听多种方式,使用数组进行包裹就可以
export function testWatch(){
    let test_reactive = reactive({
        state:0
    })     

    let test_ref = ref(1);

    const add_ref = () =>{
        test_ref.value++
    }

    const add_reactive = ()=>{
        test_reactive.state++
    }
    
    watch(test_ref,(newValue,oldValue)=>{
        console.log('---------ref----新---',newValue)
        console.log('---------ref----旧---',oldValue)
    })

    watch(()=>test_reactive.state,(newV,oldV)=>{
        console.log('---------reactive----新---',newV)
        console.log('---------reactive----旧---',oldV)
    })

    watch([test_ref,()=>test_reactive.state],([newV,newV1],[oldV,oldV1])=>{
        console.log('----------test_ref----新',newV);
        console.log('----------test_reactive----新',newV1);
        console.log('----------test_ref----旧',oldV);
        console.log('----------test_reactive----旧',oldV1);
    })

    return{
        test_ref,
        ...toRefs(test_reactive),
        add_ref,
        add_reactive
        
    }
}
  • 19、expose
    • 如果父组件不通过emit事件进行修改子组件中的数据,而是直接调用子组件中的其他的方法,通过ref是拿不到的
    • 需要通过expose将方法暴露出去,父组件才可以通过ref进行取到数据
 // expose 只能被调用一次。
    // 如果需要暴露多个 property,则它们
    // 必须全部包含在传递给 expose 的对象中。
    expose({
      //将要暴露出去的方法
    })
  • 20、在script标签上使用setup
    • 我们引入的import方法,组件等会被自动解包,直接在模板中使用就可以了
    • 要是接收props使用defineProps 接收,emit使用defineEmits,expose使用defineExpose

  • 在组件中我们可以直接在模板中使用attrs,要是在js中使用通过useSlots,useAttrs

  • 可以跟普通的script标签一起搭配使用

  • 21、全局组件

    • 新建一个all.vue文件,在main.js中引入,注册,在需要引入的地方直接写就可以了
    • 在vite中可能会有缓存,需要修改引入全局组件的父组件,全局组件才会进行显示


      image.png
  • 22、使用defineProps 和 defineEmits接收和传递

    • 在父组件中正常的使用v-bind:属性值,或@自定义事件名
    • 在子组件中使用script setup这种写法进行接收参数和调用
      父组件


子组件



  • 23、 defineExpose
    • 将当前的子组件中的方法,属性,暴露给父组件
    • 在父组件中只能在onMounted生命周期中获取,其他的地方或者生命周期获取不到

子组件


父组件



  • 24、directive(全局)或directives(局部)自定义指令

    • 具体可以查看文档
  • main.js中全局的自定义指令


const app = createApp(App)
   
    // app.component('all-h4', all)
    app.directive('format',{
        mounted(el,binding){
            console.log(el);
            console.log(binding);
            el.innerText = Number(binding.value).toFixed(2);

        }
    })

    app.mount('#app')
  • 在组件中使用自定义指令

vite中env进行生产测试环境变量的切换
  • 1、在当前的项目根目录下创建文件.env.['模式']
  • 2、.env 这个文件是在测试、生产环境中都是可以获取到的,可以进行公共的路径进行提取
  • 3、.env.development 这是测试环境中,我们的请求接口路径
  • 4、.env.production 这是生产环境的
  • 5、.env.local或者是.ent.development/production.local 是提交到git上可以进行忽略不上传
  • 6、在环境变量的文件中要是用VITE_进行开头,否则变量在全局是不会进行暴露,获取不到的
# 本地环境
ENV = 'development / production' 线上和测试这个要进行指定,env公共的就不需要了  

# 本地环境接口地址
VITE_API_URL = '2222'  这个是请求的数据接口路径

在js文件中使用import.meta.env.VITE_API_URL【这个是自己定义的变量】这种方式进行获取就可以了
vite中进行配置axios
  • 下载axios

npm i axios -S-D

  • 新建一个request.js文件进行简单的配置搭配element-plus
import axios from 'axios';
import { ElLoading, ElMessage } from 'element-plus';
const instance = axios.create({
    baseURL: import.meta.env.VITE_API_URL,
    timeout: 1000,
    headers: { 'X-Custom-Header': 'foobar' },
});

let loading;
// 正在请求的数量
let requestCount = 0;
// 显示loading
const showLoading = () => {
    if (requestCount === 0 && !loading) {
        loading = ElLoading.service({
            lock: true,
            text: 'Loading',
            spinner: 'el-icon-loading',
            background: 'rgba(0, 0, 0, 0.7)',
        });
    }
    requestCount++;
};
// 隐藏loading
const hideLoading = () => {
    requestCount--;
    if (requestCount === 0) {
        loading.close();
    }
};
// 请求拦截器
instance.interceptors.request.use(
    (config) => {
        const reqConfig = config;
        // showLoading()
        // 每次发送请求之前判断是否存在token,如果存在,则统一在http请求的header都加上token,不用每次请求都手动添加了
        //   const token = window.localStorage.getItem('token')
        //   if (token) {
        //     reqConfig.headers.Authorization = token
        //   }
        // 若请求方式为post,则将data参数转为JSON字符串
        //   if (reqConfig.method.toLocaleUpperCase() === 'POST') {
        //     reqConfig.data = JSON.stringify(reqConfig.data)
        //   }
        return reqConfig;
    },
    (error) =>
        // 对请求错误做些什么
        Promise.reject(error)
);

// 响应拦截器
instance.interceptors.response.use(
    (response) => {
        // hideLoading()
        // 响应成功
        return response.data;
    },
    (error) => {
        // 响应错误
        if (error.response && error.response.status) {
            const { status } = error.response;
            let message = '';
            const actions = {
                400: '请求错误',
                401: '请求错误',
                404: '请求地址出错',
                408: '请求超时',
                500: '服务器内部错误!',
                501: '服务未实现!',
                502: '网关错误!',
                503: '服务不可用!',
                504: '网关超时!',
                505: 'HTTP版本不受支持',
                20000: '请求失败',
            };
            message = actions[status] ? actions[status] : actions['20000'];
            ElMessage.error(message);
            return Promise.reject(error);
        }
        return Promise.reject(error);
    }
);

const request = (url, method, data = {}, isloading = false) => {
    !isloading && showLoading(); //todo 也可以放到请求拦截的里面中,这里更方便的进行控制
    return new Promise((resolve, reject) => {
        instance({
            method: method,
            url: url,
            data: data,
        })
            .then((res) => {
                console.log('成功-------', res);
                resolve(res);
            })
            .catch((msg) => {
                console.log('失败-------', msg);
                ElMessage.error(msg);
                reject(msg);
            })
            .finally(() => {
                !isloading && hideLoading(); //todo 这个可以放到响应拦截器中,这里进行方便的控制
            });
    });
};

export default request;
vite配置mock,进行模拟请求
  • 首先下载mockjs

npm i mockjs vite-plugin-mock cross-env -D

  • 在vite.config.js中进行配置
import { defineConfig } from 'vite';
import { resolve } from 'path';
import vue from '@vitejs/plugin-vue';
import { viteMockServe } from 'vite-plugin-mock'; 这里进行引入
import Components from 'unplugin-vue-components/vite';
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers';
import ElementPlus from 'unplugin-element-plus/vite';
// https://vitejs.dev/config/
export default defineConfig({
    // 公共路径测试是绝对路径,生产是相对路径
    base: process.env.NODE_ENV === 'production' ? process.env.VITE_PUBLIC_PATH : './',
    plugins: [
        vue(),
        ElementPlus({
            //elementui的样式插件
            importStyle: 'sass',
            useSource: true,
        }),
        Components({
            //elementui 组件的自动导入插件
            resolvers: [ElementPlusResolver()],
        }),
        //todo 配置mockjs模拟请求数据的
        viteMockServe({ supportTs: false }), 这里配置mockjs
    ],
    resolve: {
        //todo 配置别名
        alias: {
            '/@': resolve(__dirname, './src/components'),
        },
    },
    server: {
        proxy: {配置跨域
            //代理(解决跨域问题)
            '/api': {
                target: 'http://localhost:3000/',
                ws: true,
                changeOrigin: true,
                rewrite: (path) => path.replace(/^\/api/, ''),
            },
        },
    },
    // build: {
    //  outDir: 'dist',
    //  minify: 'esbuild',
    //  sourcemap: false,//打包后不生成sourcemap文件
    //  chunkSizeWarningLimit: 1500,
    // },
});
  • 要是项目中有.env.development文件,将里面的默认路径跟vite.config.js中的配置跨域的路径保持一致
  • 最后在项目的根目录下创建一个mock的文件夹,新建一个index.js文件进行模拟接口数据
export default [数组的形式,可以写多个对象形式的接口,也可以只返回一个对象
    {
        url: '/api/get',
        method: 'get',
        response: () => {
            return {
                code: 0,
                data: {
                    name: 'vben',
                },
            }
        },
    },
]
  • 在src文件下,新建一个api文件夹,在新建一个test.js专门将接口进行统一管理
import request from './request';
export const test = () => {
    return request('/api/get', 'get');
};

  • 随便在一个.vue文件中进行请求调用
import { test } from '../api/test.js'

setup(){
  onMounted(()=>{
      这是使用axios进行封装的调用接口
      test().then(data => console.log(data)).catch(msg => console.log(msg))
      这是直接使用内置的fetch进行接口的调用请求
      fetch('/api/get').then(res => res.json()).then(m => console.log(m)).catch(a => {
         console.log(a);
       })
  })
}
vite中进行简单的配置eslint+prettierrc(目前配置的不是很准确,后面会进行深入的)

npm install --save-dev eslint eslint-plugin-vue 这个是没有加ts的eslint,下面的配置是加了ts的eslint,到时候报错的话可以进行下载下或者将下面的配置文件中的ts的eslint进行删除就可以了

  • 在根目录下新建一个.eslintrc.js文件然后就可以进行简单的一些提示
module.exports = {
    root: true,
    env: {
        browser: true,
        es2021: true,
        node: true,
    },
    parser: 'vue-eslint-parser',
    parserOptions: {
        ecmaVersion: 12,
        parser: '@typescript-eslint/parser',
        sourceType: 'module',
    },
    extends: ['plugin:vue/vue3-essential', 'plugin:vue/essential', 'eslint:recommended'],
    plugins: ['vue', '@typescript-eslint'],
    rules: {
        // http://eslint.cn/docs/rules/
        // https://eslint.vuejs.org/rules/
        '@type-eslint/ban-ts-ignore': 'off',
        '@type-eslint/explicit-function-return-type': 'off',
        '@type-eslint/no-explicit-any': 'off',
        '@type-eslint/no-var-requires': 'off',
        '@type-eslint/no-empty-function': 'off',
        '@type-eslint/no-use-before-define': 'off',
        '@type-eslint/ban-ts-comment': 'off',
        '@type-eslint/ban-types': 'off',
        '@type-eslint/no-non-null-assertion': 'off',
        '@type-eslint/explicit-module-boundary-types': 'off',
        'vue/custom-event-name-casing': 'off',
        'vue/attributes-order': 'off',
        'vue/one-component-per-file': 'off',
        'vue/html-closing-bracket-newline': 'off',
        'vue/max-attributes-per-line': 'off',
        'vue/multiline-html-element-content-newline': 'off',
        'vue/singleline-html-element-content-newline': 'off',
        'vue/attribute-hyphenation': 'off',
        'vue/html-self-closing': 'off',
        'vue/no-multiple-template-root': 'off',
        'vue/require-default-prop': 'off',
        'vue/no-v-model-argument': 'off',
        'vue/no-arrow-functions-in-watch': 'off',
        'vue/no-template-key': 'off',
        'vue/no-v-html': 'off',
        'vue/comment-directive': 'off',
        'vue/no-parsing-error': 'off',
        'vue/no-deprecated-v-on-native-modifier': 'off',
        'no-useless-escape': 'off',
        'no-sparse-arrays': 'off',
        'no-prototype-builtins': 'off', //禁止直接调用 Object.prototypes 的内置属性off关闭
        'no-constant-condition': 'off', //禁止在条件中使用常量表达式
        'no-use-before-define': 'off',
        'no-restricted-globals': 'off',
        'no-restricted-syntax': 'off',
        'generator-star-spacing': 'off',
        'no-unreachable': 'off',
        'no-multiple-template-root': 'off',
        'no-unused-vars': 'error',
        'no-v-model-argument': 'off',
        'no-case-declarations': 'off',
        'no-undef': 'off',
        'no-var': 'error', //禁止使用变量var进行声明,修复为let,const
        'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
        'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
        //强制使用单引号
        quotes: ['error', 'single'],
        //强制不使用分号结尾
        semi: ['error', 'never'],
    },
};

  • 在package.json文件中的script中进行配置一个指令
"lint-fix": "eslint --fix --ext .js --ext .jsx --ext .vue src/"
  • 每次进行输入指令npm run lint-fix 就会检查出我们项目中的src目录下的所有文件的语法是否错误,一些简单会自动的帮我们进行修复
  • 根目录下有个.vscode文件夹,在新建一个settings.json(prettierrc这个文件中的配置可能不起作用,只好在这个文件中进行配置了)
{
    "eslint.alwaysShowStatus": true,
    "editor.codeActionsOnSave": {
        "source.fixAll.eslint": true
    },
    //保存自动格式化
    "editor.formatOnSave": true,
    "editor.defaultFormatter": "esbenp.prettier-vscode",
    "eslint.workingDirectories": [{ "mode": "auto" }],
    "eslint.validate": ["javascript", "javascriptreact", "typescript", "typescriptreact", "vue"],
    //根据文件后缀名定义vue文件类型
    "files.associations": {
        "*.vue": "vue"
    },
    //开启 eslint 支持
    "prettier.eslintIntegration": true,
    //使用单引号
    "prettier.singleQuote": false,
    //结尾不加分号
    "prettier.semi": true
}

  • 在项目的根目录下新建一个.prettierrc.js文件
module.exports = {
    // 一行最多多少个字符
    printWidth: 150,
    // 指定每个缩进级别的空格数
    tabWidth: 2,
    // 使用制表符而不是空格缩进行
    useTabs: true,
    // 在语句末尾打印分号
    semi: true,
    // 使用单引号而不是双引号
    singleQuote: true,
    // 更改引用对象属性的时间 可选值""
    quoteProps: "as-needed",
    // 在JSX中使用单引号而不是双引号
    jsxSingleQuote: false,
    // 多行时尽可能打印尾随逗号。(例如,单行数组永远不会出现逗号结尾。) 可选值"",默认none
    trailingComma: "es5",
    // 在对象文字中的括号之间打印空格
    bracketSpacing: true,
    // jsx 标签的反尖括号需要换行
    jsxBracketSameLine: false,
    // 在单独的箭头函数参数周围包括括号 always:(x) => x \ avoid:x => x
    arrowParens: "always",
    // 这两个选项可用于格式化以给定字符偏移量(分别包括和不包括)开始和结束的代码
    rangeStart: 0,
    rangeEnd: Infinity,
    // 指定要使用的解析器,不需要写文件开头的 @prettier
    requirePragma: false,
    // 不需要自动在文件开头插入 @prettier
    insertPragma: false,
    // 使用默认的折行标准 always\never\preserve
    proseWrap: "preserve",
    // 指定HTML文件的全局空格敏感度 css\strict\ignore
    htmlWhitespaceSensitivity: "css",
    // Vue文件脚本和样式标签缩进
    vueIndentScriptAndStyle: false,
    // 换行符使用 lf 结尾是 可选值""
    endOfLine: "lf",
}

vite配置postcss
  • 这个插件有很多的功能,具体可以在GitHub上查看下,这里简单的介绍下几个
  • 可以参考这篇文章https://www.jianshu.com/p/21be605c6ad1
  • vite中是内置支持postcss的,只需要我们将插件进行引入在vite.config.js中进行配置就可以使用了
  • autoprefixer这个插件是当我们使用新的css时,为了兼容老的浏览器,会自动将我们的代码加个前缀

npm install autoprefixer -D

  • 在vite.config.js中进行配置
import { defineConfig } from "vite"
import vue from "@vitejs/plugin-vue"
import autoprefixer from "autoprefixer"//引入插件
// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue()],
  css: {
    postcss: {
      plugins: [autoprefixer],//进行注册
    },
  },
})
  • 还需要进行兼容浏览器的版本,不可能是全部浏览器的版本都可以进行添加,那就太多了,需要有个限制进行约束在package.json中


    image.png
  • 或者在根目录下新建.browserslistrc文件,不用逗号,换行就行
 > 1%
 last 2 versions
  • 具体可以参考这篇文章https://www.jianshu.com/writer#/notebooks/49948771/notes/86532182/preview
  • 然后当我们的项目打包后,就会将display:flex;加上一些前缀

你可能感兴趣的:(vue3.x+vite的笔记)