• 近期分享学习心得3


    看文档是解决问题最快的方式

    1、全屏组件封装

    先看之前大屏端的监控部分全屏代码
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    整块全屏代码
    常规流是下面这种

    //进入全屏
    function full(ele) {
          //if (ele.requestFullscreen) {
          //    ele.requestFullscreen();
          //} else if (ele.mozRequestFullScreen) {
          //    ele.mozRequestFullScreen();
          //} else if (ele.webkitRequestFullscreen) {
          //    ele.webkitRequestFullscreen();
          //} else if (ele.msRequestFullscreen) {
          //    ele.msRequestFullscreen();
          //}
    
    		const funcNames=[
    			'requestFullscreen',
    			'mozRequestFullScreen',
    			'webkitRequestFullscreen',
    			'msRequestFullscreen',
    		]
    		const name=funcNames.find(funcName=>funcName in ele)
    		name&&ele[name]()
    }
    //退出全屏
    function exitFullscreen() {
        if(document.exitFullScreen) {
            document.exitFullScreen();
        } else if(document.mozCancelFullScreen) {
            document.mozCancelFullScreen();
        } else if(document.webkitExitFullscreen) {
            document.webkitExitFullscreen();
        } else if(document.msExitFullscreen) {
            document.msExitFullscreen();
        }
    }
    //监控全屏
     window.onresize = () => {
        // 全屏下监控是否按键了ESC
        //that.isFull = this.isFullScreenFunc()
    }
    //判断全屏
    isFullScreenFunc() {
          return !!(
            document.fullscreen ||
          document.mozFullScreen ||
          document.webkitIsFullScreen ||
          document.webkitFullScreen ||
          document.msFullScreen
          )
        },
    //获取全屏节点
    function getFullscreenElement() {
        return (        
            document.fullscreenElement ||
            document.mozFullScreenElement ||
            document.msFullScreenElement ||
            document.webkitFullscreenElement||null
        );
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57

    提高

    function getPropertyName(names,target){
    	return names.find(name=>name in target)
    }
    const enterFullScreen=getPropertyName([
    	'requestFullscreen',
    	'mozRequestFullScreen',
    	'webkitRequestFullscreen',
    	'msRequestFullscreen',
    ],document.documentElement)
    export function enter(ele){
    	enterFullScreen&&ele[enterFullScreen]()
    }
    //获取全屏节点
    const fullEleName=getPropertyName([
    	'fullscreenElement',
    	'mozFullScreenElement',
    	'msFullScreenElement',
    	'webkitFullscreenElement',
    ],document.documentElement)
    export function getElement(){
    	return document[fullEleName]||null
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    在这里插入图片描述

    2、任务执行的洋葱模型(存疑,后期回顾)

    在这里插入图片描述
    在这里插入图片描述
    KOA洋葱模型

    3、状态库持久化(存疑,后期回顾)

    状态库vuex和pinia,存储在内存中,一旦刷新数据没了,在和同事探讨时,发现数据是存储在session和local里,再取出来
    1、vuex

    2、pinia

    4、统一vite中的图片转换逻辑

    在这里插入图片描述
    一张小图一张大于4M大图,
    开发环境里打印的是正常绝对路径,
    生产环境大于4M图自动变成base64
    在这里插入图片描述
    第一种方法是动生产环境,修改配置,小于4096就自动转换,改成0
    在这里插入图片描述
    第二种方法是动开发环境,自己写vite插件,
    在这里插入图片描述
    写个插件小于4096在开发环境转成base64,
    【题外:code ai代码补全】
    在这里插入图片描述
    打印的id是文件的绝对路径
    在这里插入图片描述
    导入fs模块
    import fs from ‘node:fs’

    await fs.promise.stat(id)//stat文件状态,是异步的
    
    • 1

    下面是上面await的打印对象
    在这里插入图片描述
    在这里插入图片描述
    如果大于4096才需要转换,
    读取文件,是buffer对象,转base64
    在这里插入图片描述
    vite是由esbuild和rollup组成,
    transform是rollup的钩子函数,做代码转换用的
    在这里插入图片描述

    5、读取原始文件内容

    需求是:把写死的base64放在图片img标签src下
    但是这样写不太优雅
    提取出去,比方说放在同级的img.dataUrl文件下,随便取的
    1、vue-cli
    import dataUrl from ‘./img.dataUrl’
    在这里插入图片描述

    直接导入会报错,没有loader来处理的错误
    在这里插入图片描述
    整个vue是用webpack搭建的,默认可以处理*.js文件,于是其他文件需要loader来处理
    .css css-loader
    img file
    但是
    .dataUrl没有loader来处理
    所以需要配置loader,我们是希望获得文件内容,所以需要用到raw-loader

    如何在vue-cli里面配置webpack
    在这里插入图片描述
    2、vite
    直接加?raw
    在这里插入图片描述

    6、.env.production文件的变量获取不到

    只有 NODE_ENV,BASE_URL 和以 VUE_APP_ 开头的变量
    在这里插入图片描述

    7、参数归一化

    lodash
    在这里插入图片描述
    在这里插入图片描述
    最强大的就是函数形式

    // 格式化时间函数,参数归一化 该函数主要用来处理不用的 参数类型 例如 'date' 'datetime' 'yyyy-MM-dd HH:mm:ss' 等等
    
    function _formatNormalize(formatter) {
      if (typeof formatter === 'function') {
        return formatter;
      }
      if (typeof formatter !== 'string') {
        throw new TypeError('formatter must be a string');
      }
      if (formatter === 'date') {
        formatter = 'yyyy-MM-dd';
      } else if (formatter === 'datetime') {
        formatter = 'yyyy-MM-dd HH:mm:ss';
      } else if (formatter === 'date') {
        formatter = 'yyyy-MM-dd';
      }
      //将格式化好的formatter里面的占位符替换成真实数据
      const formatterFunc = (dateInfo) => {
        return formatter.replace(/yyyy|MM|dd|HH|mm|ss|SSS/g, (matched) => {
          return dateInfo[matched];
        });
        //replace用法
      };
      return formatterFunc;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    上方代码是下面代码的优化
    在这里插入图片描述

    // 格式化时间函数
    function formatDate(date, formatter, isPad = true) {
      formatter = _formatNormalize(formatter);
      const dateInfo = {
        year: date.getFullYear(),
        month: date.getMonth() + 1,
        date: date.getDate(),
        hour: date.getHours(),
        minute: date.getMinutes(),
        second: date.getSeconds(),
        miniSecond: date.getMilliseconds()
      };
    
      //再写一份用来匹配规则
      const dateFeildArr = ['yyyy', 'MM', 'dd', 'HH', 'mm', 'ss', 'SSS'];
      const dateInfoKeys = Object.keys(dateInfo);
      dateFeildArr.forEach((feild, index) => {
        dateInfo[feild] = dateInfo[dateInfoKeys[index]].toString();
      });
    
      function _pad(prop, len = 1) {
        dateInfo[prop] = dateInfo[prop].padStart(len, '0');
      }
    
      if (isPad) {
        dateFeildArr.forEach((feild) => {
          const len = feild.length;
          _pad(feild, len);
        });
      }
      return formatter(dateInfo);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    padStart() 方法有两个参数:

    • padLength 是填充后的结果字符串的长度。如果 padLength 小于字符串的长度,则字符串按原样返回,没有填充。
    • padString 是一个可选参数,用于填充字符串。此参数的默认值为“ ”。如果 padString 大于
      padLength,padString 将被截断,只填充最左边的部分。

    8、props单向数据流

    在这里插入图片描述
    禁止props里的值直接修改,因为要保护单项数据流
    父传子,子组件直接修改的话,会导致数据脱钩,
    比方说,下图的子组件修改了变成3,父组件没修改,还是8,导致显示异常
    在这里插入图片描述
    只有数据的拥有者有资格修改数据
    在这里插入图片描述
    用$emit(或其他)抛出事件给父组件,然后props单向

    9、优雅导入组件等文件

    index.js

    // 三个参数
    // directory {String} -读取文件的路径
    // useSubdirectories {Boolean} -是否遍历文件的子目录
    // regExp {RegExp} -匹配文件的正则
    // require.context(‘./test’, false, /.test.js$/);
    // 上面的代码遍历当前目录下的test文件夹的所有.test.js结尾的文件,不遍历子目录
    const contexts = require.context('./', false, /\.vue$/)
    const components = []
    let removeList = [] //要排除某个文件
    contexts.keys().forEach(key => {//遍历子目录
        const name = key.replace(/(\.\/|\.vue)/g, '')
        removeList.includes(name) ? '' : components[name] = resolve => require([`${key}`], resolve)
    })
    //由export default改为 export
    export {
        components
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    在这里插入图片描述

    10、prop

    父组件给子组件通常通过props传值,如果需要做一些强校验则可以使用validator
    如父组件传入一个propType参数,规定只能传入’text’, 'number’或者’letter’其中一种就可以这么写:

    props: {
    	propType: {
    		type: String,
    		default:  'text',
    		validator() {
    			return ['text', 'number','letter'].indexOf(propType) > -1
    		}
     	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    又或者你想传入一个参数,但是想限制它的长度,那你也可以使用validator进行强校验

    props: {
    	lintLength: {
    		type: Array,
    		default: () => [],
    		validator() {
    			return lintLength.length < 6
    		}
     	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    11、插槽

    深受启发
    https://blog.csdn.net/weixin_66375317/article/details/124673576

    11.1、默认插槽(自动填坑)

    在这里插入图片描述

    11.2、具名插槽(对应填坑)

    v-slot: 可以简化成#
    在这里插入图片描述

    11.3、作用域插槽(携带参数)

    在这里插入图片描述
    默认插槽 =》1. 子组件标签下不使用template写html结构 2. 子组件通过
    具名插槽 => 1. 子组件标签下使用template =》包裹传递html结构 =》template上提供名字#插槽名 2. 子组件通过传递数据=》子传父
    作用域插槽=> 1. 子组件 2. 父组件=》