JS前端技術(shù)類文章
前沿
裝飾器
裝飾器是一種函數(shù),寫成@ + 函數(shù)名。它可以放在類和類方法的定義前面。
裝飾器的行為
@decorator
class?A?{}
//?等同于
class?A?{}
A?=?decorator(A)?||?A;
裝飾器函數(shù)的第一個參數(shù),就是所要裝飾的目標類。
注意,裝飾器對類的行為的改變,是代碼編譯時發(fā)生的,而不是在運行時。這意味著,裝飾器能在編譯階段運行代碼。也就是說,裝飾器本質(zhì)就是編譯時執(zhí)行的函數(shù)。
添加實例屬性
function?testable(target)?{
??target.prototype.isTestable?=?true;
}
@testable
class?MyTestableClass?{}
let?obj?=?new?MyTestableClass();
obj.isTestable?//?true
Object.assign()
Object.assign()?方法用于將所有可枚舉屬性的值從一個或多個源對象分配到目標對象。它將返回目標對象。
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)
如果目標對象中的屬性具有相同的鍵,則屬性將被源對象中的屬性覆蓋。后面的源對象的屬性將類似地覆蓋前面的源對象的屬性。
[復(fù)制一個對象]
const?obj?=?{?a:?1?};
const?copy?=?Object.assign({},?obj);
console.log(copy);?//?{?a:?1?}
[深拷貝問題]
針對深拷貝,需要使用其他辦法,因為?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();
[合并對象]
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 }, 注意目標對象自身也會改變。
[合并具有相同屬性的對象]
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)]
[繼承屬性和不可枚舉屬性是不能拷貝的]
[原始類型會被包裝為對象]
const?v1?=?"abc";
const?v2?=?true;
const?v3?=?10;
const?v4?=?Symbol("foo")
const?obj?=?Object.assign({},?v1,?null,?v2,?undefined,?v3,?v4);
//?原始類型會被包裝,null 和 undefined 會被忽略。
//?注意,只有字符串的包裝對象才可能有自身可枚舉屬性。
console.log(obj);?//?{?"0":?"a",?"1":?"b",?"2":?"c"?}
數(shù)組的處理
Object.assign可以用來處理數(shù)組,但是會把數(shù)組視為對象。
Object.assign([1,?2,?3],?[4,?5])
//?[4,?5,?3]
Object.assign只能進行值的復(fù)制,如果要復(fù)制的值是一個取值函數(shù),那么將求值后再復(fù)制。
const?source?=?{
??get?foo()?{?return?1?}
};
const?target?=?{};
Object.assign(target,?source)
//?{?foo:?1?}
為對象添加屬性
class?Point?{
??constructor(x,?y)?{
????Object.assign(this,?{x,?y});
??}
}
通過Object.assign方法,將x屬性和y屬性添加到Point類的對象實例。
克隆對象
function?clone(origin)?{
??return?Object.assign({},?origin);
}
將原始對象拷貝到一個空對象,就得到了原始對象的克隆。
合并多個對象
將多個對象合并到某個對象。
const?merge?=?(target,?...sources)?=>?Object.assign(target,?...sources);
如果希望合并后返回一個新對象,可以改寫上面函數(shù),對一個空對象合并。
const?merge?=?(...sources)?=>?Object.assign({},?...sources);
Object.create()
Object.create() 方法創(chuàng)建一個新對象,使用現(xiàn)有的對象來提供新創(chuàng)建的對象的__proto__。
Object.freeze()
Object.freeze() ?方法可以凍結(jié)一個對象。一個被凍結(jié)的對象再也不能被修改;凍結(jié)了一個對象則不能向這個對象添加新的屬性,不能刪除已有屬性,不能修改該對象已有屬性的可枚舉性、可配置性、可寫性,以及不能修改已有屬性的值。此外,凍結(jié)一個對象后該對象的原型也不能被修改。freeze()?返回和傳入的參數(shù)相同的對象。
Object.keys()
Object.keys()?方法會返回一個由一個給定對象的自身可枚舉屬性組成的數(shù)組,數(shù)組中屬性名的排列順序和正常循環(huán)遍歷該對象時返回的順序一致 。
//?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對象原來的值如下
??//?{
??//???value:?specifiedFunction,
??//???enumerable:?false,
??//???configurable:?true,
??//???writable:?true
??//?};
??descriptor.writable?=?false;
??return?descriptor;
}
readonly(Person.prototype,?'name',?descriptor);
//?類似于
Object.defineProperty(Person.prototype,?'name',?descriptor);
修改屬性描述對象的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)先進入,但是內(nèi)層裝飾器@dec(2)先執(zhí)行。
裝飾器只能用于類和類的方法,不能用于函數(shù),因為存在函數(shù)提升。
UEditor 是由百度「FEX前端研發(fā)團隊」開發(fā)的所見即所得富文本web編輯器
"en-US">
????"UTF-8">
????ueditor?demo
????
????
????
????
????
????
????
????
傳入自定義的參數(shù)
編輯器有很多可自定義的參數(shù)項,在實例化的時候可以傳入給編輯器:
var?ue?=?UE.getEditor('container',?{
????autoHeight:?false
});
配置項也可以通過 ueditor.config.js 文件修改
設(shè)置和讀取編輯器的內(nèi)容
通 getContent 和 setContent 方法可以設(shè)置和讀取編輯器的內(nèi)容
var?ue?=?UE.getContent();
//對編輯器的操作最好在編輯器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();
});
打開控制臺(注意:windows系統(tǒng)下請使用管理員權(quán)限打開),輸入:
npm?install?-g?grunt-cli
然后輸入以下命令。
npm?install?grunt?--save-dev
完整的按鈕列表
toolbars:?[
????[
????????'anchor',?//錨點
????????'undo',?//撤銷
????????'redo',?//重做
????????'bold',?//加粗
????????'indent',?//首行縮進
????????'snapscreen',?//截圖
????????'italic',?//斜體
????????'underline',?//下劃線
????????'strikethrough',?//刪除線
????????'subscript',?//下標
????????'fontborder',?//字符邊框
????????'superscript',?//上標
????????'formatmatch',?//格式刷
????????'source',?//源代碼
????????'blockquote',?//引用
????????'pasteplain',?//純文本粘貼模式
????????'selectall',?//全選
????????'print',?//打印
????????'preview',?//預(yù)覽
????????'horizontal',?//分隔線
????????'removeformat',?//清除格式
????????'time',?//時間
????????'date',?//日期
????????'unlink',?//取消鏈接
????????'insertrow',?//前插入行
????????'insertcol',?//前插入列
????????'mergeright',?//右合并單元格
????????'mergedown',?//下合并單元格
????????'deleterow',?//刪除行
????????'deletecol',?//刪除列
????????'splittorows',?//拆分成行
????????'splittocols',?//拆分成列
????????'splittocells',?//完全拆分單元格
????????'deletecaption',?//刪除表格標題
????????'inserttitle',?//插入標題
????????'mergecells',?//合并多個單元格
????????'deletetable',?//刪除表格
????????'cleardoc',?//清空文檔
????????'insertparagraphbeforetable',?//"表格前插入行"
????????'insertcode',?//代碼語言
????????'fontfamily',?//字體
????????'fontsize',?//字號
????????'paragraph',?//段落格式
????????'simpleupload',?//單圖上傳
????????'insertimage',?//多圖上傳
????????'edittable',?//表格屬性
????????'edittd',?//單元格屬性
????????'link',?//超鏈接
????????'emotion',?//表情
????????'spechars',?//特殊字符
????????'searchreplace',?//查詢替換
????????'map',?//Baidu地圖
????????'gmap',?//Google地圖
????????'insertvideo',?//視頻
????????'help',?//幫助
????????'justifyleft',?//居左對齊
????????'justifyright',?//居右對齊
????????'justifycenter',?//居中對齊
????????'justifyjustify',?//兩端對齊
????????'forecolor',?//字體顏色
????????'backcolor',?//背景色
????????'insertorderedlist',?//有序列表
????????'insertunorderedlist',?//無序列表
????????'fullscreen',?//全屏
????????'directionalityltr',?//從左向右輸入
????????'directionalityrtl',?//從右向左輸入
????????'rowspacingtop',?//段前距
????????'rowspacingbottom',?//段后距
????????'pagebreak',?//分頁
????????'insertframe',?//插入Iframe
????????'imagenone',?//默認
????????'imageleft',?//左浮動
????????'imageright',?//右浮動
????????'attachment',?//附件
????????'imagecenter',?//居中
????????'wordimage',?//圖片轉(zhuǎn)存
????????'lineheight',?//行間距
????????'edittip?',?//編輯提示
????????'customstyle',?//自定義標題
????????'autotypeset',?//自動排版
????????'webapp',?//百度應(yīng)用
????????'touppercase',?//字母大寫
????????'tolowercase',?//字母小寫
????????'background',?//背景
????????'template',?//模板
????????'scrawl',?//涂鴉
????????'music',?//音樂
????????'inserttable',?//插入表格
????????'drafts',?//?從草稿箱加載
????????'charts',?//?圖表
????]
]
傳入配置參數(shù)
var?ue?=?UE.getEditor('container',?{
????toolbars:?[
????????['fullscreen',?'source',?'undo',?'redo',?'bold']
????],
????autoHeightEnabled:?true,
????autoFloatEnabled:?true
});
讀取配置項
讀取配置項可以通過getOpt方法讀取
var?lang?=?ue.getOpt('lang');?//默認返回:zh-cn
前端配置項說明
UEDITOR_HOME_URL?{Path String} [默認值:根據(jù)config文件路徑自動獲取] // 為編輯器實例添加一個路徑,這個不能被注釋
serverUrl?{Path String} [默認值:URL + "php/controller.php"] // 服務(wù)器統(tǒng)一請求接口路徑
toolbars?{2d Array} //工具欄上的所有的功能按鈕和下拉框,可以在new編輯器的實例時選擇自己需要的從新定義
labelMap?{Object} [默認:從lang包的labelMap項獲取] //參數(shù)格式是鍵值對,鍵名對應(yīng)toolbar參數(shù)的項:{"bold": "加粗"} ],當鼠標放在工具欄上時顯示的tooltip提示,留空支持自動多語言配置,否則以配置值為準
lang?{String} [默認值:"zh-cn"] //lang值也可以通過自動獲取 (navigator.language||navigator.browserLanguage ||navigator.userLanguage).toLowerCase(),語言配置項,默認是zh-cn。有需要的話也可以使用如下這樣的方式來自動多語言切換,當然,前提條件是lang文件夾下存在對應(yīng)的語言文件:
langPath?{Path String} [默認值:URL +"lang/"] //語言包文件存放目錄
theme?{String} [默認值:'default'] //主題配置項,默認是default。有需要的話也可以使用如下這樣的方式來自動多主題切換,當然,前提條件是themes文件夾下存在對應(yīng)的主題文件:
themePath?{Path String} [默認值:URL +"themes/"] //現(xiàn)有如下皮膚:default
zIndex?{Number} [默認值:900] //編輯器在頁面上的z-index層級的基數(shù),默認是900
charset?{String} [默認值:"utf-8"] //針對getAllHtml方法,會在對應(yīng)的head標簽中增加該編碼設(shè)置。
customDomain?{Boolean} [默認值:false] //若實例化編輯器的頁面手動修改的domain,此處需要設(shè)置為true
isShow?{Boolean} [默認值:true] //默認顯示編輯器
textarea?{String} [默認值:'editorValue'] // 提交表單時,服務(wù)器獲取編輯器提交內(nèi)容的所用的參數(shù),多實例時可以給容器name屬性,會將name給定的值最為每個實例的鍵值,不用每次實例化的時候都設(shè)置這個值
initialContent?{String} [默認值:'歡迎使用ueditor!'] //初始化編輯器的內(nèi)容,也可以通過textarea/script給值,看官網(wǎng)例子
autoClearinitialContent?{Boolean} [默認值:true] //是否自動清除編輯器初始內(nèi)容,注意:如果focus屬性設(shè)置為true,這個也為真,那么編輯器一上來就會觸發(fā)導(dǎo)致初始化的內(nèi)容看不到了
focus?{Boolean} [默認值:false] //初始化時,是否讓編輯器獲得焦點true或false
initialStyle?{String} [默認值:'p{line-height:1em}']//編輯器層級的基數(shù),可以用來改變字體等 //如果自定義,最好給p標簽如下的行高,要不輸入中文時,會有跳動感
iframeCssUrl?{Path String} [默認值:URL + '/themes/iframe.css'] //給編輯器內(nèi)部引入一個css文件
indentValue?{String} [默認值:'2em'] //首行縮進距離,默認是2em
initialFrameWidth?{Number} [默認值:1000] //初始化編輯器寬度,默認1000
initialFrameHeight?{Number} [默認值:320] //初始化編輯器高度,默認320
readonly?{Boolean} [默認值:false] //編輯器初始化結(jié)束后,編輯區(qū)域是否是只讀的,默認是false
autoClearEmptyNode?{Boolean} [默認值:true] //getContent時,是否刪除空的inlineElement節(jié)點(包括嵌套的情況)
enableAutoSave?{Boolean} [默認值:true] //啟用自動保存
saveInterval?{Number} [默認值:500] //自動保存間隔時間,單位ms
imageScaleEnabled?{Boolean} [默認值:true] //啟用圖片拉伸縮放
fullscreen?{Boolean} [默認值:false] //是否開啟初始化時即全屏,默認關(guān)閉
imagePopup?{Boolean} [默認值:true] //圖片操作的浮層開關(guān),默認打開
autoSyncData?{Boolean} [默認值:true] //自動同步編輯器要提交的數(shù)據(jù)
emotionLocalization?{Boolean} [默認值:false] //是否開啟表情本地化,默認關(guān)閉。若要開啟請確保emotion文件夾下包含官網(wǎng)提供的images表情文件夾
retainOnlyLabelPasted?{Boolean} [默認值:false] //粘貼只保留標簽,去除標簽所有屬性
pasteplain?{Boolean} [默認值:false] //是否默認為純文本粘貼。false為不使用純文本粘貼,true為使用純文本粘貼
filterTxtRules?{Object} //純文本粘貼模式下的過濾規(guī)則
allHtmlEnabled?[默認值:false] //提交到后臺的數(shù)據(jù)是否包含整個html字符串
insertorderedlist?//有序列表的下拉配置,值留空時支持多語言自動識別,若配置值,則以此值為準insertunorderedlist?//無序列表的下拉配置,值留空時支持多語言自動識別,若配置值,則以此值為準
listDefaultPaddingLeft?[默認值:'30'//默認的左邊縮進的基數(shù)倍
listiconpath?[默認值:'http://bs.baidu.com/listicon/']//自定義標號的路徑
maxListLevel?[默認值:3] //限制可以tab的級數(shù), 設(shè)置-1為不限制
autoTransWordToList?[默認值:false] //禁止word中粘貼進來的列表自動變成列表標簽
fontfamily?//字體設(shè)置 label留空支持多語言自動切換,若配置,則以配置值為準
fontsize?{Array} //字號
//默認值:
[10,?11,?12,?14,?16,?18,?20,?24,?36]paragraph?{Object} //段落格式 值留空時支持多語言自動識別,若配置,則以配置值為準
//默認值:
{
????'p':?'',
????'h1':?'',
????'h2':?'',
????'h3':?'',
????'h4':?'',
????'h5':?'',
????'h6':?''
}rowspacingtop?{Array} //段間距 值和顯示的名字相同
//默認值:
['5',?'10',?'15',?'20',?'25']rowspacingbottom?//段間距 值和顯示的名字相同
//默認值:
['5',?'10',?'15',?'20',?'25']lineheight?[默認值:['1', '1.5','1.75','2', '3', '4', '5'] ] //行內(nèi)間距 值和顯示的名字相同
customstyle?[Array] //自定義樣式,不支持國際化,此處配置值即可最后顯示值block的元素是依據(jù)設(shè)置段落的邏輯設(shè)置的,inline的元素依據(jù)BIU的邏輯設(shè)置,盡量使用一些常用的標簽
//默認值:
[{
????????tag:?'h1',?//tag?使用的標簽名字
????????name:?'tc',?//
????????label:?'',?//label?顯示的名字也是用來標識不同類型的標識符,注意這個值每個要不同
????????style:?'border-bottom:#ccc?2px?solid;padding:0?4px?0?0;text-align:center;margin:0?0?20px?0;'?//style?添加的樣式
????},?//每一個對象就是一個自定義的樣式enableContextMenu?{Boolean} [默認值:true] //打開右鍵菜單功能
contextMenu?{Object} //右鍵菜單的內(nèi)容
shortcutMenu?{Array} //快捷菜單
//默認值
["fontfamily",?"fontsize",?"bold",?"italic",?"underline",?"forecolor",?"backcolor",?"insertorderedlist",?"insertunorderedlist"]elementPathEnabled?{Boolean} [默認值:true] //是否啟用元素路徑,默認是顯示
wordCount?{Boolean} [默認值:true] //是否開啟字數(shù)統(tǒng)計
maximumWords?{Number} [默認值:10000] //允許的最大字符數(shù)
wordCountMsg?{String} [默認值:] //當前已輸入 {#count} 個字符,您還可以輸入{#leave} 個字符,字數(shù)統(tǒng)計提示,{#count}代表當前字數(shù),{#leave}代表還可以輸入多少字符數(shù),留空支持多語言自動切換,否則按此配置顯示
\默認值:
'當前已輸入{#count}個字符, 您還可以輸入{#leave}個字符。?'wordOverFlowMsg?{String} [默認值:] //超出字數(shù)限制提示 留空支持多語言自動切換,否則按此配置顯示
\默認值:
'你輸入的字符個數(shù)已經(jīng)超出最大允許值,服務(wù)器可能會拒絕保存!'tabSize?{Number} [默認值:4] //點擊tab鍵時移動的距離,tabSize倍數(shù),tabNode什么字符做為單位
tabNode?{String} [默認值:'?']
removeFormatTags?//清除格式時可以刪除的標簽和屬性
//默認值:
'b,big,code,del,dfn,em,font,i,ins,kbd,q,samp,small,span,strike,strong,sub,sup,tt,u,var'removeFormatAttributes?[默認值:'class,style,lang,width,height,align,hspace,valign'
maxUndoCount?{Number} [默認值:20] //undo操作,可以最多回退的次數(shù),默認20
maxInputCount?{Number} [默認值:1] //undo操作,當輸入的字符數(shù)超過該值時,保存一次現(xiàn)場
autoHeightEnabled?{Boolean} [默認值:true] //是否自動長高,默認true
scaleEnabled?{Boolean} [默認值:false] //是否可以拉伸長高,默認true(當開啟時,自動長高失效)
minFrameWidth?{Number} [默認值:800] //編輯器拖動時最小寬度,默認800
minFrameHeight?{Number} [默認值:220] //編輯器拖動時最小高度,默認220
autoFloatEnabled?[默認值:true] //是否保持toolbar的位置不動,默認true
topOffset?[默認值:30] //浮動時工具欄距離瀏覽器頂部的高度,用于某些具有固定頭部的頁面
toolbarTopOffset?[默認值:400] //編輯器底部距離工具欄高度(如果參數(shù)大于等于編輯器高度,則設(shè)置無效)
pageBreakTag?[默認值:'ueditorpagebreaktag '] //分頁標識符,默認是ueditorpagebreaktag
autotypeset?{Object} //自動排版參數(shù) 默認值:
{
????mergeEmptyline:?true,?//合并空行
????removeClass:?true,?//去掉冗余的class
????removeEmptyline:?false,?//去掉空行
????textAlign:?"left",?//段落的排版方式,可以是?left,right,center,justify?去掉這個屬性表示不執(zhí)行排版
????imageBlockLine:?'center',?//圖片的浮動方式,獨占一行劇中,左右浮動,默認:?center,left,right,none?去掉這個屬性表示不執(zhí)行排版
????pasteFilter:?false,?//根據(jù)規(guī)則過濾沒事粘貼進來的內(nèi)容
????clearFontSize:?false,?//去掉所有的內(nèi)嵌字號,使用編輯器默認的字號
????clearFontFamily:?false,?//去掉所有的內(nèi)嵌字體,使用編輯器默認的字體
????removeEmptyNode:?false,?//?去掉空節(jié)點
????//可以去掉的標簽
????removeTagNames:?{標簽名字:?1
????},
????indent:?false,?//?行首縮進
????indentValue:?'2em',?//行首縮進的大小
????bdc2sb:?false,
????tobdc:?false
}tableDragable?{Boolean} [默認值:true] //表格是否可以拖拽
disabledTableInTable?{Boolean} [默認值:true] //禁止表格嵌套
sourceEditor?{String} [默認值:"codemirror"] //源碼的查看方式,codemirror是代碼高亮,textarea是文本框,默認是codemirror,注意默認codemirror只能在ie8+和非ie中使用
codeMirrorJsUrl?{Path String} [默認值:URL + "third-party/codemirror/codemirror.js"] //如果sourceEditor是codemirror需要配置這項,codeMirror js加載的路徑
codeMirrorCssUrl?{Path String} [默認值:URL + "third-party/codemirror/codemirror.css"] //如果sourceEditor是codemirror需要配置這項,codeMirror css加載的路徑
sourceEditorFirst?{String} [默認值:false] //編輯器初始化完成后是否進入源碼模式,默認為否。
iframeUrlMap?{Object} //dialog內(nèi)容的路徑 ~會被替換成URL,垓?qū)傩砸坏┐蜷_,將覆蓋所有的dialog的默認路徑
//默認值:
{
????'anchor':?'~/dialogs/anchor/anchor.html',
}webAppKey?{String} //webAppKey 百度應(yīng)用的APIkey,每個站長必須首先去百度官網(wǎng)注冊一個key后方能正常使用app功能,注冊介紹,http://app.baidu.com/static/cms/getapikey.html
allowDivTransToP?{Boolean} 默認會將外部進入的html數(shù)據(jù)中的Div標簽轉(zhuǎn)換成P標簽,外部進入的數(shù)據(jù)包括粘貼和調(diào)用setContent接口進入編輯器的數(shù)據(jù)。如果設(shè)置成false將不在做這個轉(zhuǎn)換。
dialogs: 彈出對話框?qū)?yīng)的資源和JS文件
lang: 編輯器國際化顯示的文件
php或jsp或asp或net: 涉及到服務(wù)器端操作的后臺文件
themes: 樣式圖片和樣式文件
third-party: 第三方插件(包括代碼高亮,源碼編輯等組件)
ueditor.all.js: 開發(fā)版代碼合并的結(jié)果,目錄下所有文件的打包文件
ueditor.all.min.js: ueditor.all.js文件的壓縮版,建議在正式部署時采用
ueditor.config.js: 編輯器的配置文件,建議和編輯器實例化頁面置于同一目錄
ueditor.parse.js: 編輯的內(nèi)容顯示頁面引用,會自動加載表格、列表、代碼高亮等樣式
_doc: 部分markdown格式的文檔
_example: ueditor的使用例子
_parse: ueditor.parse.js的源碼
_src: ueditor.all.js的源碼
_src\core: ueditor核心代碼 _src\plugins: 插件文件 _src\ui: ui相關(guān)文件 _src\adapter: 橋接層文件,對接ueditor核心和ui代碼
擴展你的功能。
UE.registerUI('uiname',?function(editor,?uiname)?{
????//do?something
},?[index,?[editorId]]);
考慮到大家的功能基本上都會擴展一個UI和這個UI做的事情,所以UEditor提供了registerUI這個接口,可以讓開發(fā)者動態(tài)的注入擴展的內(nèi)容。
uiname,是你為新添加的UI起的名字,這里可以是1個或者多個,“uiname”后者是“uiname1 uiname2 uiname3” function,是實際你要做的事情,這里提供兩個參數(shù),editor是編輯器實例,如果你有多個編輯器實例,那每個編輯器實例化后,都會調(diào)用這個function,并且把editor傳進來,uiname,你為ui起的名字,如果前邊你添加的是多個的化,這里function會被調(diào)用多次,并且將每一個ui名字傳遞進來.如果函數(shù)返回了一個UI 實例,那這個UI實例就會被默認加到工具欄上。當然也可以不返回任何UI。比如希望監(jiān)控selectionchange事件,在某些場景下彈出浮層,這時就不需要返回任何UI. index,是你想放到toolbar的那個位置,默認是放到最后 editorId,當你的頁面上有多個編輯器實例時,你想將這個ui擴展到那個編輯器實例上,這里的editorId是給你編輯器初始化時,傳入的id,默認是每個實例都會加入你的擴展
追加編輯器內(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è)置上標
ue.execCommand('supscript');?//設(shè)置下標
ue.execCommand('forecolor',?'#FF0000');?//設(shè)置字體顏色
ue.execCommand('backcolor',?'#0000FF');?//設(shè)置字體背景顏色
在當前光標位置插入html內(nèi)容
ue.execCommand('inserthtml',?'hello!');
http://fex.baidu.com/ueditor/#start-config
vuex-module-decorators
安裝
npm?install?-D?vuex-module-decorators
這個包以es2015格式生成代碼。如果你的 Vue 項目面向 ES6 或 ES2015,那么你不需要做任何事情。但是如果您的項目使用es5目標(以支持舊瀏覽器),那么您需要告訴 Vue CLI / Babel 轉(zhuǎn)譯這個包。
//?in?your?vue.config.js
module.exports?=?{
??/*?...?other?settings?*/
??transpileDependencies:?['vuex-module-decorators']
}
vuex 模塊過去寫法:
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
??}
}
動態(tài)模塊
Vuex 允許我們在構(gòu)建 store 后在運行時將模塊注冊到 store。
來創(chuà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?{
...
或者當它沒有初始狀態(tài)并且您從 localStorage 加載狀態(tài)時
...
--?@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
用法
有幾個裝飾器和 1 個函數(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)注+點贊+收藏+評論+轉(zhuǎn)發(fā)??,原創(chuàng)不易,鼓勵筆者創(chuàng)作更好的文章
點贊、收藏和評論
我是Jeskson,感謝各位人才的:點贊、收藏和評論,我們下期見!(如本文內(nèi)容有地方講解有誤,歡迎指出?謝謝,一起學習了)
我們下期見!
github收錄,歡迎Star:https://1024bibi.com
