常用的三种许可证(Apache License 2.0、GNU General Public License v3.0、MIT License)简单介绍及区别

Apache License 2.0

简介:

Apache许可证(英语:Apache License),是一个由Apache软件基金会发布的自由软件许可证,最初为Apache http服务器而撰写。Apache许可证要求被授权者保留著作权和放弃权利的声明,但它不是一个反著作权的许可证。

此许可证最新版本为“版本2”,于2004年1月发布。

许可条件:

Apache许可证是宽容的,因为它不会强制派生和修改产物使用相同的许可证进行发布(与一些著作权许可证不同,参见比较)。但它仍然要求对所有未修改的部分应用相同的许可证,并且在每个许可文件中,必须保留再分发代码中的任何原始著作权,专利,商标和归属通知(不需要包括任何部分的派生作品);并且在每个更改的许可文件中,都必须添加一条通知,说明对该文件进行了更改。

如果声明文本文件作为原始作品发布的一部分包含在内,则派生作品必须在包含该通知文本文件的可读副本,可以是文档或显示在软件中。

声明文件的内容不会修改许可证,因为它们仅用于提供信息,并且可以在许可证文本中添加更多属性声明,前提是这些声明不能被理解为修改许可证。修改可能有适当的著作权声明,并可能为修改提供不同的许可条款。

除非另有明确规定,否则许可证持有者向授权者提交的任何文稿将根据许可证的条款进行,没有任何条款和条件,但这并不排除与授权者有关的这些贡献有单独的协议。

GNU General Public License v3.0

简介:

GNU通用公共许可协议(英语:GNU General Public License,缩写GNU GPL 或 GPL),是被广泛使用的自由软件许可证,给予了终端用户运行、学习、共享和修改软件的自由。许可证最初由自由软件基金会理查德·斯托曼为GNU项目所撰写,并授予计算机程序的用户自由软件定义(The Free Software Definition)的权利。 GPL是一个Copyleft许可证,这意味着派生作品只能以相同的许可条款分发。 这与宽松自由软件许可证有所区别 ,如BSD许可证MIT许可证就是其中被广泛使用的例子。 GPL是第一个普遍使用的Copyleft许可证。

许可条件:

GPL的条款和条件必须提供给任何接受GPL应用的作品的副本(“被许可人”)的人员。任何遵守条款和条件的被授证人员都有权修改作品,以及复制和重新分发作品或任何派生版本。被许可人被允许为此服务收取费用,或无偿。后一点将GPL与禁止商业再分发的软件许可区分开来。FSF认为,自由软件不应该限制商业用途,GPL明确规定GPL作品可能以任何价格出售。

GPL还规定,经销商不得对GPL授予的权利施加“进一步限制”。禁止根据不披露协议或合同分发软件等活动。

许可证版本2的第四部分和版本3的第七部分要求,作为预编译二进制文件分发的程序应附有源代码的副本,通过与前一版本相同的机制分发源代码的书面报价编译的二进制文件或书面报价,以获取用户在GPL下接收预编译二进制文件时获得的源代码。版本2的第二部分和版本3的第五部分还要求“所有收件人本程序附带的许可证副本”。 许可证的版本3允许以其他方式提供源代码来实现第七部分。这些包括从相邻网络服务器下载源代码或通过点对点传输,只要编译代码是可用的,并且在哪里可以找到源代码的“清晰方向”。

除非作者明确赋予 FSF 著作权(除了作为GNU项目一部分的程序很少发生),否则FSF对GPL发布的作品不具有著作权。只有个人著作权持有人有权在发生许可证时才起诉。

MIT License

简介:

MIT许可协议之名源自麻省理工学院(Massachusetts Institute of Technology, MIT),又称“X许可协议”(X License)或“X11许可协议”(X11 License)

MIT内容与三条款BSD许可协议(3-clause BSD license)内容颇为近似,但是赋予软件被许可人更大的权利与更少的限制。

许可条件:

被许可人有权利使用、复制、修改、合并、出版发行、散布、再许可和/或贩售软件及软件的副本,及授予被供应人同等权利,惟服从以下义务。

在软件和软件的所有副本中都必须包含以上著作权声明和本许可声明。

此许可协议并非属copyleft的自由软件许可协议条款,允许在自由及开放源代码软件或非自由软件(proprietary software)所使用。

MIT的内容可依照程序著作权者的需求更改内容。此亦为MIT与BSD(The BSD license, 3-clause BSD license)本质上不同处。

MIT许可协议可与其他许可协议并存。另外,MIT条款也是自由软件基金会(FSF)所认可的自由软件许可协议条款,与GPL兼容。

三种许可证的区别:

许可证名称

Apache License 2.0

GNU General Public License v3.0

MIT License

权限

✅商业用途
✅修改
  ✅分配
✅专利使用
✅私人使用

✅商业用途
 ✅修改
 ✅分配
 ✅专利使用
 ✅私人使用

✅商业用途
 ✅修改
 ✅分配
 ❎专利使用
 ✅私人使用

局限性

❎商标使用
 ❎责任
 ❎保证

✅商标使用
 ❎责任
 ❎保证

✅商标使用
 ❎责任
 ❎保证

条件

✅许可和版权声明
 ✅状态变更
❎公开来源
 ❎相同许可证

✅许可和版权声明
 ✅状态变更
✅公开来源
 ✅相同许可证

✅许可和版权声明
 ❎状态变更
❎公开来源
 ❎相同许可证

生产力工具uTools

uTools是一个极简、插件化、跨平台的现代桌面软件。通过自由选配丰富的插件,打造你得心应手的工具集合。当你熟悉它后,能够为你节约大量时间,让你可以更加专注地改变世界。

官网地址: https://u.tools/
支持Windows,Mac,Linux

通过快捷键(默认alt+space)就可以快速呼出这个搜索框。它相当聪明,可以支持输入、拖拽、自动粘贴等作为输入源,相应的插件也早已准备就绪,统一的设计风格和操作方式,助你高效的得到结果。

uTools能做什么?

最简单的,uTools可以作为一个程序快速启动器,支持英文、英文驼峰、中文拼音、拼音首字母来打开你的本地程序。除程序外,win10和mac用户还可以快速搜索并打开「控制面板」内的细项。总之,你只要还记得一个大概的名字,直接输入基本都能找到。

针对中文特别优化,例如可以通过搜索记事本jsb打开记事本,而不是搜索notepad

程序启动器仅仅是最基础的功能,uTools最大的特点就是拥有强大的插件系统,每个插件都有简洁美观、易于操作的界面,输入plugins进入插件管理,你就可以根据自己的需求挑选安装,组合成自己最趁手的工具合集,为各种日常操作提供便利。不断产生的新插件,也将为你带来无限可能。

多样的插件可大大提高工作效率

特性

  • 插件化: 优秀的插件化设计,自取所需。每个插件解决一个具体场景的问题,简洁易用、随用随走。
  • 多功能输入框: 支持文本、截图、图片、文件、文件夹
  • 自动识别: 自动识别文本类型(json、base64、时间戳等)
  • 自动粘贴: 呼出uTools时,如果剪切板中5秒内有新的内容,将自动粘贴到输入框
  • 全局快捷键: 配合插件,可一键上传截图到图床、以图搜图、翻译剪贴板内容等
  • 数据同步: 云端同步,永不丢失

uTools支持在插件中心中下载文档

uTools支持导入开发文档,快捷搜索

利用forEach循环Dom元素

DOM,主要用来修改HTML的标准编程接口,可以用来修改各种html标签内容 和属性 样式。

查找:

document: 整个文档。 

1
document.getElementsByTagName
1
document.getElementById
1
document.getElementsByClassName
1
document.querySelector
1
document.querySelectorAll

遍历节点:

1
var div = document.getElementsByClassName('con')[0];

div.parentNode-> 父节点  (最顶端的parentNode为#document);
遍历元素:

div.children 遍历所有的子元素(孙子就不算)这就是一个对象,可以.length属性

获取节点类型:div.firstElementChild.nodeType

元素节点 —— 1
属性节点 —— 2
文本节点 —— 3
注释节点 —— 8
document —— 9
DocumentFragment —— 11
获取节点类型 nodeType

forEach是循环数组用的,但是它不能循环Dom元素。
可以利用call来完成forEach循环Dom;

假设有这样的HTML结构:

1
2
3
4
5
6
7
<ul class="box">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>

点击上面的LI来输出自身的索引值,具体可看下面代码:

1
2
3
4
5
6
var arrLi = document.querySelector(".box").children;
Array.prototype.forEach.call(arrLi, function(ele, index) {
ele.onclick = function() {
alert(index)
}
})

需要注意的是,在IE8及以下是不支持forEach的,所以我们需要做下兼容,使用以下方法:

1
2
3
4
5
6
7
8
9
10
// 兼容IE8以下浏览器方法:
if (!Array.prototype.forEach) {
Array.prototype.forEach = function(fun) {
for (var i = 0; i < this.length; i++) {
if (i in this) {
fun.call(arguments[1], this[i], i, this);
}
}
};
}

关于网站版权声明(Copyright)的格式和写法

美国产权局关于版权声明格式的说明

参考标准和格式是美国产权局的说明:http://www.copyright.gov/

Form of Notice for Visually Perceptible Copies
对于可视化的,或者图形的(比如书籍,电影,网页,软件)版权声明,应该具备如下三部分。
1. The symbol© (the letter C in a circle), or the word “Copyright,” or the abbreviation “Copr.”; and 

1。符号©(字母C外加一个圆),或者单词“Copyright”版权,或者缩写“Copr.”以及 

2. The year of first publication of the work. In the case of compilations or derivative works incorporating previously published material, the year date of first publication of the compilation or derivative work is sufficient. The year date may be omitted where a pictorial, graphic, or sculptural work, with accompanying textual matter, if any, is reproduced in or on greeting cards, postcards, stationery, jewelry, dolls, toys, or any useful article; and 

2。作品初次公开发表的年份。如果是之前发表材料的编辑或者衍生(编辑比如:文选,衍生比如:翻译或者编剧),有权利使用编辑或者衍生作品的最初发表年份。画报,绘画或者雕塑复制在贺卡,明信片,文具,珠宝,玩偶,玩具或者其他有用的物品上,如果有伴随的文本材料时,年份可以省略。以及 

3. The name of the owner of copyright in the work, or an abbreviation by which the name can be recognized, or a generally known alternative designation of the owner. 

3。作品的版权拥护者名称,或者可识别的拥有者名称缩写,或者是拥有者的其他为公众知晓的名称。 

Example: ©2006 John Doe 

The “C in a circle” notice is used only on “visually perceptible copies.” Certain kinds of works—for example, musical, dramatic, and literary works—may be fixed not in “copies” but by means of sound in an audio recording. Since audio recordings such as audio tapes and phonograph disks are “phonorecords” and not “copies,” the “C in a circle” notice is not used to indicate protection of the underlying musical, dramatic, or literary work that is recorded. 

圆圈中一个字母C的标志只能使用在“可视化的拷贝”。某类作品,比如音乐,戏剧和文学作品,可能没有在拷贝中,而是出现在音频记录中的声音。音位音频记录比如音频磁带和留声机磁盘等,是唱片,而不是拷贝,圆圈中C的标志不被用来表明对记录在这里的音乐,戏剧和文学作品的保护。 

来自民间的关于版权声明格式的说明

从法律角度看,加入了伯尔尼公约的国家,版权保护是随着作品(无论是文字,还是图片)的问世的即刻就得到版权的保护的,并不是必须要声明。但是作为惯例,这一小行文字还是有很好加强意识,提醒浏览者,所观看的内容是受到版权保护的。 

正确的格式应该是:Copyright [dates] by [author/owner] 

© 通常可以代替Copyright, 但是不可以用(c)。 All Rights Reserved 在某些国家曾经是必须的,但是现在在大多数国家,都不是法律上必须有的字样。 

参见下面几个正确的格式: 

©1995-2004 Macromedia, Inc. All rights reserved. 

©2004 Microsoft Corporation. All rights reserved. 

Copyright © 2004 Adobe Systems Incorporated. All rights reserved. 

©1995-2004 Eric A. and Kathryn S. Meyer. All Rights Reserved. 

请注意标点符号和大小写的用法,这也是专业精神的一种体现。

现在流行some rights reserved:creativecommons.org

some rights reserved 和copyright 本身并不矛盾,但是其中的界限更多是一个道德问题,真正的保留一部分权力,是指给浏览者fair use 的权利,fair use的界定也决不是随便乱用,或者抄袭。

甚至说,除了copyright, 还有copyleft,它的定义是为了程序员开发能够共享源代码的一个方式,英文里free, 并不仅仅是免费。 而且这种的源码公开免费使用,和版权也一点都不冲突。请大家不要误解。

对于从网上下载素材,如音乐,图片等版权问题, 有朋友问这个问题,答案很简单,所有的这些都有版权问题。和这些作品的大小格式没有关系。

版权是互相的,因为每个人都在随时的拥有着你所刚刚创造的作品的版权,哪怕你的涂鸦之作已经被丢进垃圾桶,严格意义上,那也不可以被人抄袭的。不然公司就不需要碎纸机了。

只有彼此的尊重,互相的尊重才能有真正意义上的共享,简单的拿来主义,或者因为我是经典的用户,所以别人就必须要尊重经典的版权,而我不必尊重别人的版权,是不会形成好的版权保护意识的。

版权其实并不意味着付费,和商业化也没有直接的关联。很多时候,你如果真想使用版权保护的内容,只要发封邮件,询问一下许可就可以, 大多数的情形下,个人用户是很喜欢甚至欣赏这样的礼貌和尊重的。

版权问题中很多的灰色地带,我想与其总是用法律的角度来要求用户,还不如让我们都从自己的道德来判断,从尊重的角度来取舍。

HTML常用meta

Meta标签是HTML中的一个辅助性标签,位于HTML文档头部和title标签之间,提供用户不可见的信息。
Meta:即元数据(Metadata)是数据的数据信息。

元数据可以被使用浏览器,搜索引擎或其他Web服务调用。

基础数据设置

  • 定义文档的字符编码
    <meta charset="utf-8" />
  • 强制浏览器内核为Chromium内核(主要用于国产双核浏览器)
    <meta name="renderer" content="webkit" />
    <meta name= "force-rendering" content="webkit" />
  • 如果有安装Google Chrome Frame插件则强制为Chromium内核,否则强制为本机支持的最高版本IE内核,(作用于IE浏览器)
    <meta http=equiv="X-UA-Compatible" content="IE=Edge,chrome=1" />
  • 设置视窗大小
    width:设置layout viewport的宽度,为一个正整数,或为字符串“width-device”;
    initial-scale:设置页面的初始缩放值,为一个数字,可以带小数;
    minimum-scale:允许用户的最小缩放值,为一个数字,可以带小数;
    maximum-scale:允许用户的最大缩放值,为一个数字,可以带小数;
    shrink-to-fit=no:IOS9中使以上属性生效时加入;
    height:设置layout viewport的高度,为一个正整数(通常很少使用);
    user-scalable:是否允许用户进行缩放,值为“no”或“yes”,“no”代表不允许,“yes”代表允许;
    <meta name="viewport" content="width=device-width,initial-scale=1.0,shrink-to-fit=no,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" />
  • 页面描述
    <meta name="description" content="不超过150个字符" />
  • 页面关键词
    <meta name="keywords" content="空格或“,”隔开" />
  • 网页作者
    <meta name="author" content="name,email@xxx.com" />
  • 搜索引擎抓取
    all:文件将被检索,且页面上的链接可以被查询;
    none:文件将不被检索,且页面上的链接不可以被查询;
    index:文件将被检索;
    follow:页面上的链接可以被查询;
    noindex:文件将不被检索;
    nofollow:页面上的链接不可以被查询。
    <meta name="robots" content="index,follow" />
  • 忽略页面中的数字识别为电话,忽略email识别
    <meta name="format-detection" content="telphone=no,email=no" />

针对浏览器

  • 拒绝百度转码
    <meta http-equiv="Cache-Control" content="no-siteapp" />
  • 针对手持设备优化,主要针对一些老的不识别viewport的浏览器
    <meta name="HandheldFriendly" content="true" />
  • 针对微软老式浏览器
    <meta name="MobileOptimized" content="320" />
  • UC强制竖屏
    <meta name="screen-orientation" content="portrait" />
  • QQ强制竖屏
    <meta name="x5-orientation" content="portrait" />
  • UC强制全屏
    <meta name="full-screen" content="yes" />
  • QQ强制全屏
    <meta name="x5-fullscreen" content="true" />
  • UC应用模式
    <meta name="browsermode" content="application" />
  • QQ应用模式
    <meta name="x5-page-mode" content="app" />
  • Windows Phone点击无高光
    <meta name="msapplication-tap-highlight" content="no" />

针对IOS数据设置

  • 添加到主屏后的标题
    <meta name="apple-mobile-web-app-title" content="标题" />
  • 当网站添加到主屏幕快速启动方式,可隐藏地址栏,仅针对IOS的Safari浏览器(IOS7.0版本以后,Safari上已看不到效果)
    <meta name="apple-mobile-web-app-capable" content="yes" />
  • 是否启用Webapp全屏模式,删除苹果默认的工具栏和菜单栏
    <meta name="apple-touch-fullscreen" content="yes" />
  • 添加智能App广告条Smart App Banner(IOS6+ Safari)
    <meta name="apple-itunes-app" content="app-id=myAppStoreID,affiliate-data=myAffiliateData,app-argument=myURL" />
  • 设置苹果工具栏颜色:默认值为default(白色),可以设置为black(黑色)和black-translucent(灰色半透明)
    <meta name="apple-mobile-web-app-status-bar-style" content="black" />

IOS网站添加至桌面时的图标

  • iPhone和iTouch,默认57x57像素,必须设置
    <link rel="apple-touch-icon-precomposed" sizes="57x57" href="table_ico57.png">
  • Retina iPhone 和 Retina iTouch,114x114 像素,可以没有,但推荐有
    <link rel="apple-touch-icon-precomposed" sizes="72x72" href="table_ico72.png">
    <link rel="apple-touch-icon-precomposed" sizes="114x114" href="table_ico114.png">
  • Retina iPad,144x144 像素,可以没有,但推荐有
    <link rel="apple-touch-icon-precomposed" sizes="144x144" href="table_ico144.png">

IOS启动画面

  • iPad 竖屏 768 x 1004(标准分辨率)
    <link rel="apple-touch-startup-image" sizes="768x1004" href="/splash-screen-768x1004.png"/>
  • iPad 横屏 1024x748(标准分辨率)
    <link rel="apple-touch-startup-image" sizes="1024x748" href="/Default-Portrait-1024x748.png"/>
  • iPad 竖屏 1536x2008(Retina)
    <link rel="apple-touch-startup-image" sizes="1536x2008" href="/splash-screen-1536x2008.png"/>
  • iPad 横屏 2048x1496(Retina)
    <link rel="apple-touch-startup-image" sizes="2048x1496" href="/splash-screen-2048x1496.png"/>
  • iPhone/iPod Touch 竖屏 320x480 (标准分辨率)
    <link rel="apple-touch-startup-image" href="/splash-screen-320x480.png"/>
  • iPhone/iPod Touch 竖屏 640x960 (Retina)
    <link rel="apple-touch-startup-image" sizes="640x960" href="/splash-screen-640x960.png"/>
  • iPhone 5/iPod Touch 5 竖屏 640x1136 (Retina)
    <link rel="apple-touch-startup-image" sizes="640x1136" href="/splash-screen-640x1136.png"/>

Windows 8磁贴设置

  • Windows 8 磁贴颜色
    <meta name="msapplication-TileColor" content="#000"/>
  • Windows 8 磁贴图标
    <meta name="msapplication-TileImage" content="icon.png"/>
  • 添加 RSS 订阅
    <link rel="alternate" type="application/rss+xml" title="RSS" href="/rss.xml"/>

SNS社交标签

  • 参考微博API
    ` `

低版本IE浏览器访问问题

添加好强制Webkit内核的代码,使用国产浏览器访问网站已经不存在IE兼容问题了,IE访客量将大大减少。但仍然不可避免会有一些老旧电脑通过低版本IE浏览器访问,如果我们专门为了这极小部分用户进行 CSS HACK ,将严重加重我们的工作量。
更何况自2016年1月起微软已经停止为IE11以下版本提供支持和更新,已经这么久没有更新,低版本IE不仅对CSS3和HTML5支持有问题,更有安全问题。
那么,我们不去支持低版本IE,这小部分用户怎么办呢?
我们可以使用 if IE 语句给网站添加IE升级提示,提示用户进行浏览器升级,或者切换更先进的浏览器再访问。
我们可以在刚刚的meta标签下添加一段跳转到IE升级提示页的代码(当IE版本低于IE11时跳转),实现低版本IE用户访问时提示他们进行升级或者更换浏览器。
强制Webkit内核和提示低版本IE访问用户升级完整代码如下所示,把这段代码添加到头部模板文件标签下即可:

(@cc\_on 是 IE10 及更旧版IE特有的条件编译语句,因此可以用来判断是否除 IE11 以外的其他IE版本。) 因为低版本IE访问时因为不兼容CSS3和HTML5网站往往是错版的,添加了上面这段代码,当低版本IE用户访问时就会跳转到升级提示页,避免不必要的资源加载,降低网站服务器开销。

解决Vue中数据改变,DOM未重新渲染的问题

组件内部,属性值地址空间内引用地址改变,DOM不能渲染。

问题举例:
数据改变了,但是页面没有渲染。

例:this.items = [[],[],[],[]]

问题原因:
这种情况下一般都是数组和json才会发生。

items 中,修改任意一项数组中的值,DOM是不会更新的。

解决方案:

this.items = [...this.items]。通过解构赋值,重新给items赋值。

组件之间传值,父组件传data改变,子组件未更新。

子组件中在mounted中对父组件传的值,进行了判断等相关处理,通过改变子组件自身定义的状态实现效果。
此时,父组件值更新,子组件不重新渲染,是因为,父组件值改变子组件不会走mounted的生命周期。

处理方案:

使用watch监听父组件传的值,当值改变的时候,进行对应操作。
推荐使用:
子组件中直接使用父组件传的值,如需类型转换或者简单判断,直接通过三目运算符判断使用,就省去了对 父组件传值的监听步骤。

Promise简单应用

1.加载图片

1
2
3
4
5
6
7
8
const preloadImage = function (path) {
return new Promise(function (resolve, reject) {
const image = new Image();
image.onload = resolve;
image.onerror = reject;
image.src = path;
});
};

2.Generator函数与Promise的结合

Generator 函数与 Promise 的结合

使用 Generator 函数管理流程,遇到异步操作的时候,通常返回一个Promise对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
function getFoo () {
return new Promise(function (resolve, reject){
resolve('foo');
});
}

const g = function* () {
try {
const foo = yield getFoo();
console.log(foo);
} catch (e) {
console.log(e);
}
};

function run (generator) {
const it = generator();

function go(result) {
if (result.done) return result.value;

return result.value.then(function (value) {
return go(it.next(value));
}, function (error) {
return go(it.throw(error));
});
}

go(it.next());
}

run(g);

上面代码的 Generator 函数g之中,有一个异步操作getFoo,它返回的就是一个Promise对象。函数run用来处理这个Promise对象,并调用下一个next方法。

JavaScript常用数组遍历方法

  1. 普通的for循环
    let arr = [1,2,3,4,5,6,7,8,9]; for (let i = 0; i < arr.length; i ++) { console.log(arr[i]); }
    //最简单,**使用频率最高**的一种遍历方法,虽然性能不弱,但仍有优化空间
    for (let i = 0,len = arr.length; i < len; i ++) { conso.log(arr[i]); }
    //使用临时变量保存数组长度,避免重复获取数组长度,**当数组较大时优化效果才会比较明显**
    for (let i = 0; arr[i] != null; i ++) { console.log(arr[i]); }
    //使用数组项本身判断的循环,**性能要远小于普通for循环**
  2. forEach循环
    let arr = [1,2,3,4,5,6,7,8,9] arr.forEach((item, index) => { console.log(item,index); })
    //使用频率较高,**性能稍弱于普通for循环**,代码比较简单,缺点是无法中断停止整个循环
  3. for . . . in . . . 循环
    let arr = [1,2,3,4,5,6,7,8,9] for (let i in arr) { console.log(i); }
    //更常用于对象的遍历,在众多循环遍历方式中**效率最低**
  4. for . . . of . . . 循环
    let arr = [1,2,3,4,5,6,7,8,9] for (let i of arr) { console.log(i); }
    //可以通过break方法终止循环,continute方法跳过当次循环,**性能要好于for . . . in . . .循环,但仍比不上普通for循环**
  5. filter
    let arr = [1,2,3,4,5,6,7,8,9] arr.filter((item, index) => { console.log(item); }) //不会对空数组进行检测,不会改变原始数组
  6. map
    let arr = [1,2,3,4,5,6,7,8,9] let newArr = arr.map((item, index) => { return item; }) //支持return返回值,使用效率比forEach低
  7. every
    let arr = [1,2,3,4,5,6,7,8,9] arr.every((item, index) => { return item> 5; }) //检测数组所有元素是否都符合条件返回true,否则返回false
  8. some
    let arr = [1,2,3,4,5,6,7,8,9] arr.some((item, index) => { return item > 7; }) //检测到数组中只要有一个值符合条件就返回true,剩下的元素都不会继续执行,全部不符合则返回false
  9. reduce && reduceRight
    let arr = [1,2,3,4,5,6,7,8,9] let newArr = arr.reduce((preTotal, curValue, index, array) =>{ return preTotal + curValue; }) //reduce()接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终为一个值。reduceRight则是从右到左开始
  10. find && findIndex
    let arr = [1,2,3,4,5,6,7,8,9] let result = arr.find((item, index) => { if (index == 5) { return item; } }) //find返回数组中符合条件的第一个元素,否则返回undefined,findIndex返回数组中符合条件的第一个元素的下标

Element UI Input输入框限制数字输入

1
2
3
4
<el-form-item label="发布版本号:" prop="version" class="versionAction">
<el-input v-model="xxx.xxx" maxlength="8" onkeyup="value=value.replace(/[^\d.]/g,'')" onblur="value.slice(-1) == '.'value = value.slice(0,value.length - 1):''" onKeypress="javascript:if(event.keyCode == 32)event.returnValue = false;">
</el-input>
</el-form-item>

onKeyUp:键盘抬起时事件

onBlur:输入框失去焦点事件

onKeyPress:键盘按下时事件

Vue中使用wangEditor3

安装

通过npm安装:

1
npm install wangeditor

创建实例

基本用法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<template>
<div>
<div id="editor" class="editor"></div>
</div>
</template>

<script>
//导入wangEditor
import E from 'wangeditor'
export default {
name: 'editor',
mounted () {
var editor = new E('#editor')
editor.customConfig.onchange = (html) => {
this.formArticle.content = html
}
//创建编辑器实例
editor.create()
}
}
</script>

简单的富文本编辑器实例

将菜单与编辑器主体分离:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<template>
<div>
<div id="editorMenu" class="editorMenu"></div>
<div id="editor" class="editor"></div>
</div>
</template>

<script>
import E from 'wangeditor'
export default {
name: 'editor',
mounted () {
var editor = new E('#editorMenu', '#editor')// 两个参数也可以传入 elem 对象,class 选择器
editor.customConfig.onchange = (html) => {
this.formArticle.content = html
}
editor.create()
}
}
</script>

<style scoped>
.editorMenu {
border: 1px solid #ccc;
}
.editor {
margin-top: -1px;//将多出来的一像素边框隐藏
border: 1px solid #ccc;
min-height: 400px;//编辑框最小高度
height:auto;//编辑框高度超过最小高度会根据内容高度自适应
}
</style>

菜单与主体分离的编辑器

上传本地图片tab配置/隐藏网络图片tab配置:

1
2
3
4
5
6
// 下面两个配置,使用其中一个即可显示“上传图片”的tab。但是两者不要同时使用!!!
editor.customConfig.uploadImgShowBase64 = true // 使用 base64 保存图片
editor.customConfig.uploadImgServer = '/upload' // 上传图片到服务器

// 隐藏“网络图片”tab
editor.customConfig.showLinkImg = false

上传图片tab

网络图片tab

上传图片到服务器配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
// 配置服务器端地址
editor.customConfig.uploadImgServer = '服务器接口地址'
//自定义filename
editor.customConfig.uploadFileName = 'file'
//自定义上传参数
editor.customConfig.uploadImgHeaders = {
'Accept' :'*/*',
'Blade-Auth':xxxx
}
// 将图片大小限制为 3M
editor.customConfig.uploadImgMaxSize = 3 * 1024 * 1024
// 限制一次最多上传 5 张图片
editor.customConfig.uploadImgMaxLength = 5


//使用监听函数处理上传图片的不同阶段
editor.customConfig.uploadImgHooks = {
before: function (xhr, editor, files) {
// 图片上传之前触发
// xhr 是 XMLHttpRequst 对象,editor 是编辑器对象,files 是选择的图片文件
// 如果返回的结果是 {prevent: true, msg: 'xxxx'} 则表示用户放弃上传
// return {
// prevent: true,
// msg: '放弃上传'
// }
},
success: function (xhr, editor, result) {
// 图片上传并返回结果,图片插入成功之后触发
// xhr 是 XMLHttpRequst 对象,editor 是编辑器对象,result 是服务器端返回的结果
},
fail: function (xhr, editor, result) {
// 图片上传并返回结果,但图片插入错误时触发
// xhr 是 XMLHttpRequst 对象,editor 是编辑器对象,result 是服务器端返回的结果
},
error: function (xhr, editor) {
// 图片上传出错时触发
// xhr 是 XMLHttpRequst 对象,editor 是编辑器对象
},
timeout: function (xhr, editor) {
// 图片上传超时时触发
// xhr 是 XMLHttpRequst 对象,editor 是编辑器对象
},
// 如果服务器端返回的不是 {errno:0, data: [...]} 这种格式,可使用该配置
// (但是,服务器端返回的必须是一个 JSON 格式字符串!!!否则会报错)
customInsert: function (insertImg, result, editor) {
// 图片上传并返回结果,自定义插入图片的事件(而不是编辑器自动插入图片!!!)
// insertImg 是插入图片的函数,editor 是编辑器对象,result 是服务器端返回的结果
// 举例:假如上传图片成功后,服务器端返回的是 {url:'....'} 这种格式,即可这样插入图片:
var url = result.url
insertImg(url)
// result 必须是一个 JSON 格式字符串!!!否则报错
}
}


//自定义上传图片错误时的提示效果(默认为alert弹窗)
editor.customConfig.customAlert = function (info) {
// info 是需要提示的内容
alert('自定义提示:' + info)
}


//完全控制上传图片过程
editor.customConfig.customUploadImg = function (files, insert) {
// files 是 input 中选中的文件列表
// insert 是获取图片 url 后,插入到编辑器的方法
// 上传代码返回结果之后,将图片插入到编辑器中
insert(imgUrl)
}

更多配置请参考wangEditor3官方文档:

https://www.kancloud.cn/wangfupeng/wangeditor3/332599

将wangEditor作为组件使用:

子组件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
<template>
<div id="wangeditor">
<div ref="editorElem" style="text-align:left"></div>
</div>
</template>

<script>
import E from 'wangeditor'
export default {
name: 'editorElem',
data () {
return {
editorContent: '',
}
},
props:['catchData'], //接收父组件的方法
mounted() {
var editor = new E(this.$refs.editorElem) //创建富文本实例
editor.customConfig.onchange = (html) => {
this.editorContent = html
this.catchData(html) //把这个html通过catchData的方法传入父组件
}
editor.customConfig.uploadImgServer = '你的上传图片的接口'
editor.customConfig.uploadFileName = '你自定义的文件名'
editor.customConfig.uploadImgHeaders = {
'Accept': '*/*',
'Authorization':'Bearer ' + token //头部token
}
//wangEditor3中菜单栏无法换行显示,如菜单项内容超出则需要对菜单项进行删减
editor.customConfig.menus = [ //菜单配置
'head', // 标题
'bold', // 粗体
'fontSize', // 字号
'fontName', // 字体
'italic', // 斜体
'underline', // 下划线
'strikeThrough', // 删除线
'foreColor', // 文字颜色
'backColor', // 背景颜色
'link', // 插入链接
'list', // 列表
'justify', // 对齐方式
'quote', // 引用
'emoticon', // 表情
'image', // 插入图片
'table', // 表格
'video', // 插入视频
'code', // 插入代码
'undo', // 撤销
'redo' // 重复
]
//下面是最重要的的方法
editor.customConfig.uploadImgHooks = {
before: function (xhr, editor, files) {
// 图片上传之前触发
// xhr 是 XMLHttpRequst 对象,editor 是编辑器对象,files 是选择的图片文件
// 如果返回的结果是 {prevent: true, msg: 'xxxx'} 则表示用户放弃上传
// return {
// prevent: true,
// msg: '放弃上传'
// }
},
success: function (xhr, editor, result) {
// 图片上传并返回结果,图片插入成功之后触发
// xhr 是 XMLHttpRequst 对象,editor 是编辑器对象,result 是服务器端返回的结果
this.imgUrl=Object.values(result.data).toString()
},
fail: function (xhr, editor, result) {
// 图片上传并返回结果,但图片插入错误时触发
// xhr 是 XMLHttpRequst 对象,editor 是编辑器对象,result 是服务器端返回的结果
},
error: function (xhr, editor) {
// 图片上传出错时触发
// xhr 是 XMLHttpRequst 对象,editor 是编辑器对象
},
timeout: function (xhr, editor) {
// 图片上传超时时触发
// xhr 是 XMLHttpRequst 对象,editor 是编辑器对象
},
// 如果服务器端返回的不是 {errno:0, data: [...]} 这种格式,可使用该配置
// (但是,服务器端返回的必须是一个 JSON 格式字符串!!!否则会报错)
customInsert: function (insertImg, result, editor) {
// 图片上传并返回结果,自定义插入图片的事件(而不是编辑器自动插入图片!!!)
// insertImg 是插入图片的函数,editor 是编辑器对象,result 是服务器端返回的结果
// 举例:假如上传图片成功后,服务器端返回的是 {url:'....'} 这种格式,即可这样插入图片:
let url = Object.values(result.data) //result.data就是服务器返回的图片名字和链接
JSON.stringify(url) //在这里转成JSON格式
insertImg(url)
// result 必须是一个 JSON 格式字符串!!!否则报错
}
}
editor.create()
}
}
</script>

父组件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<template>
<div>
<wangeditor :catchData="catchData"></wangeditor>
</div>
</template>

<script>
import wangeditor from './wangeditor'
data(){
return{
content:""
}
},
methods:{
catchData(value){
this.content=value //在这里接受子组件传过来的参数,赋值给data里的参数
}
},
components: {
wangeditor
},
</script>

修改编辑器默认高度:

1
2
3
4
//wangEditor3中默认高度为300px
.w-e-text-container{
height: 700px !important;/*!important是重点,因为原div是行内样式设置的高度300px*/
}