vue3+vite脚手架配置

环境要求:vite及vue3需要node版本大于12

# 1. vue3的优势

  1. 性能比Vue2.x快1.2~2倍
  • diff方法优化: vue2中的虚拟dom是全量的对比(每个节点不论写死的还是动态的都会比较), vue3新增了静态标记(patchflag)与上次虚拟节点对比时,只对比带有patch flag的节点(动态数据所在的节点);可通过flag信息得知当前节点要对比的具体内容
  • 静态提升 vue2无论元素是否参与更新,每次都会重新创建然后再渲染 vue3对于不参与更新的元素,会做静态提升,只会被创建一次,在渲染时直接复用即可
  • 时间侦听器缓存 默认情况下onClick会被视为动态绑定,所以每次都会追踪它的变化 但是因为是同一个函数,所以不用追踪变化,直接缓存起来复用即可
  1. 按需编译,体积比vue2.x更小
  2. 组合API(类似react hooks)
  3. 更好的Ts支持
  4. ...

# 2. vite的优势

就一个字:快

这个快体现在开发时的编译和热更新上。 webpack会先打包,然后启动开发服务器,请求服务器时直接给予打包结果。

而vite是直接启动开发服务器,请求哪个模块再对该模块进行实时编译。 由于现代浏览器本身就支持ES Module,会自动向依赖的Module发出请求。vite充分利用这一点,将开发环境下的模块文件,就作为浏览器要执行的文件,而不是像webpack那样进行打包合并。

由于vite在启动的时候不需要打包,也就意味着不需要分析模块的依赖、不需要编译,因此启动速度非常快。当浏览器请求某个模块时,再根据需要对模块内容进行编译。这种按需动态编译的方式,极大的缩减了编译时间,项目越复杂、模块越多,vite的优势越明显。 在HMR(热更新)方面,当改动了一个模块后,仅需让浏览器重新请求该模块即可,不像webpack那样需要把该模块的相关依赖模块全部编译一次,效率更高。

  • 简洁的说,就是vite在开发编译的时候,动态编译,哪个改了编译哪个。而webpack是要把该模块的相关依赖模块编译一次
  • 注意点: 由于vite利用的是ES Module,因此在代码中(除了vite.config.js里面,这里是node的执行环境)不可以使用CommonJS. 也就是说不能使用require

# 3. 创建一个vite项目

cmd 进入你想要创建项目的文件夹

npm init @vitejs / app
//然后按提示操作

@vitejs/create-app is deprecated, use npm init vite instead

√ Project name: ... test project
√ Package name: ... test-project
√ Select a framework: » vue
√ Select a variant: » vue-ts

Scaffolding project in D:\zhuyunjing\src\test\test project...

Done. Now run:

  cd test project
  npm install
  npm run dev

安装好依赖启动就可以了

也可以直接命令行添加参数

# npm 6. x
npm init @vitejs / app my - vue - app--template vue

# npm 7 + , 需要额外的双横线:
npm init @vitejs / app my - vue - app-- --template vue

# yarn
yarn create @vitejs / app my - vue - app--template vue

# 4. vite.config.js

这个文件就相当于vue.config.js的作用,基本写法也类似

import {
    defineConfig
} from 'vite'
import vue from '@vitejs/plugin-vue'
import {
    resolve
} from 'path'
import copy from 'rollup-plugin-copy' //引入插件
import viteCompression from 'vite-plugin-compression';

export default defineConfig({
    plugins: [
        vue(),
        // viteCompression(),  //gzip压缩,需要服务端支持
    ],
    resolve: {
        alias: {
            '@': resolve('./src'),
        },
    }, //别名
    base: './',
    server: {
        port: 8010, // 服务端口号
        open: true, // 服务启动时是否自动打开浏览器
        cors: true, // 允许跨域
        proxy: {
            '/dealerWebApi': {
                target: 'http://192.168.100.107:30058/',
                changeOrigin: true,
                rewrite: (path) => path.replace(/^\/dealerWebApi/, ''),
            },
        },
    },
    // 生产环境移除console
    build: {
        terserOptions: {
            compress: {
                drop_console: true,
            },
        },
        rollupOptions: {
            output: {
                //设置打包后的路径
                entryFileNames: `js/app.[hash].js`,
                chunkFileNames: `js/chunk.[hash].js`,
                assetFileNames: `assets/[hash].[ext]`
            }
        }
    }
})

# 5. Router的配置

// 利用createRouter方法创建路由。有createWebHistory和createWebHashHistory良种模式
import {
    createRouter,
    createWebHashHistory
} from 'vue-router'

const routes = [{
    path: '/userinfo',
    name: 'UserInfo',
    component: () => import('../views/UserInfo.vue')
}]
// hash模式
const router = createRouter({
    history: createWebHashHistory(),
    routes,
})
// histtory模式
const router = createRouter({
    history: createWebHistory(
        import.meta.env.VITE_APP_BASE_API),
    routes
})

# 6. postCss适配

安装 "postcss-pxtorem",然后添加postcss.config.js

module.exports = {
    plugins: {
        'autoprefixer': {
            overrideBrowserslist: [
                "Android 4.1",
                "iOS 7.1",
                "Chrome > 31",
                "ff > 31",
                "ie >= 8"
                //'last 2 versions', // 所有主流浏览器最近2个版本
            ],
            grid: true
        },
        'postcss-pxtorem': {
            rootValue: 100, //结果为:设计稿元素尺寸/100,比如元素宽100px,最终页面会换算成 1rem
            propList: ['*']//对于哪些css生效,可以写['*', '!border*']意思是排除带有border的属性
            selectorBlackList: []. //忽略的选择器,可以将vant或者ant的文件去除,但是不推荐,因为去除了就不能适配了。
        }
    }
}

然后创建一个rem.js

export default class RemInit {
  public setRem(): void {

    // 基准大小
    const baseSize = 100
    const basePc = baseSize / 1920 // 表示1920的设计图,使用100PX的默认值
    let vW = window.innerWidth // 当前窗口的宽度
    const vH = window.innerHeight // 当前窗口的高度
    // 非正常屏幕下的尺寸换算
    const dueH = (vW * 937) / 1920 // PC 去掉地址栏高度取 设计稿取 1920 * 937
    if (vH < dueH) {
      // 当前屏幕高度小于应有的屏幕高度,就需要根据当前屏幕高度重新计算屏幕宽度
      vW = (vH * 1920) / 1080
    }
    const rem = vW * basePc // 以默认比例值乘以当前窗口宽度,得到该宽度下的相应font-size值
    document.documentElement.style.fontSize = rem + 'Px'

  }
}
export const remInit = new RemInit()

在main.js引入一下

import { remInit } from './utils/RemInit'
remInit.setRem()
window.onresize = function () {
  remInit.setRem()
}

这样设置之后,在css写100px,在渲染时会自动变成1rem。而根元素的fontSize会根据实际的比例进行缩放,默认是100.这样的话,在1920*1080的分辨率下,写100px,页面会渲染成1rem,且对应的实际尺寸还是100px。就正常按设计稿的尺寸去写就醒了。

# 7. 环境变量

除了内置的变量以外,其他的要以VITE_APP_XXXX开头。 使用的时候 import.meta.env. VITE_APP_BASE_API。其他的和webpack一样的,再packge.js设置不同的mode

# 8. 全局注册组件

因为vite环境里用不了require,所以找了替代方法,效果差不多

import {
    App
} from 'vue'
/*
 **全局注册组件
 ** 放在components/global文件夹下
 */
const modulesFiles =
    import.meta.globEager('/src/component/global/*.vue') /// import.meta.globEager用来代替require因为vite不支持node语法require
const globalResult = Object.keys(modulesFiles).filter(item => true)
export default (app: App < Element > ) => {
    globalResult.forEach(item => {
        const component = modulesFiles[item]?.default
        app.component(component.name, component)
    })
}

# 9. Composition-API 的优势实现代码分离。

  • 代替mixins 用多了会比较混乱,由于API是基于函数的,因此可以有效地组织和编写可重用的代码。实现代码分离。
  • 在Vue应用程序中更好地使用TypeScript。
  • Composition-API 不是给你写一堆代码再setup里面的,要适当地分离、组织

# 10. setUp函数拆分

//创建一个js
import {
    ref
} from 'vue'

export function useBigImg(pageOption ? : PageOption) {
    const bigImgShow = ref < boolean > (false)
    const bigImgSrc = ref < string > ('')
    const showModal = (src: string) => {
        bigImgSrc.value = src
        bigImgShow.value = true;
    };
    onMounted(() => {
            console.log('111111)
            })

        return {
            bigImgShow,
            bigImgSrc,
            showModal
        }
    }

然后在vue文件中引用,就可以再html里用了

import {
    useBigImg
} from './index
export default defineComponent({
    name: 'ITable',
    props,
    emits: ['handleTableChange'],
    setup(props, context) {
        //预览图放大功能
        const {
            bigImgSrc,
            showModal,
            bigImgShow
        } = useBigImg()

        return {
            bigImgSrc,
            showModal,
            bigImgShow,
        }
    },
})

这种拆分可以在任何文件里倒入,类似于hooks的方法。一般以useXXX命名

rtsp视频流播放

rtsp视频流播放

vue数据更新但页面不刷新的7中情况

vue数据更新但页面不刷新的7中情况