开发记录

191 阅读1分钟

1、v-show 不生效? (vue)

v-show指令是控制display:none作为显示隐藏的。但有些UI框架组件的display优化级会更高,所以无法达到预期效果。

2、$emit的返回值 (vue)

$emit的返回值为当前组件的this。如果需要父组件的一些响应操作,可以利用emit 可以传多参数的属性,传一个回调函数过去,父组件在适应的时机调用

// son
this.$emit('hello', '123', (str) => console.log(str))

// parent
handleHello(data, callback) {
    callback('我是你需要的数据')
}

3、canvas 尺寸问题

如果使用css 设置width height 会出现拉伸(默认300px * 150px),模糊等问题。但如果不用css 设置,在2倍屏以上会出现设计稿还原问题。

      // 把样式的宽高赋值给原本的宽高属性,注意要清除px单位
      const el = document.getElementById("c1");
      el.width = el.style.width.replace("px", "");
      el.height = el.style.height.replace("px", "");

4、自动化加载目录下的正则匹配上的文件

一个webpack的api,通过执行require.context函数获取一个特定的上下文,主要用来实现自动化导入模块

// 自定义指令
// 加载当前module目录下的所有.js文件
const files = require.context("./module", false, /\.js$/);
const directives = {};
files.keys().forEach((key) => {
  const name = key.match(/\.\/([\s\S]*)\.js/)[1];
  if (name) {
    directives[name] = files(key).default || files(key);
  }
});

export default {
  install(Vue) {
    Object.keys(directives).forEach((key) => {
      Vue.directive(key, directives[key]);
    });
  },
};

5、异步函数异常,外部无法try catch问题

主要是异步函数和执行的同步函数不在同一执行栈 call stack里面,所以无法try catch

   !function () {
       try {       
           setTimeout(() => {
               throw new Error('test')
           })
       }catch(e) {
           console.log(e)
       }

   }()
  1. 如果是callback,nodejs 有个error-firstcallback规范,不要throw error,而是把error当做回调的第一个参数,回传。
  2. promise 内部如果发生异常,会在最近的catch里面处理,如果没有,全局异常。
   const promise = new Promise((resovle,reject) => {
       setTimeout(() => {
           reject(new Error('test'))
       })
   })
   promise.catch(e => console.log(e))
  1. async await 终极
   !function(){
       async function createError() {
            setTimeout(() => {
                if (Math.random() > 0.5) {
                    throw new Error('i am error')
                } else {
                    console.log('none error')
                }
            })

       }
       async function test() {
           try {       
               await createError()
               await createError()
           }catch(e) {
               console.log('async', e)
           }
       }
       test()
   }()

6、Math.random 检查不安全

    // Generate a random integer r with equal chance in min <= r < max.
    function randrange(min, max) {
      var range = max - min;
      if (range <= 0) {
        throw new Error("max must be larger than min");
      }
      var requestBytes = Math.ceil(Math.log2(range) / 8);
      if (!requestBytes) {
        // No randomness required
        return min;
      }
      var maxNum = Math.pow(256, requestBytes);
      var ar = new Uint8Array(requestBytes);

      // eslint-disable-next-line no-constant-condition
      while (true) {
        // 核心
        window.crypto.getRandomValues(ar);

        var val = 0;
        for (var i = 0; i < requestBytes; i++) {
          val = (val << 8) + ar[i];
        }

        if (val < maxNum - (maxNum % range)) {
          return min + (val % range);
        }
      }
    }

7、devServer 配置简单mock数据

// config
  devServer: {
    // 跨域请求
    port: process.env.PORT || xxxx,
    proxy: {
      "/api": {
        target: SERVICE_HOST,
        changeOrigin: true,
        secure: false,
        pathRewrite: {
          "/api": "",
        },
        bypass: function(req, res) {
          if (req.headers.accept.indexOf("html") !== -1) {
            return "/index.html";
          } else if (process.env.MOCK === "yes") {
            const name = req.path
              .split("/api/")[1]
              .split("/")
              .join("_");      // 把api路径转为_命名的的文件名
            // 不存在的文件,会走回原有的api请求
            try {
              const mock = require(`./mock/${name}`);
              const result = mock(req.method);
              delete require.cache[require.resolve(`./mock/${name}`)];
              return res.send(result);
            } catch (e) {}
          }
        },
      },
    },
  },
  
  // mock文件
  
  function data(method) {
  let res = null;
  switch (method) {
    case "POST":
      res = {
        Code: 0,
        Message: null,
        HasError: false,
        Result: {
          Total: 6,
          TotalNumber: 40,
          TotalArea: (Math.random() * 100000).toFixed(2),
        },
      };
      break;
    default:
      res = null;
  }
  return res;
}

module.exports = data;

8、axios baseUrl 设置问题

  1. url 为绝对地址,不会使用baseUrl;
  2. url 相对地址,如果设置baseUrl,但拼接上baseUrl后也是相对地址,再会拼接上当前访问前缀;
  3. url 相对地址,如果设置baseUrl,但拼接上baseUrl后也是绝对地址,就直接发送;

9、webpack splitchunkPlugin

主要参数说明

-> chunks: async(默认 异步引入) initial(同步引入的) all (推荐)

10、axios 一个项目中如果需要使用多个axios

axios 需要实例化,把实例上配置拦截器,请求头,默认配置之类等参数

import axios from "axios";
const instance = axios.create();
instance.defaults.headers["Content-Type"] = "application/json";
instance.interceptors.request.use(
  config => {
  })
  
export const Axios = instance;

11、process.env添加新KEY

    // vue.config.js
    config.plugins.push(
      new webpack.DefinePlugin({
        "process.env": {
          LANG: '"' + process.env.LANG + '"',
          SERVICE_HOST: '"' + process.env.SERVICE_HOST + '"',
        },
      }),
    );

12