Git Product home page Git Product logo

docs's People

Contributors

imondo avatar

Stargazers

 avatar  avatar

Watchers

 avatar

docs's Issues

VUE项目打包修改相对路径

vue-cli打包修改相对路径

config/index.js文件

build: {
 assetsPublicPath: './'
}

build/utils.js

const extractLoader = {
    loader: MiniCssExtractPlugin.loader,
    options: {
      publicPath: '../../'
    }
}
...
if (options.extract) {
   loaders.push(extractLoader)
} else {
   loaders.push('vue-style-loader')
}

Vue中对setInterval的清除方案

vue定义到datasetInterval轮询时,无法清除。

处理方案:

const polling = setInterval(() =>{                    
    // do something                
}, 1500); 
this.$once('hook:beforeDestroy', () => {            
    clearInterval(polling);                                    
})

实现队列输出

      // function start(id) {
      //   setTimeout(() => {
      //     execute(id).catch(console.error)
      //   }, id * 1000)
      // }

       function start(id) {
         this.promise = this.promise
           ? this.promise.then(_ => execute(id))
           : execute(id);
       }

      // 测试代码 (请勿更改):

      for (let i = 0; i < 5; i++) {
        start(i);
      }

      function sleep() {
        const duration = Math.floor(Math.random() * 500);
        return new Promise(resolve => setTimeout(resolve, duration));
      }

      function execute(id) {
        return sleep().then(() => {
          console.log("id", id);
        });
      }

vue项目浏览器缓存解决

浏览器缓存statusCode区别

  • 200 OK (from cache)* 是直接点击链接访问,输入网址按回车访问也能触发;浏览器没有跟服务器确认,直接用了浏览器缓存;

  • 304 Not Modified 是刷新页面时触发,或是设置了长缓存、但 Entity Tags 没有移除时触发;是浏览器和服务器确认了一次缓存的有效性,再使用缓存,多一次确认

vue项目首页index.html强制去掉缓存

// index.html
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="0">

// nginx
location /demo{
   add_header Cache-Control 'private, no-store, max-age=0';
   alias  /opt/nginx-front/test/demo;
   index  index.html;
   try_files $uri $uri/ /demo/index.html;
 }

小心你的箭头函数

使用箭头函数你要格外的小心;箭头函数运行时候bind this

场景:

  • 定义对象方法

  • 定义原型方法

  • 定义构造函数

  • 定义事件回调函数

箭头函数没有定义this绑定

var obj = {
  i: 10,
  b: () => console.log(this.i, this),
  c: function() {
    console.log( this.i, this)
  }
}
obj.b(); 
// undefined, Window{...}

Taro中Swiper组件卡片3D化

DOM格式

        <View className="college-container">
          <Swiper
            className="swiper-block"
            circular
            autoplay
            current={this.state.current}
            previous-margin="32rpx"
            next-margin="32rpx"
            onChange={this.handleChange.bind(this)}
          >
            {list.slice(0, 1).map(item => {
              return (
                <SwiperItem className="swiper-item">
                  <FallbackImage src={item.content.posterPath} directory={false}/>
                </SwiperItem>
              );
            })}
          </Swiper>
        </View>

样式

.index-wrapper {
  .college-container {
    display: flex;
    flex-direction: column;
  }

  .swiper-block {
    height: 258px;
    width: 100%;
  }

  swiper-item {
    width: 620px !important;
    height: 258px !important;
  }

  .swiper-item {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: flex-start;
    overflow: unset;
  }

  .swiper-image {
    height: 258px;
    width: 620px;
    border-radius: 9px;
    box-shadow: 0 2px 14px 0 rgba(0, 0, 0, 0.10);
    margin: 0px 32px;
    z-index: 1;
    transform: scale(0.9);
  }

  .active {
    transform: scale(1);
    transition: all 0.2s ease-in 0s;
    z-index: 20;
  }
}

vuex在actions挂载相同的函数

// a.js
actions: {
  same(){
    ...
  }
}
// b.js
actions: {
  same(){
    ...
  }
}

disaptch('same');

执行这个same的函数时都会触发

但执行的顺序跟store模块顺序有关,先引入先执行。

export default new Vuex.Store({
  modules: {
    a,
    b
  }
});

JS原生操作DOM

// 克隆元素
const cloneNode = dom.cloneNode(true);

// 创建元素,插入子元素
const exportNode = document.createElement('div').appendChild(cloneNode);

// 设置元素样式
exportNode.style = 'display: none';

// 查找元素,返回元素arr
const checkBoxNode = exportNode.querySelectorAll('.el-table-column--selection');
const displayNoneNode = exportNode.querySelectorAll('[style*="display: none"]');

// 设置元素属性
thNode.setAttribute('colspan', 10);

trNode.appendChild(thNode);

// 插入到existingDom[0]元素前
dom.insertBefore(trNode, existingDom[0]);

// 移除DOM
dom.remove();

Vue对window监听scroll无效

window.addEventListener('scroll', () => {
    this.handleScroll();
}, false)

去掉App.vueoverflow:auto可实现监听

Blob下载

前端可以使用Blob来下载文件

具体代码如下

const blob = res.response;
const reader = new FileReader();
reader.readAsDataURL(blob); // 转换为base64,可以直接放入a表情href
const disposition = decodeURI(xhr.getResponseHeader('Content-Disposition'));
const dispositionArray = disposition.split('filename=');
const name = dispositionArray[dispositionArray.length - 1];
reader.onload = function(e) {
  // 转换完成,创建一个a标签用于下载
  const a = document.createElement('a');
  a.download = name;
  a.href = e.target.result;
  document.body.appendChild(a);
  a.click();
  document.body.removeChild(a);
};

还可以通过后台返回的数据来判断错误提示

const reader = new FileReader();
reader.onload = e => {
  if (!e.target.result.includes('%PDF')) {
    const result = JSON.parse(e.target.result);
    Message({
      message: result.msg,
      type: 'warning'
    });
  }
};
reader.readAsText(res.response);

ElInput的change 事件无效

ElInput的change 事件现在仅在输入框失去焦点或用户按下回车时触发,与原生 input 元素一致。如果需要实时响应用户的输入,可以使用 input 事件

大数据Array循环性能问题

对于数据量> 1000的数组操作

  • 大量数据可先定义缓存数组arr长度,再循环添加元素

  • 优先使用for i++循环

  • 赋值时注意缓存

let postData = [];
let _projectId = $('[name="projectId"]').val();
let _rogId = $('[name="orgId"]').val();
postData.length = tableData.length;
console.log(new Date());
for (let i = 0, len = tableData.length; i < len; i++) {
  postData[i] = {
    projectId: _projectId,
    id: tableData[i].id
    req: { orgId: _rogId }
  };
}

流图片数据显示

需要对请求设置 { responseType: 'blob' }
根据返回来的流Blob数据处理

window.URL.createObjectURL(blob);

递归获取树结构路径

const routePath = getRoutePath(this.routers, parentPath);
const path = routePath.join('/');
console.log(path) // /school/instrument/assetin

const getRoutePath  = (data, target) => {
      let flag = false;
      const path = [];
      const whileRoutePath = (data, target) => {
        for (let i = 0; i < data.length; i++) {
          const route = data[i];
          if (!flag) {
            if (i > 0) {
              path.pop();
            }
            path.push(route.path);
            if (route.path === target) {
              flag = true;
              return;
            } else {
              const children = route.children;
              if (children) {
                whileRoutePath(children, target);
              }
            }
          }
        }
        if (!flag) {
          path.pop();
        }
        return;
      };
      whileRoutePath(data, target);
      return path;
    }

https抛出This request has been blocked; the content must be served over HTTPS异常

HTTPS页面里动态的引入HTTP资源,比如引入一个js文件,会被直接block掉的.在HTTPS页面里通过AJAX的方式请求HTTP资源,也会被直接block掉的。

可以在相应的页面的里加上这句代码,意思是自动将http的不安全请求升级为https

<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">

input对中英文输入法判断

  <el-input
    v-model="barcode"
    @compositionstart.native="start"
    @compositionend.native="end"
  ></el-input>
  methods: {
    start() { // 中文开始输入
      this.composing = true;
    },
    end() { // 输入结束
      this.composing = false;
      this.barcode = '';
    }
 }

axios封装

// 设置请求统一信息
import axios from 'axios';
import store from '../store/index.js';
import qs from 'qs';
import { messages } from './msg-box.js';
import { logout } from './logout.js';

const service = axios.create({
  timeout: 300000, // 超时设置
  withCredentials: true // 跨域请求
});

let hasLogoutStatus = false; // 是否某个请求存在需要退出的状态

const queue = []; // 请求队列

const CancelToken = axios.CancelToken; // axios内置的中断方法

/**
 * 拼接请求的url和方法;
 * 同样的`url + method` 可以视为相同的请求
 * @param {Object} config 请求头对象
 */
const token = config => {
  return `${config.url}_${config.method}`;
};

/**
 * 中断重复的请求,并从队列中移除
 * @param {Object} config 请求头对象
 */
const removeQueue = config => {
  for (let i = 0, size = queue.length; i < size; i++) {
    const task = queue[i];
    if (!task) return;
    // 出现401,403状态码中断后续请求
    const isLogout = token(config).includes('logout');
    // 退出接口跳过中断逻辑
    if (!isLogout && hasLogoutStatus) {
      task.token();
      queue.splice(i, 1);
    } else {
      const cancelMethods = ['post', 'put', 'delete']; // 需要中断的请求方式
      const { method } = config;
      if (cancelMethods.includes(method)) {
        if (task.token === token(config)) {
          task.cancel();
          queue.splice(i, 1);
        }
      }
    }
  }
};

/**
 * 请求错误统一处理
 * @param {Object} response 错误对象
 */
const errorHandle = response => {
  const { status, data: { message }} = response;
  let msg = message;
  if (!message) {
    switch (status) {
      case 401:
        msg = '您没有权限访问此操作!';
        break;
      case 403:
        msg = '您的登录状态已失效,请重新登录。';
        break;
      case 424:
        msg = response.data.error;
        break;
      default:
        msg = '请求失败!';
    }
  }
  hasLogoutStatus = status === 401 || status === 403;
  if (hasLogoutStatus) {
    messages('error', msg, () => {
      logout();
    });
  }
  messages('error', msg);
};

// 请求拦截器
service.interceptors.request.use(
  config => {
    // 中断之前的同名请求
    removeQueue(config);
    // 添加cancelToken
    config.cancelToken = new CancelToken(c => {
      queue.push({ token: token(config), cancel: c });
    });
    // 登录后添加token
    if (store.getters.token) {
      config.headers['Authorization'] =
        store.getters.token.token_type + ' ' + store.getters.token.access_token;
    }
    return config;
  },
  error => {
    return Promise.reject(error);
  }
);

// 响应拦截器
service.interceptors.response.use(
  response => {
    // 在请求完成后,自动移出队列
    removeQueue(response.config);
    // 设置全局按钮Loading响应
    store.dispatch('SetLoading', false);
    // 错误码处理
    if (response.status !== 200) {
      return Promise.reject(response);
    }
    return response;
  },
  error => {
    const { response } = error;
    if (response) {
      // 错误处理
      errorHandle(response);
      return Promise.reject(response);
    } else {
      // 请求超时
      if (error.message.includes('timeout')) {
        console.log('超时了');
        messages('error', '请求已超时,请刷新或检查互联网连接');
      } else {
        // 断网,可以展示断网组件
        console.log('断网了');
        messages('error', '请检查网络是否已连接');
      }
    }
  }
);

export default {
  get: (url, data = {}) => {
    return new Promise((resolve, reject) => {
      service
        .get(store.getters.api.EMS_API + url, { params: data })
        .then(response => {
          resolve(response.data);
        })
        .catch(error => {
          reject(error);
        });
    }).catch(error => {
      throw new Error(error);
    });
  },
  exportFile: (url, data = {}) => {
    return new Promise((resolve, reject) => {
      service
        .post(store.getters.api.EMS_API + url, data, {
          headers: { 'Content-Type': 'application/json' },
          withCredentials: true,
          responseType: 'blob'
        })
        .then(response => {
          resolve(response);
        })
        .catch(error => {
          resolve(error);
        });
    }).catch(error => {
      return Promise.reject(error);
    });
  },
  post: (url, data = {}) => {
    return new Promise((resolve, reject) => {
      service
        .post(store.getters.api.EMS_API + url, data, {
          headers: {
            'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'
          },
          withCredentials: true,
          transformRequest: [
            data => {
              return qs.stringify(data);
            }
          ]
        })
        .then(response => {
          resolve(response.data);
        })
        .catch(error => {
          reject(error);
        });
    }).catch(error => {
      return Promise.reject(error);
    });
  },
  putJson: (url, data = {}) => {
    return new Promise((resolve, reject) => {
      service
        .put(store.getters.api.EMS_API + url, data, {
          headers: { 'Content-Type': 'application/json' },
          withCredentials: true
        })
        .then(response => {
          resolve(response.data);
        })
        .catch(error => {
          throw new Error(error);
        });
    }).catch(error => {
      throw new Error(error);
    });
  },
  delete: (url, data = {}) => {
    return new Promise((resolve, reject) => {
      service
        .delete(store.getters.api.EMS_API + url, {
          data
        })
        .then(response => {
          resolve(response.data);
        })
        .catch(error => {
          throw new Error(error);
        });
    }).catch(error => {
      throw new Error(error);
    });
  }
};

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.