javascript

765 阅读8分钟

localforage存储

Highchart

1. tooltip.refresh

应用场景:一个时间轴拖动改变到2017-12-01后,

  1. 一张图tooltip显示2017-12-01,并选中这个点
  2. 一张图更新chart series 遇到的难点:更新选中的tooltip,并且显示crosshair

解决办法:

参考 highchart points highchart points

 /**
  * Highlight a point by showing tooltip, setting hover state and draw crosshair
  */
Highcharts.Point.prototype.highlight = function (event) {
    this.onMouseOver(); // Show the hover marker
    this.series.chart.tooltip.refresh(this); // Show the tooltip
    this.series.chart.xAxis[0].drawCrosshair(event, this); // Show the crosshair
};

采用

    chart.tooltip.refresh(points); // Show the tooltip
    chart.xAxis[0].drawCrosshair(e, points[0]); // Show the crosshair

2. 更新series的5种方法

3. highcharts三图联动

4. chart.series.update

4.1 series.remove & chart.addSeries

应用场景:当我想完全替换原来的series,而不仅仅是在上面做更新和新增的时候,可以采用series.remove和chart.addSeries结合的方法。也就是说,要先去掉所有原来的series,再逐个加入新的。

遇到的难点:Highcarts图表中,可以有多个series。当我们想更新其中某一个series时,可以直接调用其update方法。

解决办法:

seriesData = [{
        type: 'column',
        name: 's1 new',
        data: [234.9, 171.5, 1106.4, 1129.2, 144.0, 176.0, 135.6, 1148.5, 216.4, 194.1, 195.6, 454.4]
    	}];
    while (chart.series.length > 0) {
      chart.series[0].remove(true);
    }
    for (var i = 0; i < seriesData.length; i++) {    
      chart.addSeries(seriesData[i]);
    }

4.2 series.update

应用场景:Highcarts图表中,可以有多个series。当我们想更新其中某一个series时,可以直接调用其update方法

解决办法:

 chart.series[0].update({
    	data: [29.9, 71.5, 306.4, 429.2, 144.0, 176.0, 135.6, 248.5, 216.4, 194.1, 95.6, 54.4]
    });

4.3 chart.update

应用场景:如果想一次性更新多个series,那么就可以直接使用chart.update。除了series,其他参数也可以同时进行更新。要注意的是,chart.update只允许更新原来的series,不允许新增series。比如在这个例子里,只能更新原来的一个或两个series,哪怕多加series,也不会起作用。

解决办法:

  chart.update({
        series: [{
        type: 'column',
        name: 's1',
        data: [129.9, 171.5, 306.4, 429.2, 144.0, 176.0, 135.6, 248.5, 216.4, 194.1, 95.6, 54.4]
    	},{
        type: 'column',
        name: 's2',
        data: [69.9, 51.5, 176.4, 121.2, 124.0, 476.0, 935.6, 248.5, 266.4, 191.1, 99.6, 53.4]
    	}]
    });

4.4 chart.addSeries

应用场景:如果想要新增series,就得使用chart.addSeries了。一次只能加一个series。注意这个方法有性能问题,当series的长度很长, 且一次性加好多series的时候,图表的反应会很慢。

解决办法:

   chart.addSeries({
        type: 'column',
        name: 's3',
        data: [129.9, 171.5, 1106.4, 1129.2, 144.0, 176.0, 135.6, 1148.5, 216.4, 194.1, 95.6, 54.4]
    	});

在 Vue 中使用 Highcharts

1.demo 2.demo2

vue

Vue.js 中,7种定义组件模板的方法

vuxjs gitbooks

Vue系列之computed使用详解

computed

一个完整的计算属性如下:

computed: {
 example: {
   get () {
     return 'example'
   },
   set (newValue) {
     console.log(newValue)
   }
 }

只有getter

export default {
    data () {
       return {
        numbers: [ 1, 2, 3, 4, 5 ]
       }
     },
    computed: {
      evenNumbers () {
        return this.numbers.filter(function (number) {
          return number % 2 === 0
        })
      }
    }
  }

作者:付出
链接:https://juejin.cn/post/6844903557812977672
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

element ui chechbox change事件传值问题

 在参数中写个 "$event" 就可以了。
"@change" = "checkedChange($event , scope.row)"

element ui table + pagination

应用场景:前端得到所有数据进行分页

<template>
    <el-table :data="tableData | pagination(pageNo,pageSize)">
      <el-table-column label="ID">
          <template slot-scope="scope">
              
          </template>
      </el-table-column>
    </el-table>
    <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="pageNo" :page-size="pageSize" layout=" prev, pager, next, sizes, jumper" :total="tableData.length"></el-pagination>
</template>
<script>
  export default{
    data(){
      return {
        tableData: [1,2,3,4],
        pageNo: 1,
        pageSize:10
      }
    },
    mounted(){
    },
    methods:{
      handleSizeChange(val) {
        this.pageSize=val;
      },
      handleCurrentChange(val) {
        this.pageNo = val;
      }
    },
    filters:{
      pagination(array,pageNo,pageSize){
        let offset = (pageNo - 1) * pageSize;
        let data=(offset + pageSize >= array.length) ? array.slice(offset, array.length) : array.slice(offset, offset + pageSize);
        return data
      }
    }
  }
</script>

debounce

lodash api

methods: {
    // This is where the debounce actually belongs.
    expensiveOperation: _.debounce(function () {
      this.isCalculating = true
      setTimeout(function () {
        this.isCalculating = false
        this.searchQueryIsDirty = false
      }.bind(this), 1000)
    }, 500)
  }

element-ui的el-radio怎么在已选中的情况下,再次点击取消选中

<el-checkbox-group v-model="checkList" :max="1">
    <el-checkbox label="选项 A"></el-checkbox>
    <el-checkbox label="选项 B"></el-checkbox>
    <el-checkbox label="选项 C"></el-checkbox>
</el-checkbox-group>

data () {
    return {
        checkList: ['选项A']
    }
}

或者这样:
<el-radio-group v-model="radio2">
  <el-radio @click.native.prevent="clickitem(3)" :label="3"> 备选项</el-radio>
  <el-radio @click.native.prevent="clickitem(6)" :label="6"> 备选项</el-radio>
  <el-radio @click.native.prevent="clickitem(9)" :label="9"> 备选项</el-radio>
</el-radio-group>
          
clickitem (e) {
  e === this.radio2 ? this.radio2 = '' : this.radio2 = e
},

<el-table>表头内插入 HTML 标签?

 <el-table-column prop="multiselectValue" :render-header="renderMultipleHeader" label="aaa" width="542">
  </el-table-column>
  renderMultipleHeader(createElement, { column, $index }) {
      return createElement("span", {
        domProps: {
          innerHTML:
            '<span class="m-r" style="display:inline-block;width:200px;">111 </span>\
                                            <span class="m-r" style="display:inline-block;width:70px;">222</span>\
                                            <span class="m-r" style="display:inline-block;width:100px;">333</span>\
                                            <span class="m-r" style="display:inline-block;width:70px;">444</span>'
        }
      });

使用jsx写法 ------------待补充

element ui 表格提交时获取所有选中的checkbox的数据

设定此属性@selection-change="changeFun",意思是每次勾选的时候都会触发这个事件

 //复选框状态改变
  changeFun(val) {
    this.multipleSelection = val;
  },

再在数据中心设定multipleSelection:[]就可以了 后面需要就用this.multipleSelection直接获取吧

表单校验必须使用el-form-item吗?

在el-table中使用el-form表单验证

<el-table-column align="right" label="入库数量">
                  <template scope="scope">
                      <el-form-item
                              :prop="'tableData.'+scope.$index+'.count'"
                              :key="scope.row.key"
                              :rules="{type: 'number',min: 0 ,required: true, message: '价格必须填写', trigger: 'change'}">
                          <el-input size="small" class="number" v-model.number="scope.row.count"
                                    @change="computedMoney(scope.row)"/>
                      </el-form-item>
                  </template>
              </el-table-column>

element-ui date 默认值在ie中不显示bug

解决办法:用v-if控制date-picker显示

vue-router 实现a标签里的target=“blank”

<router-link tag="a" :to="{/home}" target="_blank"></router-link>

vue怎么检测窗口的大小变动

防止页面卡顿 :VueJs 监听 window.resize 方法

data(){
    return {
        clientHeight: '600px',
    },
},
mounted() {
    // 动态设置背景图的高度为浏览器可视区域高度
    
    // 首先在Virtual DOM渲染数据时,设置下背景图的高度.
    this.clientHeight.height = `${document.documentElement.clientHeight}px`;
    // 然后监听window的resize事件.在浏览器窗口变化时再设置下背景图高度.
    const that = this;
    window.onresize = function temp() {
        that.clientHeight = `${document.documentElement.clientHeight}px`;
    };
},

Vue2.0爬坑:ie11中打开项目页面空白

vue多页面开发和打包的正确姿势

vue mixin

// This is a global mixin, it is applied to every vue instance
Vue.mixin({
  data: function() {
    return {
      get globalReadOnlyProperty() {
        return "Can't change me!";
      }
    }
  }
})

WEBPACK + JSP 构建多页应用

参考 WEBPACK + JSP 构建多页应用

vue cli 构建的 webpack 项目

参考

设置多页面

设置多页面

面试官问你有没有了解过 vue-cli 构建的打包工程

记一次webpack4.x打包vue报错

vue-cli脚手架种中引入elementUI

vue多页面开发和打包的正确姿势

vue-cli脚手架种中引入elementUI步骤

 npm install element-ui -save
import Vue from 'vue'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI)

vue-cli 3.x

vue-cli 3.0脚手架配置及扩展 (二):vue.config.js多页配置 vue-cli 3.0 UI控制台初体验

需要在项目的 根目录添加一个Vue.config.js。在这个文件中,我们可以进行一些个性化定制。

module.exports = {
    // 基本路径
    baseUrl: './',
    // 生产环境是否生成 sourceMap 文件
    productionSourceMap: false,
    // 服务器端口号
    devServer: {
        port: 1234,
    },
}

详细的配置

module.exports = {
 // 基本路径
 baseUrl: '/',
 // 输出文件目录
 outputDir: 'dist',
 // eslint-loader 是否在保存的时候检查
 lintOnSave: true,
 // use the full build with in-browser compiler?
 // https://vuejs.org/v2/guide/installation.html#Runtime-Compiler-vs-Runtime-only
 compiler: false,
 // webpack配置
 // see https://github.com/vuejs/vue-cli/blob/dev/docs/webpack.md
 chainWebpack: () => {},
 configureWebpack: () => {},
 // vue-loader 配置项
 // https://vue-loader.vuejs.org/en/options.html
 vueLoader: {},
 // 生产环境是否生成 sourceMap 文件
 productionSourceMap: true,
 // css相关配置
 css: {
  // 是否使用css分离插件 ExtractTextPlugin
  extract: true,
  // 开启 CSS source maps?
  sourceMap: false,
  // css预设器配置项
  loaderOptions: {},
  // 启用 CSS modules for all css / pre-processor files.
  modules: false
 },
 // use thread-loader for babel & TS in production build
 // enabled by default if the machine has more than 1 cores
 parallel: require('os').cpus().length > 1,
 // 是否启用dll
 // See https://github.com/vuejs/vue-cli/blob/dev/docs/cli-service.md#dll-mode
 dll: false,
 // PWA 插件相关配置
 // see https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-pwa
 pwa: {},
 // webpack-dev-server 相关配置
 devServer: {
  open: process.platform === 'darwin',
  host: '0.0.0.0',
  port: 8080,
  https: false,
  hotOnly: false,
  proxy: null, // 设置代理
  before: app => {}
 },
 // 第三方插件配置
 pluginOptions: {
  // ...
 },
 // 代理配置表,在这里可以配置特定的请求代理到对应的API接口
// 例如将'localhost:8080/api/xxx'代理到'www.example.com/api/xxx'
// 使用方法:https://vuejs-templates.github.io/webpack/proxy.html
proxyTable: {
      '/api': {
        target: 'http://xxxxxx.com', // 接口的域名
        // secure: false,  // 如果是https接口,需要配置这个参数
        changeOrigin: true, // 如果接口跨域,需要进行这个参数配置
        pathRewrite: {
          '^/api': ''
        }
      }
},
}

修改静态文件不相对于outputDir

assetsDir not relative to outputDir

const path = require("path");

module.exports = {
  outputDir: path.resolve('../../backend/static'),
  assetsDir: '../../backend/static/assets',
  baseUrl: '/',
}

Vue CLI 3 開箱

vue中Axios的封装和API接口的管理

vue中Axios的封装和API接口的管理 vue拦截器的一次实践

// 引入axios以及element ui中的loading和message组件
import axios from 'axios'
import { Loading, Message, MessageBox  } from 'element-ui'
// 超时时间
axios.defaults.timeout = 5000
// http请求拦截器
var loadinginstace
axios.interceptors.request.use(config => {
    //修改 Content-Type
    config.headers['Content-Type'] = 'application/json; charset=UTF-8'
  // element ui Loading方法
  loadinginstace = Loading.service({ fullscreen: true });
  console.log(loadinginstace)
  return config
}, error => {
  MessageBox({
    title:'提示',
    message:'加载超时',
    callback: action => {
      loadinginstace.close()
    }
  })
  return Promise.reject(error)
})
// http响应拦截器
axios.interceptors.response.use(data => {// 响应成功关闭loading
  loadinginstace.close()
  return data
}, error => {
  MessageBox({
    title:'提示',
    message:'请求失败',
    callback: action => {
      loadinginstace.close()
    }
  })
  return Promise.reject(error)
})
export default axios;

axios post request to send form data

var body = {
                 userName: 'Fred',
                 userEmail: 'Flintstone@gmail.com'
              }

        axios({
              method: 'post',
              url: '/addUser',
              data: body,
              headers:{
                  Content-Type:'multipart/form-data'
                }
            })
            .then(function (response) {
                console.log(response);
              })
              .catch(function (error) {
                console.log(error);
            });

vue-cli 3.0在打包时引用静态文件,vender 包优化,减少chunk-ventors文件体积

configureWebpack: config => {
  // 生产模式
  if (isProduction) {
   config.externals = {
    'vue': 'Vue',
    'vue-router': 'VueRouter',
    'moment': 'moment'
   }
  }
 }

vue 插件

Vue图片浏览组件v-viewer,支持旋转、缩放、翻转等操作

smooth scroll

smooth scroll behavior polyfill

smooth scroll behavior polyfill fix ie兼容性
window.scrollTo({
    top: 1000,
    behavior: "smooth"
});

vue实现滚动监听 添加当前滚动到哪里的active class

参考Vue监听滚动实现锚点定位(双向)

从 Vue.js 自定义输入框深入理解 v-model

javascript技巧

window.location

URL详解 window.location的一系列方法

Parsing URL string with lodash

Url参数处理方法(js,querystring,lodash)

参考dom操控 判断一个元素是否在overflow hidden区域

Element.getBoundingClientRect() 兼容性不够完美 故采用上面的方法

扩展运算符实现对象的深拷贝

var obj = {
  name: 'FungLeo',
  sex: 'man',
  old: '18'
}
var { ...obj2 } = obj
obj.old = '22'
console.log(obj)
console.log(obj2)

对象的深拷贝

1.万能的for循环实现对象的深拷贝

var obj = {
  name: 'FungLeo',
  sex: 'man',
  old: '18'
}
var obj2 = copyObj(obj)
function copyObj(obj) {
  let res = {}
  for (var key in obj) {
    res[key] = obj[key]
  }
  return res
}

2.转换成json再转换成对象实现对象的深拷贝

var obj = {
  name: 'FungLeo',
  sex: 'man',
  old: '18'
}
var obj2 = JSON.parse(JSON.stringify(obj))

数组的深拷贝

1.使用 jQuery 的 extend 方法

var arr1 = [1, 2, [3, 4], {a: 5, b: 6}, 7],
	arr2 = $.extend(true, [], arr1);
 
console.log(arr1, arr2);
arr2[1] = 10;
console.log(arr1, arr2);

2.JSON.stringify(array) 然后再 JSON.parse()

var arr1 = [1, 2, [3, 4], {a: 5, b: 6}, 7],
	arr2 = JSON.parse(JSON.stringify(arr1));
 
console.log(arr1, arr2);
arr2[1] = 10;
arr2[3].a = 20;
console.log(arr1[1], arr2[1]);
console.log(arr1[3], arr2[3]);

使用闭包缓存函数

var gotop = (function(){
    var isFF = /firefox/i.test(navigator.userAgent);
    var docEl = document[ isFF ? 'documentElement' : 'body' ];
    return function(){
        docEl.scrollTop = 0;
    }
    })();
    

数组去重 

JavaScript数组去重—ES6的两种方式

function unique(arr) {
    const res = new Map();
    return arr.filter((a) => !res.has(a) && res.set(a, 1))
}
function unique(arr) {
    return Array.from(new Set(arr))
}

数组groupBy

Array.prototype.groupBy = function (keyName) {
    var result = {};
    this.forEach(function (item) {
        if (!result[item[keyName]])
            result[item[keyName]] = new Array();
        result[item[keyName]].push(item);
    });
    return result;
}

Cookie 基本操作

//设置cookie
Vue.prototype.setCookie = (c_name, value, expiredays) => {
  var exdate = new Date();&emsp;&emsp;&emsp;&emsp;
  exdate.setDate(exdate.getDate() + expiredays);&emsp;&emsp;&emsp;&emsp;
  document.cookie = c_name + "=" + escape(value) + ((expiredays == null) ? "" : ";expires=" + exdate.toGMTString());
}
//获取cookie、
function getCookie(name) {
  var arr, reg = new RegExp("(^| )" + name + "=([^;]*)(;|$)");
  if (arr = document.cookie.match(reg))
    return (arr[2]);
  else
    return null;
}
Vue.prototype.getCookie = getCookie;
//删除cookie
Vue.prototype.delCookie =(name) => {
    var exp = new Date();
    exp.setTime(exp.getTime() - 1);
    var cval = getCookie(name);
    if (cval != null)
      document.cookie = name + "=" + cval + ";expires=" + exp.toGMTString();
  }

vscode下Vue代码自动格式化配置

修改配置文件

// 保存自动化
"editor.formatOnSave": true,
// 保存时自动fix
"eslint.autoFixOnSave": true,
// 添加 vue 支持
"eslint.validate": [
    "javascript",
    "javascriptreact",
    {
        "language": "vue",
        "autoFix": true
    }
],
// 使用插件格式化 html
"vetur.format.defaultFormatter.html": "js-beautify-html",
// 屏蔽vetur的js格式化
"vetur.format.defaultFormatter.js": "none"

自定义 sideNav “抽屉”

How TO - Side Navigation

position:relative后 cursor:pointer not working

调整z-index变大一点

css content

//下面的例子在每个链接后插入括号中的 URL
a:after{
  content: " (" attr(href) ")";
}