Vue

80 阅读17分钟

便捷开发插件

JsOften.js

下载安装

  • npm安装构建

    npm install jsoften --save

  • cnpm淘宝镜像安装

    npm install -g cnpm --registry=https://registry.npm.taobao.org

    cnpm install jsoften --save

注意:如果jsoften插件与npm版本不一致,使用命令更新至最新版npm update jsoften

插件使用

安装成功后在vue项目中的main.js中进行全局引用:import jsoften from 'jsoften',并在vue原型进行挂载:Vue.prototype.jsTen = jsoften。可以在任意页面进行调用:this.jsTen.xxx, 如:console.log(this.jsTen.formatDate(new Date(1609412149000),'yyyy-MM-dd hh:mm:ss')),控制台得到输出:2020-12-31 18:55:49

常用方法

日期时间

时间戳转日期格式
  • 方法调用:
console.log(this.jsTen.formatDate(new Date(1609412149000),'yyyy-MM-dd hh:mm:ss'))
//输出: 2020-12-31 18:55:49

在调用formatDate方法时,接收两个参数。 第一个参数为要转换的时间戳必须是number类型;第二个参数是需要输出的日期格式,第二个参数输出的日期格式,可选值有:

  1. yyyy-MM-dd hh:mm:ss 输出年月日 时分秒
//获取年月日 时分秒 输出: 2020-12-31 18:55:49
console.log(this.jsTen.formatDate(new Date(1609412149000),'yyyy-MM-dd hh:mm:ss'))
  1. yyyy-MM-dd 只输出年月日
//获取年月日 输出:2020-12-31
console.log(this.jsTen.formatDate(new Date(1609412149000),'yyyy-MM-dd'))
  1. hh:mm:ss 只输出时分秒
//获取时分秒 输出18:55:49
console.log(this.jsTen.formatDate(new Date(1609412149000),'hh:mm:ss'))
  1. 可以单独输出年或者月或者日:
//只获取年份 输出2020
console.log(this.jsTen.formatDate(new Date(1609412149000),'yyyy'))
//只获取月份 输出12
console.log(this.jsTen.formatDate(new Date(1609412149000),'MM'))
//只获取小时 输出18
console.log(this.jsTen.formatDate(new Date(1609412149000),'hh'))
  1. 还可以针对连接符重新选择,如果您不想使用'-'作为连接符的话,随时可以更换,例如这样:
//输出2020/12/31
console.log(this.jsTen.formatDate(new Date(1609412149000),'yyyy/MM/dd'))
//输出2020年12月31日
console.log(this.jsTen.formatDate(new Date(1609412149000),'yyyy年MM月dd日'))
//输出18时55分49秒
console.log(this.jsTen.formatDate(new Date(1609412149000),'hh时mm分ss秒'))
日期格式转换为时间戳

方法调用:formatTIme()

  • 项目中常见的两种格式,2020-12-20 12:12:12或者2020/12/20 12:12:12都可以使用formatTime进行轻松转换
//输出: 1542939000000
console.log(this.jsTen.formatTime('2020-10-31 18:55:49'))
  • 也可以使用这种常见的格式直接转换,比如:2020/12/20 13:00:09
//输出: 1608440409000
console.log(this.jsTen.formatTime('2020/12/20 13:00:09'))
当前系统时间

方法调用:getNowFormatDate() 获取当前系统时间

获取系统时间,可以使用getNowFormatDate方法,可以只获取年月日,也可以只获取时分秒,灵活获取

//输出: 2020-12-31 21:29:27
console.log(this.jsTen.getNowFormatDate('','-'))

getNowFormatDate支持参数传递,第一个参数为类型区分,可选值有:

  1. 'y'只获取系统年月日时间
  2. 'h'只获取系统时分秒时间
  3. ' '获取系统全量时间
    /*1、只获取系统年月日*/
    console.log(this.jsTen.getNowFormatDate('y','-'))
    //输出: 2020-12-31
    
    /*2、只获取系统时分秒*/
    console.log(this.jsTen.getNowFormatDate('h','-'))
    //输出: 21:34:49
    
    /*3、获取系统全量时间*/
    console.log(this.jsTen.getNowFormatDate('','-'))
    //输出: 2020-12-31 21:34:57
    
    console.log(this.jsTen.getNowFormatDate('y','/'))
    //输出: 2020/12/31
距离当前到某一天的日期

方法调用:getBeforeDate() 获取距离当前到某一天的日期

getNowFormatDate方法可以获取当前时间距离的前几天或者后几天的日期

    //获取当前时间的前一天
    console.log(this.jsTen.getBeforeDate(-1))
    //输出: 2020-12-30

getBeforeDate参数支持正数和负数,正数代表后几天,负数代表前几天,举例:

    /*1、获取前30天*/
    console.log(this.jsTen.getBeforeDate(-30))
    //输出: 2020-12-02
    
    /*2、获取后30天*/
    console.log(this.jsTen.getBeforeDate(30))
    //输出: 2021-01-31
计算两个时间段内的间隔

方法调用:diffTime() 获取距离两时间段间隔

diffTime方法可以获取两个时间段的剩余天数、小时数、分钟数、秒数等,也可更方便的拓展为倒计时功能

    //计算今天距离2022-12-31还有多少天多少小时多少分多少秒
    console.log(this.jsTen.diffTime(new Date(), '2022-12-31 00:00:00',''))

diffTime方法支持接收三个参数:第一个参数为开始时间,第二个参数为结束时间,第三个参数为 Day 时计算还有多少天,为 Hours 时计算还有多少小时,为 Minutes 计算还有多少分钟,为 Seconds 计算还有多少秒,为 '' 计算还有多少天多少小时多少分多少秒,举例:

    /*1、获取距离2022年12月31日还有多少时间*/
    console.log(this.jsTen.diffTime(new Date(), '2022-12-31 09:08:08',''))
    //输出: 728天20小时18分钟2秒
    
    /*2、、获取距离2022年12月31日还有多少天*/
    console.log(this.jsTen.diffTime(new Date(), '2022-12-31 00:00:00','Day'))
    //输出: 728天
    
    /*3、、获取距离2022年12月31日还有多少小时*/
    console.log(this.jsTen.diffTime(new Date(), '2022-12-31 00:00:00','Hours'))
    //输出: 17485小时
    
    /*4、、获取距离2022年12月31日还有多少分钟*/
    console.log(this.jsTen.diffTime(new Date(), '2022-12-31 00:00:00','Minutes'))
    //输出: 1049126分钟
    
    /*5、、获取距离2022年12月31日还有多少秒*/
    console.log(this.jsTen.diffTime(new Date(), '2022-12-31 00:00:00','Seconds'))
    //输出: 62947544秒

以上都是获取当前时间到某一天的举例,您也可以配合 str2Date 方法实现某两个不固定日期间相差的天数

    //计算2022-12-30距离2022-12-31还有多少时间
    console.log(this.jsTen.diffTime(this.jsTen.str2Date('2022-12-30'), '2022-12-31 12:28:31',''))
    //输出: 1天12小时28分钟31秒

也可以直接使用setInterval函数更方便的实现倒计时功能:

    let timer =null
    clearInterval(timer)
    timer=setInterval(()=>{
      console.log(this.jsTen.diffTime(new Date(), '2022-12-31 00:00:00',''))
      console.log(this.jsTen.diffTime(new Date(), '2022-12-31 00:00:00','Day'))
      console.log(this.jsTen.diffTime(new Date(), '2022-12-31 00:00:00','Hours'))
      console.log(this.jsTen.diffTime(new Date(), '2022-12-31 00:00:00','Minutes'))
      console.log(this.jsTen.diffTime(new Date(), '2022-12-31 00:00:00','Seconds'))
    },1000)
今年还有多少天

方法调用:restDayOfYear() 今年剩余天数

console.log(this.jsTen.restDayOfYear())
当月还有多少天

方法调用:getCountDays() 当月总共有多少天

console.log(this.jsTen.getCountDays())
今天周几

方法调用:getWeekZh() 今天星期几

getWeekZh可以轻松今天是周几,可以搭配getNowFormatDate方法获取今天是周几,也可以获取某一天是周几

//获取今天是周几
console.log(this.jsTen.getWeekZh(this.jsTen.getNowFormatDate('y','-')))

可以搭配getNowFormatDate获取今天是周几,也可以获取某一天是周几,在获取某一天是周几的时候参数必须是年月日的形式,例如这样(this.jsTen.getWeekZh('2020-01-01')),举例:

    /*获取今天是周几---搭配getNowFormatDate方法时,getNowFormatDate方法的参数固定传y,-*/
    console.log(this.jsTen.getWeekZh(this.jsTen.getNowFormatDate('y','-')))
    //输出: 星期六
    
    /*获取2020-01-01这一天是周几*/
    console.log(this.jsTen.getWeekZh('2020-01-01'))
    //输出: 星期三
    
    /*获取2025-12-30这一天是周几*/
    console.log(this.jsTen.getWeekZh('2025-12-30'))
    //输出: 星期二
字符串日期转Date

方法调用:str2Date() 字符串日期转Date

    console.log(this.jsTen.str2Date('2020-09-20'))
    //输出: Sun Sep 20 2020 00:00:00 GMT+0800 (中国标准时间)
两个日期相差的天数

方法调用:dateDiff() 两个日期间相差天数

dateDiff可以轻松获取某两个日期段之间相差的天数

console.log(this.jsTen.dateDiff('2020-09-20','2020-09-23'))

dateDiff在使用中第一个参数是开始时间,第二个参数是结束时间,但是实际使用中难免会出现开始时间和结束时间不确定顺序的情况,dateDiff如果第一个参数小于第二个参数的时候,会出现负数,我们可以使用Math.abs()方法将其转换为正数,满足不同场景的使用,举例:

    /*第一个参数大于或等于第二个参数的时候*/
    console.log(this.jsTen.dateDiff('2020-11-20','2020-12-31'))
    //输出: 41
    
    /*第一个参数小于第二个参数的时候,正常会输出*/
    console.log(this.jsTen.dateDiff('2020-12-31','2020-11-20'))
    //输出: -41
    
    /*可以使用Math.abs()方法将负数转换为正数得到的依然是相差的正确天数*/
    console.log(Math.abs(this.jsTen.dateDiff('2020-12-31','2020-11-20')))
    //输出: 41

数组/json常用方法

根据指定key去重

方法调用:removeRepeat() 数组内json根据指定key去重方法

    /*例如有以下数据,需要将name相同的去重:*/
    let arr = [
      {name:'小明',id:3},
      {name:'小李',id:5},
      {name:'小王',id:1},
      {name:'小明',id:4},
      {name:'小红',id:3},
      {name:'小李',id:3},
    ]
    console.log(this.jsTen.removeRepeat(arr,'name'))
    //输出:
    /*[
      {name: "小明", id: 3},
      {name: "小李", id: 5},
      {name: "小王", id: 1},
      {name: "小红", id: 3}
    ]*/
    
    /*将id相同的去重:*/
    console.log(this.jsTen.removeRepeat(arr,'id'))
    //输出:
    /*
    [
      {name: "小明", id: 3},
      {name: "小李", id: 5},
      {name: "小王", id: 1},
      {name: "小明", id: 4}
    ]
    */
根据指定key排序

方法调用:reverse()

    /*例如有以下数据,需要根据id从小到大进行排序:*/
    let json =[
      {name:1,id:2,time:'2020-12-21'},
      {name:3,id:5,time:'2020-05-30'},
      {name:6,id:4,time:'2020-01-01'},
      {name:82,id:21,time:'2018-04-20'},
      {name:23,id:90,time:'2002-09-12'}
    ]
    console.log(this.jsTen.JsonSort(json,'id'))
    //输出:
    /*[
      {name: 1, id: 2, time: "2020-12-21"},
      {name: 6, id: 4, time: "2020-01-01"},
      {name: 3, id: 5, time: "2020-05-30"},
      {name: 82, id: 21, time: "2018-04-20"},
      {name: 23, id: 90, time: "2002-09-12"}
    ]*/
    
    /*根据name从小到大进行排序:*/
    console.log(this.jsTen.JsonSort(json,'name'))
    //输出:
    /*
    [
      {name: 1, id: 2, time: "2020-12-21"},
      {name: 3, id: 5, time: "2020-05-30"},
      {name: 6, id: 4, time: "2020-01-01"},
      {name: 23, id: 90, time: "2002-09-12"},
      {name: 82, id: 21, time: "2018-04-20"}
    ]
    */
  
一般情况下,我们根据时间进行排序也比较常用,如果我们的数据里有年月日时间类型的数据,可以配合时间常用方法 formatTime() 将其装换为时间戳进行排序,示例:
  
    /*使用this调用方法之前您需要确保已下载安装jsoften插件并在main.js中注册完成,后续所有方法都将使用this调用的方式举例*/
    /*例如有以下数据,需要根据时间从小到大进行排序:*/
    let json =[
      {name:1,id:2,time:'2020-12-21'},
      {name:3,id:5,time:'2020-05-30'},
      {name:6,id:4,time:'2020-01-01'},
      {name:82,id:21,time:'2018-04-20'},
      {name:23,id:90,time:'2002-09-12'}
    ]
    /*第一步我们可以讲时间年月日单位转换为时间戳*/
    let json1 = []
    json.forEach((item,index,arr)=>{
      item.stamp=this.jsTen.formatTime(item.time)//循环给json里添加一个stamp的key作为存储时间戳,stamp名可根据实际情况自定义
      json1.push(item)
    })
    console.log(this.jsTen.JsonSort(json1,'stamp'))//在根据时间戳进行排序
    //输出:
    /*
    [
      {name: 23, id: 90, time: "2002-09-12", stamp: 1031760000000},
      {name: 82, id: 21, time: "2018-04-20", stamp: 1524153600000},
      {name: 6, id: 4, time: "2020-01-01", stamp: 1577808000000},
      {name: 3, id: 5, time: "2020-05-30", stamp: 1590768000000},
      {name: 1, id: 2, time: "2020-12-21", stamp: 1608480000000}
    ]
    */
  
以上例子都是将数据根据指定key值从小到大排序,实际项目中经常也会用到从大到小的需求,那么我们可以使用 reverse() 方法直接将数组翻转即可:
    
      /*例如有以下数据,需要根据id进行排序:*/
      let json =[
        {name:1,id:2,time:'2020-12-21'},
        {name:3,id:5,time:'2020-05-30'},
        {name:6,id:4,time:'2020-01-01'},
        {name:82,id:21,time:'2018-04-20'},
        {name:23,id:90,time:'2002-09-12'}
      ]
      console.log(this.jsTen.JsonSort(json,'id'))//默认从小到大进行排序
      //输出:
      /*[
        {name: 1, id: 2, time: "2020-12-21"},
        {name: 6, id: 4, time: "2020-01-01"},
        {name: 3, id: 5, time: "2020-05-30"},
        {name: 82, id: 21, time: "2018-04-20"},
        {name: 23, id: 90, time: "2002-09-12"}
      ]*/
      
      console.log(this.jsTen.JsonSort(json,'id').reverse)//使用reverse()翻转即可实现从大到小的顺序进行排序
      //输出:
      /*
      [
        {name: 23, id: 90, time: "2002-09-12"},
        {name: 82, id: 21, time: "2018-04-20"},
        {name: 3, id: 5, time: "2020-05-30"},
        {name: 6, id: 4, time: "2020-01-01"},
        {name: 1, id: 2, time: "2020-12-21"}
      ]
      */
数组深拷贝

方法调用:arrCopy() 可进行数据的深拷贝

    let a =['1','2','3','4',{'name':1}]
    let b =this.jsTen.arrCopy(a)
    a[0]='110'
    console.log(a)
    //输出 ['110','2','3','4',{'name':1}]
    console.log(b)
    //输出 ['1','2','3','4',{'name':1}]
根据某一相同字段分组数据

方法调用:groupBy() 根据某一个相同字段对数据分组

    let b=[
      {id:1,name:'aa'},
      {id:2,name:'kk'},
      {id:2,name:'ff'},
      {id:3,name:'ii'}
    ]
    /*第一个参数为需要分组的数据,第二个参数为函数,item.id的id是就是依赖分组的字段*/
    console.log(this.jsTen.groupBy(b,function(item){return [item.id]}))
    //输出
    [
      [
        {id:1,name:'aa'}
      ],
      [
        {id:2,name:'kk'},
        {id:2,name:'ff'}
      ],
      [
        {id:3,name:'ii'}
      ]
    ]
替换key值字段名

方法调用:spliceArr() 键名替换

    let b=[
      {id:1,name:'aa'},
      {id:2,name:'kk'},
      {id:2,name:'ff'},
      {id:3,name:'ii'}
    ]
    /*替换数组下某一数据的key值字段名,,第一个参数为数组,第二个参数为旧的key,第三个参数为新的key*/
    console.log(this.jsTen.spliceArr(b,'name','username'))
    //输出
    [
      {id:1,username:'aa'},
      {id:2,username:'kk'},
      {id:2,username:'ff'},
      {id:3,username:'ii'}
    ]

vue.config文件常用配置

配置alias引用

function resolve(dir) {
    return path.join(__dirname, dir)
}
module.exports = {
    chainWebpack(config) {
        config.resolve.alias
            .set('components', resolve('src/components'))
            .set('common', resolve('src/common'))
            .set('api', resolve('src/api'))
    },
}

这样在组件中引用的时候,就不用写繁琐的路径了:

import Xx from 'components/xx/xx';
import Xx from 'common/xx/xx';
import Xx from 'api/xx';

在书写CSS时候,引用的方法 (注意在路径前面有个波浪线~)

@import "~common/less/variable.less";

这一点在vue3中得到了进一步优化,甚至在vue.config.js文件中不用配置,直接使用“@”去代表根路径/src(这个是配置的 webpack 的 alias,vue-cli 内部对 webpack 的封装做的。)。

import Header from '@/components/header/header'

本地模拟数据并获取查询参数

  1. 首先将模拟的data.json文件放在文件的根目录下;
  2. 配置config文件进行读取
// 配置本地模拟服务器文件
const webpack = require('webpack');
const path = require('path');
// 引入data.json文件
const appData_one = require('./data');
const appData_error = require('./data_error');

module.exports = {
    devServer: {
        before(app) {
            // 配置好后访问localhost:8080/api/?id=1 即可得到appData_one中的数据
            app.get('/api/', function (req, res) {
                // req.query.id就是url中的查询字符串
                // 注意获取的查询字符串是字符串类型 使用需要转化为整形!
                switch (parseInt(req.query.id)) {
                    case 1:
                        res.json(appData_one);
                        break;
                    default:
                        res.json(appData_error)
                }
            });
        }
    }
}

req.query可以获得/api/这个url上的查询字符串,如/api/?id=1&age=18,那么req.query = { id: 1, age: 18 }

文件打包路径

module.exports = {
    // 打包文件的前缀路径
    publicPath: '',
    // 设置false后,上线的项目就看不到源代码了,只能看到压缩代码
    productionSourceMap: false,
}

publicPath如果不设置为空,那么打包后的项目,其中js的引用路径如下:

// publicPath未设置,使用默认值
<script src="./vendor.js"></script>
// publicPath: ''
<script src="vendor.js"></script>
// publicPath: 'v1'
<script src="v1/vendor.js"></script>

一般的直接设置为空即可。这样打包后的资源路径可以被正常访问到。

在最新的vue3中,如下配置:

module.exports = defineConfig({
  transpileDependencies: true,
  publicPath: '',            // 为空,那么打包后的js\css等前面是空,比如js/xxx
  outputDir: 'dist',         // 打包后的程序都在哪个文件夹下
  indexPath: 'app.html'  // 打包后的运行的主页=原来的index.html
});

修改打包后的主页地址,使用indexPath:'app.html' 指定即可

打包的JS和CSS取消缓存后缀

通常vue-cli打包后的js文件名如:app.190642b6.js

但是我们有时候并不需要缓存的后缀,只需要app.js,代码配置如下:

module.exports = {
    // 设置JS打包后的路径以及文件名
    configureWebpack: {
        // 输出重构  打包编译后的 文件名称 本例是取消多余的后缀只保留文件名
        output: {
            filename: `js/[name].js`,
            chunkFilename: `js/[name].js`
        }
    },
    // 设计CSS打包后的路径和文件名,需要后缀,则filename: `css/[name].[chunkhash].css`,
    css: {
        // 将组件内的 CSS 提取到一个单独的 CSS 文件 (只用在生产环境中)
        // 也可以是一个传递给 `extract-text-webpack-plugin` 的选项对象
        // 修改打包后css文件名
        // extract: true,
        extract:{
            filename: `css/[name].css`,
            chunkFilename: `css/[name].css`
        },

        // 是否开启 CSS source map?
        sourceMap: false,

        // 为预处理器的 loader 传递自定义选项。比如传递给
        // sass-loader 时,使用 `{ sass: { ... } }`。
        loaderOptions: {},
        // requireModuleExtension: false
    }
}

这样再打包后的文件名,就不会有缓存后缀了。

使用代理请求数据

module.exports = {
    devServer: {
        proxy: {
            // 所有 /api请求的路由会走这个代理
            '/api': {
                // 目标服务器地址,也就是接口服务器的真实地址
                target: 'https://ssl.qdxin.cn/wechat/api/m.qdxin.cn/api',
                /* 
                跨域时一般都设置该值 为 true
                开启代理:在本地会创建一个虚拟服务端,然后发送请求的数据,并同时接收请求的数据,
                这样服务端和服务端进行数据的交互就不会有跨域问题 
                */
                changeOrigin: true,
                // 重写接口路由
                pathRewrite: {
                    // /api_index.json 被重写为 /api/index
                    // 这样处理后,最终得到的接口路径为: http://localhost:8080/api/index
                    // 然后node服务端实际请求的地址https://ssl.qdxin.cn/.../api/api_index.json
                    '^/api/index': 'api_index.json',
                    '^/api/list/api_more_69': 'api_more_69.json',
                    '^/api/detail/2/18000': 'detail/2/18000',
                }
            }
        }
    },
}

当然代理请求数据非必要还是不要使用node,一劳永逸的情况还是使用PHP等服务端语言写更好一些。这个仅仅作为备选的方案。

sass全局配置

module.exports = {
  css: {
    loaderOptions: {
      sass: {
        // 全局引入变量和Mixin additionalData允许全局引入scss文件,
        // 全局引入后就可以直接用 无需每个组件都import了
        // 因为这是最新的特性,所以node-sass:^5.0与sass-loader:^10.1必须升级到最新版否则会报错
        additionalData: `
          @import "@/assets/scss/variable.scss";
          @import "@/assets/scss/mixin.scss";
        `
      }
    }
  }
}

这样配置后,就无需在每个组件中都引用mixin.scss和variable.scss文件了。比如

// 以前 只有在每个组件import后才能使用,否则会报错
<style>
  @import "~common/less/variable.scss";
  @import "~common/less/mixin.scss";
  div{color: @blue;}

// 配置之后 无需引用,直接在<style>中使用即可
div{color: @blue;}