组件,库,控件,插件 集合(jQuery/富文本/PDF/Excel/国际化/解压缩/JSEncrypt/Axios/其他)

组件(库)的概念 包含 控件(UI组件)、插件(基物上的组件)

jQuery 

位置与尺寸

$(window).scrollTop()   //鼠标滚动高度

$(window).height()        //窗口高度

$(window).width()         //窗口宽度

$(“#”).outerHeight()      //元素高度

$(“#”).outerWidth()      //元素宽度

$(“#”).offset().top        //元素相对于文档的位置

$("#").offset().left        //元素相对于文档的位置

$(“#”).position().top        //元素相对于父元素的位置

$("#").position().left        //元素相对于父元素的位置

$("").css("left")           //元素相对于参考元素的位置

$("").css("top")           //元素相对于参考元素的位置

事件
$(document).ready();
$(window).resize();
$(window).scroll();   // window 上的事件不好追踪,可以把滚动事件绑在DOM上

jQuery源码

jQuery源码的基本结构:

定义了jQuery函数,并使它成为全局变量   window.jQuery = window.$ = jQuery;

jQuery函数定义:

var jQuery = function( selector, context ) {
                  return new jQuery.fn.init( selector, context );
              }

jQuery函数的原型:

jQuery.prototype = {

    ........................

length: 0,
  sort: [].sort,
  splice: [].splice

有了这几个属性,它就是一个类数组对象

}

jQuery初始化函数:

jQuery.fn.init = function(selector, context){

    查找元素

    return this;

}

jQuery函数有多个成员(JS里函数可以有成员,成员与函数体无关)其中:

jQuery.fn.init.prototype = jQuery.fn =jQuery.prototype;

jQuery.fn.extend=jQuery.extend;

几个使用过程的原理:

1、通过选择器获得jQuery对象 $("#id")

     即调用了jQuery函数,返回jQuery.fn.init构造的对象,这个对象以jQuery.fn.init.prototype为原型,即以jQuery.fn 、jQuery.prototype为原型,因此jQuery对象也是一个类数组对象,并且有jQuery.fn的所有成员,数组的元素为DOM对象。

2、扩展jQuery(插件开发)

       jQuery.fn.extend=jQuery.extend = function(object){把object的成员扩展到this}

      $.fn.extend(object);方法体里的this指向jQuery.fn即jQuery.prototype,因此扩展到jQuery原型。

    $.extend(object);方法体里的this指向$,因此扩展到jQuery函数。

jQuery使用

1、jQuery对象的结构:
[DOM对象]
{
length:DOM对象的长度
context:document对象(也是个DOM对象)
selector:选择器的字符串
__proto__:各种继承而来的jQuery方法
}

2、页面加载完成事件

$(function)等效于$(document).ready(function)或 $(window).on("load",function)

3、$也可以把非DOM数组打包成jQuery对象,从而可以使用jQuery对象的那些操作数组的函数。

4、jquery插件式的UI组件

UI 组件的对外接口应该包括:构建方法、事件、实例方法、属性值


(function($) {
    // 给jquery对象添加一个成员,传入参数
// 这个插件方法 作为 UI 组件的构建方,使用:$('#id').plugin(options);
    $.fn.plugin = function(options) {
        // each 对jquery对象里的DOM对象一一处理,后,返回当前jquery对象,使得能被链式调用
        return this.each(function() {
   // 可以把一些数据绑到DOM对象上
   this.pluginId = 1;
            var $this = $(this);
// 插件逻辑 
/**************************************************/
// 某种情况下触发事件,使用:$('#id').on('eventName',function(event,data){});
$this.trigger('eventName','data');
        });
    }

// 实例方法 和 属性值 也通过插件方法实现

})(jQuery);
//匿名立即执行函数,闭包

选择器

先后流行的选择器引擎有:getElementBySelector、cssQuery

jquery采用的选择器sizzle 的工作步骤: 1、切割选择符(便于后面,先通过选择符的后段查找,再以选择符前段过滤)2、查找(通过四大原生查找函数,最差的情况就是getElementByTagName(*)),过滤,去重

最新的浏览器自带原生选择器API:querySelecter、querySelecterAll

静态展示网站

考虑到SEO,不适合使用MVVM框架,但要考虑国际化问题

动态效果,用jQuery 和 CSS 实现

共用的页头页脚用 $(".header").load("header.html");  导入

可以在项目里嵌套一个MVVM框架用于开发表单和复杂交互的页面,配置 publicPath / base

富文本 wangEditor 

GitHub - wangeditor-team/wangEditor: wangEditor —— 开源 Web 富文本编辑器

输出:html 片段

媒体文件:在 html 片段中插入 base64,或者 后端提供上传接口,html 片段中插入 上传后的url

wangEditor + Vue3

1、安装依赖

yarn add @wangeditor/editor
yarn add @wangeditor/editor-for-vue@next

2、使用

<template>
                <div style="border: 1px solid #ccc">
                    <Toolbar style="border-bottom: 1px solid #ccc" :editor="editorRef"
                             :defaultConfig="toolbarConfig" mode="default" ref="toolbar"/>
                    <Editor style="height: 200px;" v-model="form.content"
                            :defaultConfig="editorConfig" mode="default" @onCreated="handleCreated"/>
                </div>
</template>
<script>
    import '@wangeditor/editor/dist/css/style.css' // 引入 css
    import {Editor, Toolbar} from '@wangeditor/editor-for-vue'
    import {DomEditor} from '@wangeditor/editor'

    import {onBeforeUnmount, onMounted, ref, shallowRef} from 'vue'

    export default {
        name: "demo",
        components: {Editor, Toolbar},
        data() {
            return {
                form: {
                    content: ''
                },
                toolbarConfig: {
                    excludeKeys: ['fullScreen']   // 排除 全屏 按钮
                },
                editorConfig: {
                    placeholder: '请输入内容,字数2000字内',
                    maxLength: 2000,
                    autoFocus: false,
                    MENU_CONF: {
                        uploadImage: {
                            base64LimitSize: 10 * 1024, // 单位为byte,小于10kb则用base64
                            server: '/api/upload'  // 后端提供的上传图片接口
                        },
                        uploadVideo: {
                            server: '/api/upload'  // 后端提供的上传视频接口
                        }
                    }
                }
            };
        },
        setup() {
            const editorRef = shallowRef();
            onBeforeUnmount(() => {
                if (editorRef.value) {
                    editorRef.value.destroy();
                }
            });
            return {
                editorRef,
                handleCreated: (editor) => {
                    editorRef.value = editor;
                }
            };
        },
        methods: {
            submit() {
                // console.log(DomEditor.getToolbar(this.$refs.toolbar.editor));  // 查看toolbar全部配置
            }
        }
    };
</script>

PDF

HTML内容导出为PDF

1、安装依赖 

npm install  html2canvas --save

npm install  jspdf --save

2、下载 与 分页

<div id="pdfDom">
                    <div class="report_page" v-for="(page,index) in pages" :key="index">
                        <div :ref="'page_'+index)">
                            <table>
                                <tr>
                                </tr>
                                <tr v-for="(item,index) in page" :key="index">
                                </tr>
                            </table>
                        </div>
                        <div class="page_num">第 {{index+1}} 页</div>
                    </div>
</div>
            .report_page {
                box-sizing: border-box;
                height: 1705px;
                position: relative;
                padding: 40px;
            }

    import html2Canvas from 'html2canvas'
    import JsPDF from 'jspdf'           

 downloadPdf (title, selector) {
                html2Canvas(document.querySelector(selector), {
                    allowTaint: true,
                    taintTest: false,
                    scale: '2',
                    dpi: '192',
                    background: '#fff'
                }).then(function (canvas) {
                        let contentWidth = canvas.width;
                        let contentHeight = canvas.height;
                        let pageHeight = contentWidth / 592.28 * 841.89;
                        let leftHeight = contentHeight;
                        let position = 0;
                        let imgWidth = 595.28;
                        let imgHeight = 592.28 / contentWidth * contentHeight;
                        let pageData = canvas.toDataURL('image/jpeg', 1.0);
                        let PDF = new JsPDF('', 'pt', 'a4');
                        if (leftHeight < pageHeight) {
                            PDF.addImage(pageData, 'JPEG', 0, 0, imgWidth, imgHeight)
                        } else {
                            while (leftHeight > 0) {
                                PDF.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight);
                                leftHeight -= pageHeight;
                                position -= 841.89;
                                if (leftHeight > 0) {
                                    PDF.addPage()
                                }
                            }
                        }
                        PDF.save(title + '.pdf')
                    }
                )
            },
            makePage(){  // 分页,将要显示的 items 加工成 二维数组 pages
                if(this.pages.length === 0){  // 初始时 将所有 items 放到第一页
                    this.pages = [[].concat(this.items)];
                    this.$nextTick(()=>{
                        this.makePage();
                    });
                }
// 倒数第二页太长则将倒数第二页的最后一个item推到倒数第一页
                else if(this.pages.length-2 >=0 && this.$refs['page_'+(this.pages.length-2)].offsetHeight > 1625){   
                    let lastItem = this.pages[this.pages.length-2].pop();
                    this.pages[this.pages.length-1].unshift(lastItem);
                    this.pages = [].concat(this.pages);
                    this.$nextTick(()=>{
                        this.makePage();
                    });
                }
// 倒数第一页太长则新增一页,将最后一个item放到新增页
                else if(this.$refs['page_'+(this.pages.length-1)].offsetHeight > 1625){ 
                    let lastItem = this.pages[this.pages.length-1].pop();
                    this.pages.push([lastItem]);
                    this.pages = [].concat(this.pages);
                    this.$nextTick(()=>{
                        this.makePage();
                    });
                }
            },

3、使用

// 将一部分 dom 导出为 pdf  
this.downloadPdf("报告","#pdfDom");

HTML内容打印

1、生成PDF内容,参考上文

2、借用 iframe

<iframe ref="printIframe" style="display: none;" @load="iframeLoad" :src="pdfUrl"></iframe>

3、生成 iframe 用的 url

// PDF.output("datauristring") 得到的 DataURL 太长的话,iframe 不能正常加载;ObjectURL则无限制
this.report.pdfUrl = URL.createObjectURL(PDF.output('blob'));

4、使用

this.$refs.printIframe.contentWindow.print();  // 需保证 iframe 已经加载完成

另外,可以用 window.print() 来打印,但是无法控制布局 和 分页

let subWindow = window.open();
subWindow.document.body.innerHTML=window.document.getElementById("pdfDom").innerHTML;
subWindow.print();
subWindow.close();

浏览PDF

方式一、window.open(pdfUrl),浏览器默认方式

方式二、PDF.js,可以做一些定制

1、下载 PDF.js Prebuilt 包,放到项目中,作为单独的网页应用

2、打开 pdf 浏览器,传入pdfUrl,可以是 createObjectURL 产物

window.open('/pdfjs/web/viewer.html?file=' + pdfUrl);

Excel

SheetJS 导出 Excel

限制:设置单元格样式 需要交费购买SheetJS专业版

1、安装依赖 SheetJS

npm install xlsx --save

2、table 转 sheet 转 blob 转 ObjectUrl

import XLSX from 'xlsx'

            makeExcel() {
                let sheet = XLSX.utils.table_to_sheet(this.$refs.table);
                let workbook = {
                    SheetNames: ['总览'],
                    Sheets: {
                        '总览': sheet
                    }
                };
                let wopts = {
                    bookType: 'xlsx',
                    bookSST: false,
                    type: 'binary'
                };
                let wbout = XLSX.write(workbook, wopts);
                let blob = new Blob([this.s2ab(wbout)], {type: "application/octet-stream"});
                this.xlsxUrl = URL.createObjectURL(blob);
            },
            s2ab(s) {
                let buf = new ArrayBuffer(s.length);
                let view = new Uint8Array(buf);
                for (let i = 0; i != s.length; ++i) {
                    view[i] = s.charCodeAt(i) & 0xFF;
                }
                return buf;
            }

3、使用

<a :href="xlsxUrl" download="文件名.xlsx">文件下载</a>

ExcelJS 导出 Excel

1、安装依赖

npm install exceljs --save

2、生成

const ExcelJS = require('exceljs/dist/exceljs');
            makeExcel() {
                const workbook = new ExcelJS.Workbook();
                const worksheet = workbook.addWorksheet('工作簿1');
                worksheet.columns = [
                    {header: '列头1', key: 'column_1', width: 50},
                    {header: '列头2', key: 'column_2', width: 50}
                ];
                worksheet.addRow(["值1", "值2"]);
                workbook.xlsx.writeBuffer().then((buffer)=>{
                    let blob = new Blob([buffer], {type: "application/octet-stream"});
                    this.xlsxUrl = URL.createObjectURL(blob);
                });
            },

3、使用

<a :href="xlsxUrl" download="报告.xlsx">下载</a>

国际化

1、main.js

import VueI18n from 'vue-i18n'
new Vue({
  i18n: new VueI18n({
    locale: localStorage.getItem('locale') || 'en-US',
    messages: {}
  }),
  components: { App }
});

 2、App.vue 

watch: {
    "$i18n.locale": function () {
        this.fetchLang();
    }
},
methods: {
    fetchLang(){
        // 异步加载国际化词条
        if(this.$i18n.locale == 'en-US'){
            import('element-ui/lib/locale/lang/en').then((lang)=>{
                locale.use(lang);
            });
            import('./lang/en').then((lang)=>{
                this.$i18n.setLocaleMessage('en-US', lang)
                // 或者 mergeLocaleMessage
            });
        }
        else{
            import('element-ui/lib/locale/lang/zh-CN').then((lang)=>{
                locale.use(lang);
            });
            import('./lang/zh').then((lang)=>{
                this.$i18n.mergeLocaleMessage('zh-CN', lang)
            });
        }
    },
    changeLang(locale) {
        this.$i18n.locale = locale;
        localStorage.setItem('locale', locale);  // 语言选择保存到本地
    }
},
mounted() {
    this.fetchLang();
}

3、词条文件 

export const m = {
  "common": {
    "submit": "Submit"
  }
}

4、使用

$t('m.common.submit')

vue-i18n@9

<script main.js>
import { createApp } from 'vue';
import App from './App.vue';
import { createI18n } from 'vue-i18n';
import zhCN from './assets/lang/zhCN';
import en from './assets/lang/en';

let locale = localStorage.getItem('locale') || 'zhCN';
const i18n = createI18n({
    locale,
    legacy: false,
    messages: {
        en,
        zhCN,
    },
});

createApp(App).use(i18n).mount('#app');
</script>

<script>
    this.$t('dashboard.1');
    this.$i18n.locale;
</script>

<script>
  import { useI18n } from 'vue-i18n';
  setup() {
    const { t, locale } = useI18n();
    t('dashboard.1');
  }
</script>

<script setup>
  import { useI18n } from 'vue-i18n';
  const { t, locale } = useI18n();
  t('dashboard.1');
</script>

<template>
    <div>{{ $t('dashboard.1') }}{{$i18n.locale}}</div>
</template>

解压缩

解压 .zip

npm install jszip --save

import jszip from 'jszip';

jszip.loadAsync(file).then((zip) => {
    // zip.files 里既有文件也有目录,而且是平铺而不是嵌套,name里包含路径
    Object.values(zip.files).forEach((item) => {
        if (!item.dir  && item.name.endsWith('.***')) {
            item.async('blob').then((blob) => {
                let file = new File([blob], item.name.substring(item.name.lastIndexOf('.') + 1));
            });
        }
    });
});

解压 .tar.gz

 npm install pako --save

从 https://github.com/ankitrohatgi/tarballjs 下载 tarball.js

import pako from 'pako'
import { TarReader } from './tarball.js';

let reader = new FileReader();
reader.readAsArrayBuffer(tarGzFile);
reader.onload = () => {
    let byteArray = new Uint8Array(reader.result);
    byteArray = pako.ungzip(byteArray);
    let treader = new TarReader();
    treader.readFile(new File([byteArray], tarGzFile.name)).then((files) => {
        files.forEach((item) => {
            if (item.type === 'file' && item.name.endsWith('.***')) {
                let blob = treader.getFileBlob(item.name);
                let file = new File([blob], item.name.substring(item.name.lastIndexOf('.') + 1));
            }
        });
    });
};

JSEncrypt

import JSEncrypt from 'jsencrypt';

// RSA 公钥
let publicKey = `-----BEGIN PUBLIC KEY-----
            ***
            -----END PUBLIC KEY-----`;
let jse = new JSEncrypt();
jse.setPublicKey(publicKey);
jse.encrypt(source);  // 加密

Axios

// 提交文件
let formData = new FormData();
formData.append('field', field);
formData.append('file', file);
axios.post('/url', formData, {
    'Content-type': 'multipart/form-data',
});

// 下载文件
axios({
    method: 'get',
    url: `/url`,
    responseType: 'blob',
}).then((res) => {
    let blob = res.data;
    let objectUrl = URL.createObjectURL(res.data);
	let file = new File([res.data], 'filename', {type: 'application/xml', lastModified: Date.now()});
});

// 带 params 参数
axios({
    method: 'get',
    url: `/url`,
    params: new URLSearchParams(location.search)  // 解析URL参数
});

其他组件

时间:moment.js

代码编辑器:CodeMirror

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值