JS前端技術(shù)類文章
前沿
裝飾器
裝飾器是一種函數(shù),寫成@ + 函數(shù)名。它可以放在類和類方法的定義前面。
裝飾器的行為
@decorator
class?A?{}
//?等同于
class?A?{}
A?=?decorator(A)?||?A;
裝飾器函數(shù)的第一個(gè)參數(shù),就是所要裝飾的目標(biāo)類。
注意,裝飾器對(duì)類的行為的改變,是代碼編譯時(shí)發(fā)生的,而不是在運(yùn)行時(shí)。這意味著,裝飾器能在編譯階段運(yùn)行代碼。也就是說(shuō),裝飾器本質(zhì)就是編譯時(shí)執(zhí)行的函數(shù)。
添加實(shí)例屬性
function?testable(target)?{
??target.prototype.isTestable?=?true;
}
@testable
class?MyTestableClass?{}
let?obj?=?new?MyTestableClass();
obj.isTestable?//?true
Object.assign()
Object.assign()?方法用于將所有可枚舉屬性的值從一個(gè)或多個(gè)源對(duì)象分配到目標(biāo)對(duì)象。它將返回目標(biāo)對(duì)象。
const?target?=?{?a:?1,?b:?2?};
const?source?=?{?b:?4,?c:?5?};
const?returnedTarget?=?Object.assign(target,?source);
console.log(target);
//?expected?output:?Object?{?a:?1,?b:?4,?c:?5?}
console.log(returnedTarget);
//?expected?output:?Object?{?a:?1,?b:?4,?c:?5?}
Object.assign(target,?...sources)
如果目標(biāo)對(duì)象中的屬性具有相同的鍵,則屬性將被源對(duì)象中的屬性覆蓋。后面的源對(duì)象的屬性將類似地覆蓋前面的源對(duì)象的屬性。
[復(fù)制一個(gè)對(duì)象]
const?obj?=?{?a:?1?};
const?copy?=?Object.assign({},?obj);
console.log(copy);?//?{?a:?1?}
[深拷貝問(wèn)題]
針對(duì)深拷貝,需要使用其他辦法,因?yàn)?Object.assign()拷貝的是(可枚舉)屬性值。
const?log?=?console.log;
function?test()?{
??'use?strict';
??let?obj1?=?{?a:?0?,?b:?{?c:?0}};
??let?obj2?=?Object.assign({},?obj1);
??log(JSON.stringify(obj2));
??//?{?a:?0,?b:?{?c:?0}}
??obj1.a?=?1;
??log(JSON.stringify(obj1));
??//?{?a:?1,?b:?{?c:?0}}
??log(JSON.stringify(obj2));
??//?{?a:?0,?b:?{?c:?0}}
??obj2.a?=?2;
??log(JSON.stringify(obj1));
??//?{?a:?1,?b:?{?c:?0}}
??log(JSON.stringify(obj2));
??//?{?a:?2,?b:?{?c:?0}}
??obj2.b.c?=?3;
??log(JSON.stringify(obj1));
??//?{?a:?1,?b:?{?c:?3}}
??log(JSON.stringify(obj2));
??//?{?a:?2,?b:?{?c:?3}}
??//?Deep?Clone
??obj1?=?{?a:?0?,?b:?{?c:?0}};
??let?obj3?=?JSON.parse(JSON.stringify(obj1));
??obj1.a?=?4;
??obj1.b.c?=?4;
??log(JSON.stringify(obj3));
??//?{?a:?0,?b:?{?c:?0}}
}
test();
[合并對(duì)象]
const?o1?=?{?a:?1?};
const?o2?=?{?b:?2?};
const?o3?=?{?c:?3?};
const?obj?=?Object.assign(o1,?o2,?o3);
console.log(obj);?//?{?a:?1,?b:?2,?c:?3?}
console.log(o1);??//?{ a: 1, b: 2, c: 3 }, 注意目標(biāo)對(duì)象自身也會(huì)改變。
[合并具有相同屬性的對(duì)象]
const?o1?=?{?a:?1,?b:?1,?c:?1?};
const?o2?=?{?b:?2,?c:?2?};
const?o3?=?{?c:?3?};
const?obj?=?Object.assign({},?o1,?o2,?o3);
console.log(obj);?//?{?a:?1,?b:?2,?c:?3?}
[拷貝 symbol 類型的屬性]
const?o1?=?{?a:?1?};
const?o2?=?{?[Symbol('foo')]:?2?};
const?obj?=?Object.assign({},?o1,?o2);
console.log(obj);?//?{?a?:?1,?[Symbol("foo")]:?2?}?(cf.?bug?1207182?on?Firefox)
Object.getOwnPropertySymbols(obj);?//?[Symbol(foo)]
[繼承屬性和不可枚舉屬性是不能拷貝的]
[原始類型會(huì)被包裝為對(duì)象]
const?v1?=?"abc";
const?v2?=?true;
const?v3?=?10;
const?v4?=?Symbol("foo")
const?obj?=?Object.assign({},?v1,?null,?v2,?undefined,?v3,?v4);
//?原始類型會(huì)被包裝,null 和 undefined 會(huì)被忽略。
//?注意,只有字符串的包裝對(duì)象才可能有自身可枚舉屬性。
console.log(obj);?//?{?"0":?"a",?"1":?"b",?"2":?"c"?}
數(shù)組的處理
Object.assign可以用來(lái)處理數(shù)組,但是會(huì)把數(shù)組視為對(duì)象。
Object.assign([1,?2,?3],?[4,?5])
//?[4,?5,?3]
Object.assign只能進(jìn)行值的復(fù)制,如果要復(fù)制的值是一個(gè)取值函數(shù),那么將求值后再?gòu)?fù)制。
const?source?=?{
??get?foo()?{?return?1?}
};
const?target?=?{};
Object.assign(target,?source)
//?{?foo:?1?}
為對(duì)象添加屬性
class?Point?{
??constructor(x,?y)?{
????Object.assign(this,?{x,?y});
??}
}
通過(guò)Object.assign方法,將x屬性和y屬性添加到Point類的對(duì)象實(shí)例。
克隆對(duì)象
function?clone(origin)?{
??return?Object.assign({},?origin);
}
將原始對(duì)象拷貝到一個(gè)空對(duì)象,就得到了原始對(duì)象的克隆。
合并多個(gè)對(duì)象
將多個(gè)對(duì)象合并到某個(gè)對(duì)象。
const?merge?=?(target,?...sources)?=>?Object.assign(target,?...sources);
如果希望合并后返回一個(gè)新對(duì)象,可以改寫上面函數(shù),對(duì)一個(gè)空對(duì)象合并。
const?merge?=?(...sources)?=>?Object.assign({},?...sources);
Object.create()
Object.create() 方法創(chuàng)建一個(gè)新對(duì)象,使用現(xiàn)有的對(duì)象來(lái)提供新創(chuàng)建的對(duì)象的__proto__。
Object.freeze()
Object.freeze() ?方法可以凍結(jié)一個(gè)對(duì)象。一個(gè)被凍結(jié)的對(duì)象再也不能被修改;凍結(jié)了一個(gè)對(duì)象則不能向這個(gè)對(duì)象添加新的屬性,不能刪除已有屬性,不能修改該對(duì)象已有屬性的可枚舉性、可配置性、可寫性,以及不能修改已有屬性的值。此外,凍結(jié)一個(gè)對(duì)象后該對(duì)象的原型也不能被修改。freeze()?返回和傳入的參數(shù)相同的對(duì)象。
Object.keys()
Object.keys()?方法會(huì)返回一個(gè)由一個(gè)給定對(duì)象的自身可枚舉屬性組成的數(shù)組,數(shù)組中屬性名的排列順序和正常循環(huán)遍歷該對(duì)象時(shí)返回的順序一致 。
//?simple?array
var?arr?=?['a',?'b',?'c'];
console.log(Object.keys(arr));?//?console:?['0',?'1',?'2']
//?array?like?object
var?obj?=?{?0:?'a',?1:?'b',?2:?'c'?};
console.log(Object.keys(obj));?//?console:?['0',?'1',?'2']
//?array?like?object?with?random?key?ordering
var?anObj?=?{?100:?'a',?2:?'b',?7:?'c'?};
console.log(Object.keys(anObj));?//?console:?['2',?'7',?'100']
//?getFoo?is?a?property?which?isn't?enumerable
var?myObj?=?Object.create({},?{
??getFoo:?{
????value:?function?()?{?return?this.foo;?}
??}
});
myObj.foo?=?1;
console.log(Object.keys(myObj));?//?console:?['foo']
方法的裝飾
裝飾器不僅可以裝飾類,還可以裝飾類的屬性。
function?readonly(target,?name,?descriptor){
??//?descriptor對(duì)象原來(lái)的值如下
??//?{
??//???value:?specifiedFunction,
??//???enumerable:?false,
??//???configurable:?true,
??//???writable:?true
??//?};
??descriptor.writable?=?false;
??return?descriptor;
}
readonly(Person.prototype,?'name',?descriptor);
//?類似于
Object.defineProperty(Person.prototype,?'name',?descriptor);
修改屬性描述對(duì)象的enumerable屬性,使得該屬性不可遍歷。
裝飾器有注釋的作用。
組件寫法:
@Component({
??tag:?'my-component',
??styleUrl:?'my-component.scss'
})
export?class?MyComponent?{
??@Prop()?first:?string;
??@Prop()?last:?string;
??@State()?isVisible:?boolean?=?true;
??render()?{
????return?(
??????Hello,?my?name?is?{this.first}?{this.last}
????);
??}
}
class?Example?{
????@dec(1)
????@dec(2)
????method(){}
}
外層裝飾器@dec(1)先進(jìn)入,但是內(nèi)層裝飾器@dec(2)先執(zhí)行。
裝飾器只能用于類和類的方法,不能用于函數(shù),因?yàn)榇嬖诤瘮?shù)提升。
UEditor 是由百度「FEX前端研發(fā)團(tuán)隊(duì)」開發(fā)的所見即所得富文本web編輯器
"en-US">
????"UTF-8">
????ueditor?demo
????
????
????
????
????
????
????
????
傳入自定義的參數(shù)
編輯器有很多可自定義的參數(shù)項(xiàng),在實(shí)例化的時(shí)候可以傳入給編輯器:
var?ue?=?UE.getEditor('container',?{
????autoHeight:?false
});
配置項(xiàng)也可以通過(guò) ueditor.config.js 文件修改
設(shè)置和讀取編輯器的內(nèi)容
通 getContent 和 setContent 方法可以設(shè)置和讀取編輯器的內(nèi)容
var?ue?=?UE.getContent();
//對(duì)編輯器的操作最好在編輯器ready之后再做
ue.ready(function()?{
????//設(shè)置編輯器的內(nèi)容
????ue.setContent('hello');
????//獲取html內(nèi)容,返回:?hello
????var?html?=?ue.getContent();
????//獲取純文本內(nèi)容,返回:?hello
????var?txt?=?ue.getContentTxt();
});
打開控制臺(tái)(注意:windows系統(tǒng)下請(qǐng)使用管理員權(quán)限打開),輸入:
npm?install?-g?grunt-cli
然后輸入以下命令。
npm?install?grunt?--save-dev
完整的按鈕列表
toolbars:?[
????[
????????'anchor',?//錨點(diǎn)
????????'undo',?//撤銷
????????'redo',?//重做
????????'bold',?//加粗
????????'indent',?//首行縮進(jìn)
????????'snapscreen',?//截圖
????????'italic',?//斜體
????????'underline',?//下劃線
????????'strikethrough',?//刪除線
????????'subscript',?//下標(biāo)
????????'fontborder',?//字符邊框
????????'superscript',?//上標(biāo)
????????'formatmatch',?//格式刷
????????'source',?//源代碼
????????'blockquote',?//引用
????????'pasteplain',?//純文本粘貼模式
????????'selectall',?//全選
????????'print',?//打印
????????'preview',?//預(yù)覽
????????'horizontal',?//分隔線
????????'removeformat',?//清除格式
????????'time',?//時(shí)間
????????'date',?//日期
????????'unlink',?//取消鏈接
????????'insertrow',?//前插入行
????????'insertcol',?//前插入列
????????'mergeright',?//右合并單元格
????????'mergedown',?//下合并單元格
????????'deleterow',?//刪除行
????????'deletecol',?//刪除列
????????'splittorows',?//拆分成行
????????'splittocols',?//拆分成列
????????'splittocells',?//完全拆分單元格
????????'deletecaption',?//刪除表格標(biāo)題
????????'inserttitle',?//插入標(biāo)題
????????'mergecells',?//合并多個(gè)單元格
????????'deletetable',?//刪除表格
????????'cleardoc',?//清空文檔
????????'insertparagraphbeforetable',?//"表格前插入行"
????????'insertcode',?//代碼語(yǔ)言
????????'fontfamily',?//字體
????????'fontsize',?//字號(hào)
????????'paragraph',?//段落格式
????????'simpleupload',?//單圖上傳
????????'insertimage',?//多圖上傳
????????'edittable',?//表格屬性
????????'edittd',?//單元格屬性
????????'link',?//超鏈接
????????'emotion',?//表情
????????'spechars',?//特殊字符
????????'searchreplace',?//查詢替換
????????'map',?//Baidu地圖
????????'gmap',?//Google地圖
????????'insertvideo',?//視頻
????????'help',?//幫助
????????'justifyleft',?//居左對(duì)齊
????????'justifyright',?//居右對(duì)齊
????????'justifycenter',?//居中對(duì)齊
????????'justifyjustify',?//兩端對(duì)齊
????????'forecolor',?//字體顏色
????????'backcolor',?//背景色
????????'insertorderedlist',?//有序列表
????????'insertunorderedlist',?//無(wú)序列表
????????'fullscreen',?//全屏
????????'directionalityltr',?//從左向右輸入
????????'directionalityrtl',?//從右向左輸入
????????'rowspacingtop',?//段前距
????????'rowspacingbottom',?//段后距
????????'pagebreak',?//分頁(yè)
????????'insertframe',?//插入Iframe
????????'imagenone',?//默認(rèn)
????????'imageleft',?//左浮動(dòng)
????????'imageright',?//右浮動(dòng)
????????'attachment',?//附件
????????'imagecenter',?//居中
????????'wordimage',?//圖片轉(zhuǎn)存
????????'lineheight',?//行間距
????????'edittip?',?//編輯提示
????????'customstyle',?//自定義標(biāo)題
????????'autotypeset',?//自動(dòng)排版
????????'webapp',?//百度應(yīng)用
????????'touppercase',?//字母大寫
????????'tolowercase',?//字母小寫
????????'background',?//背景
????????'template',?//模板
????????'scrawl',?//涂鴉
????????'music',?//音樂(lè)
????????'inserttable',?//插入表格
????????'drafts',?//?從草稿箱加載
????????'charts',?//?圖表
????]
]
傳入配置參數(shù)
var?ue?=?UE.getEditor('container',?{
????toolbars:?[
????????['fullscreen',?'source',?'undo',?'redo',?'bold']
????],
????autoHeightEnabled:?true,
????autoFloatEnabled:?true
});
讀取配置項(xiàng)
讀取配置項(xiàng)可以通過(guò)getOpt方法讀取
var?lang?=?ue.getOpt('lang');?//默認(rèn)返回:zh-cn
前端配置項(xiàng)說(shuō)明
UEDITOR_HOME_URL?{Path String} [默認(rèn)值:根據(jù)config文件路徑自動(dòng)獲取] // 為編輯器實(shí)例添加一個(gè)路徑,這個(gè)不能被注釋
serverUrl?{Path String} [默認(rèn)值:URL + "php/controller.php"] // 服務(wù)器統(tǒng)一請(qǐng)求接口路徑
toolbars?{2d Array} //工具欄上的所有的功能按鈕和下拉框,可以在new編輯器的實(shí)例時(shí)選擇自己需要的從新定義
labelMap?{Object} [默認(rèn):從lang包的labelMap項(xiàng)獲取] //參數(shù)格式是鍵值對(duì),鍵名對(duì)應(yīng)toolbar參數(shù)的項(xiàng):{"bold": "加粗"} ],當(dāng)鼠標(biāo)放在工具欄上時(shí)顯示的tooltip提示,留空支持自動(dòng)多語(yǔ)言配置,否則以配置值為準(zhǔn)
lang?{String} [默認(rèn)值:"zh-cn"] //lang值也可以通過(guò)自動(dòng)獲取 (navigator.language||navigator.browserLanguage ||navigator.userLanguage).toLowerCase(),語(yǔ)言配置項(xiàng),默認(rèn)是zh-cn。有需要的話也可以使用如下這樣的方式來(lái)自動(dòng)多語(yǔ)言切換,當(dāng)然,前提條件是lang文件夾下存在對(duì)應(yīng)的語(yǔ)言文件:
langPath?{Path String} [默認(rèn)值:URL +"lang/"] //語(yǔ)言包文件存放目錄
theme?{String} [默認(rèn)值:'default'] //主題配置項(xiàng),默認(rèn)是default。有需要的話也可以使用如下這樣的方式來(lái)自動(dòng)多主題切換,當(dāng)然,前提條件是themes文件夾下存在對(duì)應(yīng)的主題文件:
themePath?{Path String} [默認(rèn)值:URL +"themes/"] //現(xiàn)有如下皮膚:default
zIndex?{Number} [默認(rèn)值:900] //編輯器在頁(yè)面上的z-index層級(jí)的基數(shù),默認(rèn)是900
charset?{String} [默認(rèn)值:"utf-8"] //針對(duì)getAllHtml方法,會(huì)在對(duì)應(yīng)的head標(biāo)簽中增加該編碼設(shè)置。
customDomain?{Boolean} [默認(rèn)值:false] //若實(shí)例化編輯器的頁(yè)面手動(dòng)修改的domain,此處需要設(shè)置為true
isShow?{Boolean} [默認(rèn)值:true] //默認(rèn)顯示編輯器
textarea?{String} [默認(rèn)值:'editorValue'] // 提交表單時(shí),服務(wù)器獲取編輯器提交內(nèi)容的所用的參數(shù),多實(shí)例時(shí)可以給容器name屬性,會(huì)將name給定的值最為每個(gè)實(shí)例的鍵值,不用每次實(shí)例化的時(shí)候都設(shè)置這個(gè)值
initialContent?{String} [默認(rèn)值:'歡迎使用ueditor!'] //初始化編輯器的內(nèi)容,也可以通過(guò)textarea/script給值,看官網(wǎng)例子
autoClearinitialContent?{Boolean} [默認(rèn)值:true] //是否自動(dòng)清除編輯器初始內(nèi)容,注意:如果focus屬性設(shè)置為true,這個(gè)也為真,那么編輯器一上來(lái)就會(huì)觸發(fā)導(dǎo)致初始化的內(nèi)容看不到了
focus?{Boolean} [默認(rèn)值:false] //初始化時(shí),是否讓編輯器獲得焦點(diǎn)true或false
initialStyle?{String} [默認(rèn)值:'p{line-height:1em}']//編輯器層級(jí)的基數(shù),可以用來(lái)改變字體等 //如果自定義,最好給p標(biāo)簽如下的行高,要不輸入中文時(shí),會(huì)有跳動(dòng)感
iframeCssUrl?{Path String} [默認(rèn)值:URL + '/themes/iframe.css'] //給編輯器內(nèi)部引入一個(gè)css文件
indentValue?{String} [默認(rèn)值:'2em'] //首行縮進(jìn)距離,默認(rèn)是2em
initialFrameWidth?{Number} [默認(rèn)值:1000] //初始化編輯器寬度,默認(rèn)1000
initialFrameHeight?{Number} [默認(rèn)值:320] //初始化編輯器高度,默認(rèn)320
readonly?{Boolean} [默認(rèn)值:false] //編輯器初始化結(jié)束后,編輯區(qū)域是否是只讀的,默認(rèn)是false
autoClearEmptyNode?{Boolean} [默認(rèn)值:true] //getContent時(shí),是否刪除空的inlineElement節(jié)點(diǎn)(包括嵌套的情況)
enableAutoSave?{Boolean} [默認(rèn)值:true] //啟用自動(dòng)保存
saveInterval?{Number} [默認(rèn)值:500] //自動(dòng)保存間隔時(shí)間,單位ms
imageScaleEnabled?{Boolean} [默認(rèn)值:true] //啟用圖片拉伸縮放
fullscreen?{Boolean} [默認(rèn)值:false] //是否開啟初始化時(shí)即全屏,默認(rèn)關(guān)閉
imagePopup?{Boolean} [默認(rèn)值:true] //圖片操作的浮層開關(guān),默認(rèn)打開
autoSyncData?{Boolean} [默認(rèn)值:true] //自動(dòng)同步編輯器要提交的數(shù)據(jù)
emotionLocalization?{Boolean} [默認(rèn)值:false] //是否開啟表情本地化,默認(rèn)關(guān)閉。若要開啟請(qǐng)確保emotion文件夾下包含官網(wǎng)提供的images表情文件夾
retainOnlyLabelPasted?{Boolean} [默認(rèn)值:false] //粘貼只保留標(biāo)簽,去除標(biāo)簽所有屬性
pasteplain?{Boolean} [默認(rèn)值:false] //是否默認(rèn)為純文本粘貼。false為不使用純文本粘貼,true為使用純文本粘貼
filterTxtRules?{Object} //純文本粘貼模式下的過(guò)濾規(guī)則
allHtmlEnabled?[默認(rèn)值:false] //提交到后臺(tái)的數(shù)據(jù)是否包含整個(gè)html字符串
insertorderedlist?//有序列表的下拉配置,值留空時(shí)支持多語(yǔ)言自動(dòng)識(shí)別,若配置值,則以此值為準(zhǔn)insertunorderedlist?//無(wú)序列表的下拉配置,值留空時(shí)支持多語(yǔ)言自動(dòng)識(shí)別,若配置值,則以此值為準(zhǔn)
listDefaultPaddingLeft?[默認(rèn)值:'30'//默認(rèn)的左邊縮進(jìn)的基數(shù)倍
listiconpath?[默認(rèn)值:'http://bs.baidu.com/listicon/']//自定義標(biāo)號(hào)的路徑
maxListLevel?[默認(rèn)值:3] //限制可以tab的級(jí)數(shù), 設(shè)置-1為不限制
autoTransWordToList?[默認(rèn)值:false] //禁止word中粘貼進(jìn)來(lái)的列表自動(dòng)變成列表標(biāo)簽
fontfamily?//字體設(shè)置 label留空支持多語(yǔ)言自動(dòng)切換,若配置,則以配置值為準(zhǔn)
fontsize?{Array} //字號(hào)
//默認(rèn)值:
[10,?11,?12,?14,?16,?18,?20,?24,?36]paragraph?{Object} //段落格式 值留空時(shí)支持多語(yǔ)言自動(dòng)識(shí)別,若配置,則以配置值為準(zhǔn)
//默認(rèn)值:
{
????'p':?'',
????'h1':?'',
????'h2':?'',
????'h3':?'',
????'h4':?'',
????'h5':?'',
????'h6':?''
}rowspacingtop?{Array} //段間距 值和顯示的名字相同
//默認(rèn)值:
['5',?'10',?'15',?'20',?'25']rowspacingbottom?//段間距 值和顯示的名字相同
//默認(rèn)值:
['5',?'10',?'15',?'20',?'25']lineheight?[默認(rèn)值:['1', '1.5','1.75','2', '3', '4', '5'] ] //行內(nèi)間距 值和顯示的名字相同
customstyle?[Array] //自定義樣式,不支持國(guó)際化,此處配置值即可最后顯示值block的元素是依據(jù)設(shè)置段落的邏輯設(shè)置的,inline的元素依據(jù)BIU的邏輯設(shè)置,盡量使用一些常用的標(biāo)簽
//默認(rèn)值:
[{
????????tag:?'h1',?//tag?使用的標(biāo)簽名字
????????name:?'tc',?//
????????label:?'',?//label?顯示的名字也是用來(lái)標(biāo)識(shí)不同類型的標(biāo)識(shí)符,注意這個(gè)值每個(gè)要不同
????????style:?'border-bottom:#ccc?2px?solid;padding:0?4px?0?0;text-align:center;margin:0?0?20px?0;'?//style?添加的樣式
????},?//每一個(gè)對(duì)象就是一個(gè)自定義的樣式enableContextMenu?{Boolean} [默認(rèn)值:true] //打開右鍵菜單功能
contextMenu?{Object} //右鍵菜單的內(nèi)容
shortcutMenu?{Array} //快捷菜單
//默認(rèn)值
["fontfamily",?"fontsize",?"bold",?"italic",?"underline",?"forecolor",?"backcolor",?"insertorderedlist",?"insertunorderedlist"]elementPathEnabled?{Boolean} [默認(rèn)值:true] //是否啟用元素路徑,默認(rèn)是顯示
wordCount?{Boolean} [默認(rèn)值:true] //是否開啟字?jǐn)?shù)統(tǒng)計(jì)
maximumWords?{Number} [默認(rèn)值:10000] //允許的最大字符數(shù)
wordCountMsg?{String} [默認(rèn)值:] //當(dāng)前已輸入 {#count} 個(gè)字符,您還可以輸入{#leave} 個(gè)字符,字?jǐn)?shù)統(tǒng)計(jì)提示,{#count}代表當(dāng)前字?jǐn)?shù),{#leave}代表還可以輸入多少字符數(shù),留空支持多語(yǔ)言自動(dòng)切換,否則按此配置顯示
\默認(rèn)值:
'當(dāng)前已輸入{#count}個(gè)字符, 您還可以輸入{#leave}個(gè)字符。?'wordOverFlowMsg?{String} [默認(rèn)值:] //超出字?jǐn)?shù)限制提示 留空支持多語(yǔ)言自動(dòng)切換,否則按此配置顯示
\默認(rèn)值:
'你輸入的字符個(gè)數(shù)已經(jīng)超出最大允許值,服務(wù)器可能會(huì)拒絕保存!'tabSize?{Number} [默認(rèn)值:4] //點(diǎn)擊tab鍵時(shí)移動(dòng)的距離,tabSize倍數(shù),tabNode什么字符做為單位
tabNode?{String} [默認(rèn)值:'?']
removeFormatTags?//清除格式時(shí)可以刪除的標(biāo)簽和屬性
//默認(rèn)值:
'b,big,code,del,dfn,em,font,i,ins,kbd,q,samp,small,span,strike,strong,sub,sup,tt,u,var'removeFormatAttributes?[默認(rèn)值:'class,style,lang,width,height,align,hspace,valign'
maxUndoCount?{Number} [默認(rèn)值:20] //undo操作,可以最多回退的次數(shù),默認(rèn)20
maxInputCount?{Number} [默認(rèn)值:1] //undo操作,當(dāng)輸入的字符數(shù)超過(guò)該值時(shí),保存一次現(xiàn)場(chǎng)
autoHeightEnabled?{Boolean} [默認(rèn)值:true] //是否自動(dòng)長(zhǎng)高,默認(rèn)true
scaleEnabled?{Boolean} [默認(rèn)值:false] //是否可以拉伸長(zhǎng)高,默認(rèn)true(當(dāng)開啟時(shí),自動(dòng)長(zhǎng)高失效)
minFrameWidth?{Number} [默認(rèn)值:800] //編輯器拖動(dòng)時(shí)最小寬度,默認(rèn)800
minFrameHeight?{Number} [默認(rèn)值:220] //編輯器拖動(dòng)時(shí)最小高度,默認(rèn)220
autoFloatEnabled?[默認(rèn)值:true] //是否保持toolbar的位置不動(dòng),默認(rèn)true
topOffset?[默認(rèn)值:30] //浮動(dòng)時(shí)工具欄距離瀏覽器頂部的高度,用于某些具有固定頭部的頁(yè)面
toolbarTopOffset?[默認(rèn)值:400] //編輯器底部距離工具欄高度(如果參數(shù)大于等于編輯器高度,則設(shè)置無(wú)效)
pageBreakTag?[默認(rèn)值:'ueditorpagebreaktag '] //分頁(yè)標(biāo)識(shí)符,默認(rèn)是ueditorpagebreaktag
autotypeset?{Object} //自動(dòng)排版參數(shù) 默認(rèn)值:
{
????mergeEmptyline:?true,?//合并空行
????removeClass:?true,?//去掉冗余的class
????removeEmptyline:?false,?//去掉空行
????textAlign:?"left",?//段落的排版方式,可以是?left,right,center,justify?去掉這個(gè)屬性表示不執(zhí)行排版
????imageBlockLine:?'center',?//圖片的浮動(dòng)方式,獨(dú)占一行劇中,左右浮動(dòng),默認(rèn):?center,left,right,none?去掉這個(gè)屬性表示不執(zhí)行排版
????pasteFilter:?false,?//根據(jù)規(guī)則過(guò)濾沒事粘貼進(jìn)來(lái)的內(nèi)容
????clearFontSize:?false,?//去掉所有的內(nèi)嵌字號(hào),使用編輯器默認(rèn)的字號(hào)
????clearFontFamily:?false,?//去掉所有的內(nèi)嵌字體,使用編輯器默認(rèn)的字體
????removeEmptyNode:?false,?//?去掉空節(jié)點(diǎn)
????//可以去掉的標(biāo)簽
????removeTagNames:?{標(biāo)簽名字:?1
????},
????indent:?false,?//?行首縮進(jìn)
????indentValue:?'2em',?//行首縮進(jìn)的大小
????bdc2sb:?false,
????tobdc:?false
}tableDragable?{Boolean} [默認(rèn)值:true] //表格是否可以拖拽
disabledTableInTable?{Boolean} [默認(rèn)值:true] //禁止表格嵌套
sourceEditor?{String} [默認(rèn)值:"codemirror"] //源碼的查看方式,codemirror是代碼高亮,textarea是文本框,默認(rèn)是codemirror,注意默認(rèn)codemirror只能在ie8+和非ie中使用
codeMirrorJsUrl?{Path String} [默認(rèn)值:URL + "third-party/codemirror/codemirror.js"] //如果sourceEditor是codemirror需要配置這項(xiàng),codeMirror js加載的路徑
codeMirrorCssUrl?{Path String} [默認(rèn)值:URL + "third-party/codemirror/codemirror.css"] //如果sourceEditor是codemirror需要配置這項(xiàng),codeMirror css加載的路徑
sourceEditorFirst?{String} [默認(rèn)值:false] //編輯器初始化完成后是否進(jìn)入源碼模式,默認(rèn)為否。
iframeUrlMap?{Object} //dialog內(nèi)容的路徑 ~會(huì)被替換成URL,垓?qū)傩砸坏┐蜷_,將覆蓋所有的dialog的默認(rèn)路徑
//默認(rèn)值:
{
????'anchor':?'~/dialogs/anchor/anchor.html',
}webAppKey?{String} //webAppKey 百度應(yīng)用的APIkey,每個(gè)站長(zhǎng)必須首先去百度官網(wǎng)注冊(cè)一個(gè)key后方能正常使用app功能,注冊(cè)介紹,http://app.baidu.com/static/cms/getapikey.html
allowDivTransToP?{Boolean} 默認(rèn)會(huì)將外部進(jìn)入的html數(shù)據(jù)中的Div標(biāo)簽轉(zhuǎn)換成P標(biāo)簽,外部進(jìn)入的數(shù)據(jù)包括粘貼和調(diào)用setContent接口進(jìn)入編輯器的數(shù)據(jù)。如果設(shè)置成false將不在做這個(gè)轉(zhuǎn)換。
dialogs: 彈出對(duì)話框?qū)?yīng)的資源和JS文件
lang: 編輯器國(guó)際化顯示的文件
php或jsp或asp或net: 涉及到服務(wù)器端操作的后臺(tái)文件
themes: 樣式圖片和樣式文件
third-party: 第三方插件(包括代碼高亮,源碼編輯等組件)
ueditor.all.js: 開發(fā)版代碼合并的結(jié)果,目錄下所有文件的打包文件
ueditor.all.min.js: ueditor.all.js文件的壓縮版,建議在正式部署時(shí)采用
ueditor.config.js: 編輯器的配置文件,建議和編輯器實(shí)例化頁(yè)面置于同一目錄
ueditor.parse.js: 編輯的內(nèi)容顯示頁(yè)面引用,會(huì)自動(dòng)加載表格、列表、代碼高亮等樣式
_doc: 部分markdown格式的文檔
_example: ueditor的使用例子
_parse: ueditor.parse.js的源碼
_src: ueditor.all.js的源碼
_src\core: ueditor核心代碼 _src\plugins: 插件文件 _src\ui: ui相關(guān)文件 _src\adapter: 橋接層文件,對(duì)接ueditor核心和ui代碼
擴(kuò)展你的功能。
UE.registerUI('uiname',?function(editor,?uiname)?{
????//do?something
},?[index,?[editorId]]);
考慮到大家的功能基本上都會(huì)擴(kuò)展一個(gè)UI和這個(gè)UI做的事情,所以UEditor提供了registerUI這個(gè)接口,可以讓開發(fā)者動(dòng)態(tài)的注入擴(kuò)展的內(nèi)容。
uiname,是你為新添加的UI起的名字,這里可以是1個(gè)或者多個(gè),“uiname”后者是“uiname1 uiname2 uiname3” function,是實(shí)際你要做的事情,這里提供兩個(gè)參數(shù),editor是編輯器實(shí)例,如果你有多個(gè)編輯器實(shí)例,那每個(gè)編輯器實(shí)例化后,都會(huì)調(diào)用這個(gè)function,并且把editor傳進(jìn)來(lái),uiname,你為ui起的名字,如果前邊你添加的是多個(gè)的化,這里function會(huì)被調(diào)用多次,并且將每一個(gè)ui名字傳遞進(jìn)來(lái).如果函數(shù)返回了一個(gè)UI 實(shí)例,那這個(gè)UI實(shí)例就會(huì)被默認(rèn)加到工具欄上。當(dāng)然也可以不返回任何UI。比如希望監(jiān)控selectionchange事件,在某些場(chǎng)景下彈出浮層,這時(shí)就不需要返回任何UI. index,是你想放到toolbar的那個(gè)位置,默認(rèn)是放到最后 editorId,當(dāng)你的頁(yè)面上有多個(gè)編輯器實(shí)例時(shí),你想將這個(gè)ui擴(kuò)展到那個(gè)編輯器實(shí)例上,這里的editorId是給你編輯器初始化時(shí),傳入的id,默認(rèn)是每個(gè)實(shí)例都會(huì)加入你的擴(kuò)展
追加編輯器內(nèi)容:
ue.ready(function()?{
????ue.setContent('new?text
',?true);
});
ue.ready(function()?{
????var?html?=?ue.getContent();
});
ue.getContentTxt();
ue.getPlainTxt();
ue.selection.getText();
ue.execCommand('bold');?//加粗
ue.execCommand('italic');?//加斜線
ue.execCommand('subscript');?//設(shè)置上標(biāo)
ue.execCommand('supscript');?//設(shè)置下標(biāo)
ue.execCommand('forecolor',?'#FF0000');?//設(shè)置字體顏色
ue.execCommand('backcolor',?'#0000FF');?//設(shè)置字體背景顏色
在當(dāng)前光標(biāo)位置插入html內(nèi)容
ue.execCommand('inserthtml',?'hello!');
http://fex.baidu.com/ueditor/#start-config
vuex-module-decorators
安裝
npm?install?-D?vuex-module-decorators
這個(gè)包以es2015格式生成代碼。如果你的 Vue 項(xiàng)目面向 ES6 或 ES2015,那么你不需要做任何事情。但是如果您的項(xiàng)目使用es5目標(biāo)(以支持舊瀏覽器),那么您需要告訴 Vue CLI / Babel 轉(zhuǎn)譯這個(gè)包。
//?in?your?vue.config.js
module.exports?=?{
??/*?...?other?settings?*/
??transpileDependencies:?['vuex-module-decorators']
}
vuex 模塊過(guò)去寫法:
const?moduleA?=?{
??state:?{?...?},
??mutations:?{?...?},
??actions:?{?...?},
??getters:?{?...?}
}
const?moduleB?=?{
??state:?{?...?},
??mutations:?{?...?},
??actions:?{?...?}
}
const?store?=?new?Vuex.Store({
??modules:?{
????a:?moduleA,
????b:?moduleB
??}
})
import?{?Module,?VuexModule,?Mutation,?Action?}?from?'vuex-module-decorators'
@Module
export?default?class?Counter2?extends?VuexModule?{
??count?=?0
??@Mutation
??increment(delta:?number)?{
????this.count?+=?delta
??}
??@Mutation
??decrement(delta:?number)?{
????this.count?-=?delta
??}
??//?action?'incr'?commits?mutation?'increment'?when?done?with?return?value?as?payload
??@Action({?commit:?'increment'?})
??incr()?{
????return?5
??}
??//?action?'decr'?commits?mutation?'decrement'?when?done?with?return?value?as?payload
??@Action({?commit:?'decrement'?})
??decr()?{
????return?5
??}
}
import?{?Module,?VuexModule,?MutationAction?}?from?'vuex-module-decorators'
import?{?ConferencesEntity,?EventsEntity?}?from?'@/models/definitions'
@Module
export?default?class?HGAPIModule?extends?VuexModule?{
??conferences:?Array?=?[]
??events:?Array?=?[]
??//?'events'?and?'conferences'?are?replaced?by?returned?object
??//?whose?shape?must?be?`{events:?[...],?conferences:?[...]?}`
??@MutationAction({?mutate:?['events',?'conferences']?})
??async?fetchAll()?{
????const?response:?Response?=?await?getJSON('https://xxx.json')
????return?response
??}
}
@Module
class?MyModule?extends?VuexModule?{
??wheels?=?2
??@Mutation
??incrWheels(extra)?{
????this.wheels?+=?extra
??}
??get?axles()?{
????return?this.wheels?/?2
??}
}
const?module?=?{
??state:?{?wheels:?2?},
??mutations:?{
????incrWheels(state,?extra)?{
??????state.wheels?+=?extra
????}
??},
??getters:?{
????axles:?(state)?=>?state.wheels?/?2
??}
}
import?Vuex,?{?Module?}?from?'vuex'
Vue.use(Vuex)
@Module({?stateFactory:?true?})
class?MyModule?extends?VuexModule?{
??wheels?=?2
??@Mutation
??incrWheels(extra)?{
????this.wheels?+=?extra
??}
??get?axles()?{
????return?this.wheels?/?2
??}
}
const?module?=?{
??state()?{
????return?{?wheels:?2?}
??},
??mutations:?{
????incrWheels(state,?extra)?{
??????state.wheels?+=?extra
????}
??},
??getters:?{
????axles:?(state)?=>?state.wheels?/?2
??}
}
動(dòng)態(tài)模塊
Vuex 允許我們?cè)跇?gòu)建 store 后在運(yùn)行時(shí)將模塊注冊(cè)到 store。
來(lái)創(chuàng)建動(dòng)態(tài)模塊
interface?StoreType?{
??mm:?MyModule
}
//?Declare?empty?store?first
const?store?=?new?Vuex.Store({})
//?Create?module?later?in?your?code?(it?will?register?itself?automatically)
//?In?the?decorator?we?pass?the?store?object?into?which?module?is?injected
//?NOTE:?When?you?set?dynamic?true,?make?sure?you?give?module?a?name
@Module({?dynamic:?true,?store:?store,?name:?'mm'?})
class?MyModule?extends?VuexModule?{
??count?=?0
??@Mutation
??incrCount(delta)?{
????this.count?+=?delta
??}
}
如果您想保留狀態(tài)
...
--?@Module({?dynamic:?true,?store:?store,?name:?'mm'?})
++?@Module({?dynamic:?true,?store:?store,?name:?'mm',?preserveState:?true?})
class?MyModule?extends?VuexModule?{
...
或者當(dāng)它沒有初始狀態(tài)并且您從 localStorage 加載狀態(tài)時(shí)
...
--?@Module({?dynamic:?true,?store:?store,?name:?'mm'?})
++?@Module({?dynamic:?true,?store:?store,?name:?'mm',?preserveState:?localStorage.getItem('vuex')?!==?null?})
class?MyModule?extends?VuexModule?{
...
Vue Property Decorator
安裝
npm?i?-S?vue-property-decorator
用法
有幾個(gè)裝飾器和 1 個(gè)函數(shù) (Mixin):
@Prop
@PropSync
@Model
@ModelSync
@Watch
@Provide
@Inject
@ProvideReactive
@InjectReactive
@Emit
@Ref
@VModel
@Component(由?vue-class-component?提供)
Mixins(mixins?由?vue-class-component提供的名為?helper?函數(shù))
@Prop(options: (PropOptions | Constructor[] | Constructor) = {})?裝飾師
import?{?Vue,?Component,?Prop?}?from?'vue-property-decorator'
@Component
export?default?class?YourComponent?extends?Vue?{
??@Prop(Number)?readonly?propA:?number?|?undefined
??@Prop({?default:?'default?value'?})?readonly?propB!:?string
??@Prop([String,?Boolean])?readonly?propC:?string?|?boolean?|?undefined
}
export?default?{
??props:?{
????propA:?{
??????type:?Number,
????},
????propB:?{
??????default:?'default?value',
????},
????propC:?{
??????type:?[String,?Boolean],
????},
??},
}
import?'reflect-metadata'
import?{?Vue,?Component,?Prop?}?from?'vue-property-decorator'
@Component
export?default?class?MyComponent?extends?Vue?{
??@Prop()?age!:?number
}
@PropSync(propName: string, options: (PropOptions | Constructor[] | Constructor) = {})?裝飾師
import?{?Vue,?Component,?PropSync?}?from?'vue-property-decorator'
@Component
export?default?class?YourComponent?extends?Vue?{
??@PropSync('name',?{?type:?String?})?syncedName!:?string
}
export?default?{
??props:?{
????name:?{
??????type:?String,
????},
??},
??computed:?{
????syncedName:?{
??????get()?{
????????return?this.name
??????},
??????set(value)?{
????????this.$emit('update:name',?value)
??????},
????},
??},
}
@Model(event?: string, options: (PropOptions | Constructor[] | Constructor) = {})?裝飾師
import?{?Vue,?Component,?Model?}?from?'vue-property-decorator'
@Component
export?default?class?YourComponent?extends?Vue?{
??@Model('change',?{?type:?Boolean?})?readonly?checked!:?boolean
}
export?default?{
??model:?{
????prop:?'checked',
????event:?'change',
??},
??props:?{
????checked:?{
??????type:?Boolean,
????},
??},
}
@ModelSync(propName: string, event?: string, options: (PropOptions | Constructor[] | Constructor) = {})?裝飾師
import?{?Vue,?Component,?ModelSync?}?from?'vue-property-decorator'
@Component
export?default?class?YourComponent?extends?Vue?{
??@ModelSync('checked',?'change',?{?type:?Boolean?})
??readonly?checkedValue!:?boolean
}
export?default?{
??model:?{
????prop:?'checked',
????event:?'change',
??},
??props:?{
????checked:?{
??????type:?Boolean,
????},
??},
??computed:?{
????checkedValue:?{
??????get()?{
????????return?this.checked
??????},
??????set(value)?{
????????this.$emit('change',?value)
??????},
????},
??},
}
@Watch(path: string, options: WatchOptions = {})?裝飾師
import?{?Vue,?Component,?Watch?}?from?'vue-property-decorator'
@Component
export?default?class?YourComponent?extends?Vue?{
??@Watch('child')
??onChildChanged(val:?string,?oldVal:?string)?{}
??@Watch('person',?{?immediate:?true,?deep:?true?})
??onPersonChanged1(val:?Person,?oldVal:?Person)?{}
??@Watch('person')
??onPersonChanged2(val:?Person,?oldVal:?Person)?{}
}
export?default?{
??watch:?{
????child:?[
??????{
????????handler:?'onChildChanged',
????????immediate:?false,
????????deep:?false,
??????},
????],
????person:?[
??????{
????????handler:?'onPersonChanged1',
????????immediate:?true,
????????deep:?true,
??????},
??????{
????????handler:?'onPersonChanged2',
????????immediate:?false,
????????deep:?false,
??????},
????],
??},
??methods:?{
????onChildChanged(val,?oldVal)?{},
????onPersonChanged1(val,?oldVal)?{},
????onPersonChanged2(val,?oldVal)?{},
??},
}
@Provide(key?: string | symbol)/@Inject(options?: { from?: InjectKey, default?: any } | InjectKey)裝飾者
import?{?Component,?Inject,?Provide,?Vue?}?from?'vue-property-decorator'
const?symbol?=?Symbol('baz')
@Component
export?class?MyComponent?extends?Vue?{
??@Inject()?readonly?foo!:?string
??@Inject('bar')?readonly?bar!:?string
??@Inject({?from:?'optional',?default:?'default'?})?readonly?optional!:?string
??@Inject(symbol)?readonly?baz!:?string
??@Provide()?foo?=?'foo'
??@Provide('bar')?baz?=?'bar'
}
const?symbol?=?Symbol('baz')
export?const?MyComponent?=?Vue.extend({
??inject:?{
????foo:?'foo',
????bar:?'bar',
????optional:?{?from:?'optional',?default:?'default'?},
????baz:?symbol,
??},
??data()?{
????return?{
??????foo:?'foo',
??????baz:?'bar',
????}
??},
??provide()?{
????return?{
??????foo:?this.foo,
??????bar:?this.baz,
????}
??},
})
@ProvideReactive(key?: string | symbol)/@InjectReactive(options?: { from?: InjectKey, default?: any } | InjectKey)裝飾者
如果父組件修改了提供的值,則子組件可以捕獲此修改。
const?key?=?Symbol()
@Component
class?ParentComponent?extends?Vue?{
??@ProvideReactive()?one?=?'value'
??@ProvideReactive(key)?two?=?'value'
}
@Component
class?ChildComponent?extends?Vue?{
??@InjectReactive()?one!:?string
??@InjectReactive(key)?two!:?string
}
@Emit(event?: string)?裝飾師
import?{?Vue,?Component,?Emit?}?from?'vue-property-decorator'
@Component
export?default?class?YourComponent?extends?Vue?{
??count?=?0
??@Emit()
??addToCount(n:?number)?{
????this.count?+=?n
??}
??@Emit('reset')
??resetCount()?{
????this.count?=?0
??}
??@Emit()
??returnValue()?{
????return?10
??}
??@Emit()
??onInputChange(e)?{
????return?e.target.value
??}
??@Emit()
??promise()?{
????return?new?Promise((resolve)?=>?{
??????setTimeout(()?=>?{
????????resolve(20)
??????},?0)
????})
??}
}
export?default?{
??data()?{
????return?{
??????count:?0,
????}
??},
??methods:?{
????addToCount(n)?{
??????this.count?+=?n
??????this.$emit('add-to-count',?n)
????},
????resetCount()?{
??????this.count?=?0
??????this.$emit('reset')
????},
????returnValue()?{
??????this.$emit('return-value',?10)
????},
????onInputChange(e)?{
??????this.$emit('on-input-change',?e.target.value,?e)
????},
????promise()?{
??????const?promise?=?new?Promise((resolve)?=>?{
????????setTimeout(()?=>?{
??????????resolve(20)
????????},?0)
??????})
??????promise.then((value)?=>?{
????????this.$emit('promise',?value)
??????})
????},
??},
}
@Ref(refKey?: string)?裝飾師
import?{?Vue,?Component,?Ref?}?from?'vue-property-decorator'
import?AnotherComponent?from?'@/path/to/another-component.vue'
@Component
export?default?class?YourComponent?extends?Vue?{
??@Ref()?readonly?anotherComponent!:?AnotherComponent
??@Ref('aButton')?readonly?button!:?HTMLButtonElement
}
export?default?{
??computed()?{
????anotherComponent:?{
??????cache:?false,
??????get()?{
????????return?this.$refs.anotherComponent?as?AnotherComponent
??????}
????},
????button:?{
??????cache:?false,
??????get()?{
????????return?this.$refs.aButton?as?HTMLButtonElement
??????}
????}
??}
}
@VModel(propsArgs?: PropOptions)?裝飾師
import?{?Vue,?Component,?VModel?}?from?'vue-property-decorator'
@Component
export?default?class?YourComponent?extends?Vue?{
??@VModel({?type:?String?})?name!:?string
}
export?default?{
??props:?{
????value:?{
??????type:?String,
????},
??},
??computed:?{
????name:?{
??????get()?{
????????return?this.value
??????},
??????set(value)?{
????????this.$emit('input',?value)
??????},
????},
??},
}
??關(guān)注+點(diǎn)贊+收藏+評(píng)論+轉(zhuǎn)發(fā)??,原創(chuàng)不易,鼓勵(lì)筆者創(chuàng)作更好的文章
點(diǎn)贊、收藏和評(píng)論
我是Jeskson,感謝各位人才的:點(diǎn)贊、收藏和評(píng)論,我們下期見!(如本文內(nèi)容有地方講解有誤,歡迎指出?謝謝,一起學(xué)習(xí)了)
我們下期見!
github收錄,歡迎Star:https://1024bibi.com
