This article has participated in the “Digitalstar Project” and won a creative gift package to challenge the creative incentive money.

At the forefront of

A decorator

A decorator is a function named @ +. It can precede the definition of classes and class methods.

Decorator behavior

@ decorator class A {} / / is equivalent to A class A {} A = decorator (A) | | A;Copy the code

The first argument to the decorator function is the target class to decorate.

Note that the decorator changes the behavior of the class at compile time, not run time. This means that the decorator can run the code at compile time. That is, decorators are essentially functions that are executed at compile time.

Add Instance Attributes

function testable(target) {
  target.prototype.isTestable = true;
}

@testable
class MyTestableClass {}

let obj = new MyTestableClass();
obj.isTestable // true
Copy the code

Object.assign()

The object.assign () method is used to assign the values of all enumerable properties from one or more source objects to target objects. It will return the target object.

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 }
Copy the code
Object.assign(target, ... sources)Copy the code

If an attribute in the target object has the same key, the attribute is overwritten by an attribute in the source object. Properties of subsequent source objects similarly override properties of previous source objects.

[Copy an object]

const obj = { a: 1 };
const copy = Object.assign({}, obj);
console.log(copy); // { a: 1 }
Copy the code

[Deep copy problem]

For deep copies, an alternative approach is needed because object.assign () copies (enumerable) property values.

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();
Copy the code

[Merge object]

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}, note that the target object itself also changes.Copy the code

[Merge objects with the same properties]

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 }
Copy the code

[Copy symbol type attribute]

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)]
Copy the code

[Inherited properties and non-enumerable properties cannot be copied]

[Primitive types are wrapped as objects]

const v1 = "abc"; const v2 = true; const v3 = 10; const v4 = Symbol("foo") const obj = Object.assign({}, v1, null, v2, undefined, v3, v4); // Primitive types are wrapped, null and undefined are ignored. // Note that only string wrapping objects can have their own enumerable properties. console.log(obj); // { "0": "a", "1": "b", "2": "c" }Copy the code

Array handling

Object.assign works with arrays, but treats arrays as objects.

Object.assign([1, 2, 3], [4, 5])
// [4, 5, 3]
Copy the code

Object.assign can only be used to copy values. If the value to be copied is a value function, it will be evaluated and then copied.

const source = {
  get foo() { return 1 }
};
const target = {};

Object.assign(target, source)
// { foo: 1 }
Copy the code

Add attributes to an object

class Point { constructor(x, y) { Object.assign(this, {x, y}); }}Copy the code

Assign the x and y attributes to the Object instance of the Point class using the Object.assign method.

Clone object

function clone(origin) {
  return Object.assign({}, origin);
}
Copy the code

By copying the original object to an empty object, you get a clone of the original object.

Merging multiple objects

Merge multiple objects into an object.

const merge = (target, ... sources) => Object.assign(target, ... sources);Copy the code

If you want to return a new object after the merge, you can rewrite the above function to merge an empty object.

const merge = (... sources) => Object.assign({}, ... sources);Copy the code

Object.create()

The object.create () method creates a new Object, using an existing Object to provide the __proto__ of the newly created Object.

Object.freeze()

The object.freeze () method freezes an Object. A frozen object can no longer be modified. If you freeze an object, you cannot add new attributes to the object, delete existing attributes, modify the enumerability, configurability, writability of existing attributes of the object, or modify the value of existing attributes. In addition, the stereotype of an object cannot be modified after it is frozen. Freeze () returns the same object as the argument passed in.

Object.keys()

The object.keys () method returns an array of a given Object’s own enumerable properties in the same order as the property names would be returned if the Object were iterated through normally.

// 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']Copy the code

Method decoration

Decorators can decorate not only classes but also class properties.

Function Readonly (Target, name, descriptor){// Descriptor: specifiedFunction, // enumerable: false, // configurable: true, // writable: true // }; descriptor.writable = false; return descriptor; } readonly(Person.prototype, 'name', descriptor); // Like object.defineProperty (Person.prototype, 'name', descriptor);Copy the code

Modify the Enumerable property of the property description object to make it untraversable.

Decorators serve as annotations.

Component writing:

@Component({ tag: 'my-component', styleUrl: 'my-component.scss' }) export class MyComponent { @Prop() first: string; @Prop() last: string; @State() isVisible: boolean = true; render() { return ( <p>Hello, my name is {this.first} {this.last}</p> ); }}Copy the code
class Example {
    @dec(1)
    @dec(2)
    method(){}
}
Copy the code

The outer decorator @dec(1) enters first, but the inner decorator @dec(2) executes first.

Decorators can only be used for classes and methods of classes, not functions, because function promotion exists.

UEditor is a WYSIWYG rich text Web editor developed by Baidu’s FEX front-end development team

<! DOCTYPE HTML> <html lang="en-US"> <head> <meta charset="UTF-8"> <title>ueditor demo</title> </head> <body> <! <script id="container" name="content" type="text/plain"> Here write your initialization content </script> <! <script type="text/javascript" SRC ="ueditor.config.js"></script> <! <script type="text/javascript" SRC ="ueditor.all.js"></script> <! <script type="text/javascript"> var ue = ue.geteditor ('container'); </script> </body> </html>Copy the code

Pass in a custom parameter

The editor has a number of customizable parameters that can be passed to the editor at instantiation time:

var ue = UE.getEditor('container', {
    autoHeight: false
});
Copy the code

Configuration items can also be modified through the ueditor.config.js file

Set and read the contents of the editor

The getContent and setContent methods set and read the contents of the editor

var ue = UE.getContent(); Ue.ready (function() {// Set the content of the editor ue.setContent('hello'); <p>hello</p> var HTML = ue.getContent(); Var TXT = ue.getContenttxt (); });Copy the code

Open the console (note: under Windows, please open it with administrator permission) and type:

npm install -g grunt-cli
Copy the code

Then enter the following command.

npm install grunt --save-dev
Copy the code

Complete list of buttons

toolbars: [[' anchor ', / / anchors' undo ', / / cancellation 'redo', / / redo 'bold', / / bold 'indent, / / first line indentation' snapscreen ', / / screenshot 'italic, // underline' strikethrough', // delete line' subscript', // subscript' fontborder', // character border' superscript', // blockquote', // pasteplain', // selectAll ', // print', // Print 'preview', // preview' horizontal', // delimit line 'removeFormat ', // clear format' time', // time' date', // date' unlink', // cancel link' insertrow', Insert row' insertcol', insert column 'mergeright', merge cell 'mergedown', merge cell 'deleterow', deleterow' deletecol', // Delete column 'splittorows', // split into row 'splitTocols ', // split into column' splitTocells ', // completely split cell 'deletecaption', // delete table title' insertTitle ', / / insert the title 'mergecells', / / merge multiple cells' deletetable', 'cleardoc / / delete form, / /' insertparagraphbeforetable 'empty document, //" insert line before table ", // code language 'fontfamily', // font 'fontsize', // size' paragraph', // paragraph format 'simpleupload', // Single map upload 'insertimage', // multiple map upload 'edittable', // table attribute 'editTD ', // Cell attribute 'link', // hyperlink 'emotion', // expression 'spechars', // special character 'searchreplace', // query replace' map', //Baidu map' gmap', //Google map' insertvideo', // video' help', // help' justifyleft', Justify 'justify ', justify' justify', justify' justify', justify' justify', justify' justify', justify' justify', justify' justify', justify' justify' // background color 'insertorderedlist', // orderedlist' insertunorderedlist', // orderedlist' fullscreen', // fullscreen' directionalityltr', // Type 'directionalityrtl' from left to right, // type 'RowSpacingTop' from right to left, // segment front 'RowSpacingBottom ', // segment back' pageBreak ', // insert Iframe 'imagenone', // default 'imageleft', // float left' imageright', // float right' attachment', // attach 'imagecenter', // center' wordimage', // image transfer 'lineheight', // line spacing 'edittip ', // edittip 'customstyle', // Custom title 'autotypeset', // automatic typesetting 'webApp ', // Baidu app' toupperCase ', // uppercase' tolowerCase ', // lowercase' background', / / background 'template', 'scrawl', / / template / / graffiti 'music', / / music 'inserttable', / / insert table 'drafts', / / the load from the draft tank' charts', / / chart]]Copy the code

Passing in configuration parameters

var ue = UE.getEditor('container', {
    toolbars: [
        ['fullscreen', 'source', 'undo', 'redo', 'bold']
    ],
    autoHeightEnabled: true,
    autoFloatEnabled: true
});
Copy the code

Reading configuration Items

Read configuration items can be read using the getOpt method

var lang = ue.getOpt('lang'); // The default value is zh-cnCopy the code

Description of front-end configuration items

  • UEDITOR_HOME_URL {Path String} [default: automatically retrieved from config file Path] // Adds a Path to the editor instance. This cannot be commented out

  • ServerUrl {Path String} [Default: URL + “PHP /controller.php”] // The server requests the interface Path

  • Toolbars {2d Array} // All the function buttons and drop down boxes on the toolbar, you can select your own new definition in the new editor instance

  • LabelMap {Object} [default: obtained from labelMap item of lang package] // Parameter format is key-value pair, key name corresponding to toolbar parameter item: {“bold”: “Bold “}], the tooltip is displayed when the mouse is placed on the toolbar. The default value is left blank. Automatic multi-language configuration is supported

  • Lang {String} [Default: “Useful – cn”] / / lang values can also be through automatic access to (the navigator. Language | | the navigator. BrowserLanguage | | the navigator. UserLanguage). ToLowerCase (), language configuration items, The default value is zh-cn. If necessary, you can also use the following method to automatically switch languages, of course, provided that the corresponding language files exist in the lang folder:

  • LangPath {Path String} [default: URL +”lang/”] // Language package directory

  • Theme {String} [default: ‘default’] // Theme configuration item, default is default. If necessary, you can also use the following method to automatically switch between themes. Of course, if there is a theme file in the Themes folder:

  • ThemePath {Path String} [default: URL +”themes/”] // The following skins are available: default

  • ZIndex {Number} [default: 900] // The cardinality of the editor’s z-index hierarchy on the page. The default is 900

  • Charset {String} [default: “UTF-8 “] // For the getAllHtml method, this encoding is added to the corresponding head tag.

  • CustomDomain {Boolean} [Default: false] // If the domain is manually modified on the page for instantiating the editor, set this parameter to true

  • IsShow {Boolean} [default: true] // Displays the editor by default

  • Textarea {String} [default: ‘editorValue’] // When the form is submitted, the server gets the parameters used by the editor to submit the content. In multi-instance cases, the container can be given the name attribute, and the value given by name is used as the key value for each instance

  • InitialContent {String} [default: ‘Welcome to uEditor!’] // Initialize the contents of the editor. You can also use textarea/script to initialize the contents

  • AutoClearinitialContent {Boolean} [default: true] // Whether to automatically clear the initial content of the editor. Note: if focus is set to true and this is true, the editor will trigger the initialization and the content will not be visible

  • Focus {Boolean} [default: false] // Whether to give the editor focus true or false during initialization

  • InitialStyle {String} [default: ‘p{line-height:1em}’]// initialStyle {String} [default: ‘p{line-height:1em}’]// Editor level cardinality, can be used to change font etc

  • IframeCssUrl {Path String} [default: URL + ‘/themes/iframe.css’] // Introduce a CSS file inside the editor

  • IndentValue {String} [default: ‘2em’] // First indentation distance, default is 2em

  • InitialFrameWidth {Number} [default: 1000] // Initializes the editor width, default: 1000

  • InitialFrameHeight {Number} [default: 320] // Initialize the editor height, default: 320

  • Readonly {Boolean} [default: false] // Whether the editing area is read-only after the editor is initialized, the default is false

  • AutoClearEmptyNode {Boolean} [Default: true] // Whether to remove an empty inlineElement node (including nesting) when getContent

  • EnableAutoSave {Boolean} [Default: true] // Enable automatic saving

  • SaveInterval {Number} [Default: 500] // Automatic saving interval, in ms

  • ImageScaleEnabled {Boolean} [Default: true] // Enable image stretching and scaling

  • Fullscreen {Boolean} [Default: false] // Whether to enable full-screen initialization

  • ImagePopup {Boolean} [Default: true] // Float layer switch for image manipulation, on by default

  • AutoSyncData {Boolean} [default: true] // Automatically synchronizes data to be submitted by the editor

  • EmotionLocalization {Boolean} [default: false] // Whether emotionLocalization is enabled. It is disabled by default. To enable this, make sure the emotion folder contains the images emoticos folder provided on the official website

  • RetainOnlyLabelPasted {Boolean} [Default: false] // Paste only the label, remove all attributes of the label

  • Pasteplain {Boolean} [default: false] // Whether plain text paste is default. False: do not paste plain text. True: Paste plain text

  • FilterTxtRules {Object} // Filter rules in plain text paste mode

  • AllHtmlEnabled [Default: false] // Whether the data submitted to the background contains the entire HTML string

  • Insertorderedlist // Drop down configuration of orderedlist, support multi-language automatic recognition when the value is empty, if the value is configured, the value shall be the criterion

Insertunorderedlist // Drop down configuration of an unorderedlist. Multi-language automatic recognition is supported when the value is left blank. If the value is configured, the value prevails

  • ListDefaultPaddingLeft [Default: ’30’// Default left indent multiple of the cardinality

  • Listiconpath [default: ‘bs.baidu.com/listicon/’]…

  • MaxListLevel [default: 3] // Limit the number of levels that can be tabbed, set -1 to unlimit

  • AutoTransWordToList [default: false] // Disallows pasted lists in Word to automatically become list labels

  • Fontfamily // Font setting Label left blank Supports automatic multi-language switching. If configured, the configured value prevails

  • Fontsize {Array} // size

    // Default values: [10, 11, 12, 14, 16, 18, 20, 24, 36]Copy the code
  • Paragraph {Object} // Automatic multi-language identification is supported when the paragraph format value is left blank. If configured, the configured value is used

    / / default: {' p ':', 'h1' : ', 'h2' : ', 'h3: "', 'h4' : ', 'the h5' : ', 'h6:'}Copy the code
  • Rowspacingtop {Array} // The segment spacing value is the same as the displayed name

    // Default: ['5', '10', '15', '20', '25']Copy the code
  • Rowspacingbottom // The segment spacing value is the same as the displayed name

    // Default: ['5', '10', '15', '20', '25']Copy the code
  • Lineheight [default: [‘ 1 ‘, ‘1.5’, 1.75 ‘ ‘, ‘2’, ‘3’, ‘4’, ‘5’]] / / line spacing value and display of the same name

  • Inline elements are inline elements according to the logic of the Settings section. Inline elements are inline elements according to the logic of the BIU

    // Default values: [{tag: 'h1', //label: 'tc', //label: '', //label: '', //label: '', //label: '', //label: '', //label: '', //label: '', //label: '', //label: '' 'border-bottom:# CCC 2px solid;padding:0 4px 0 0;text-align:center;margin:0 0 20px 0;' //style added style}, // each object is a custom styleCopy the code
  • EnableContextMenu {Boolean} [Default: true] // Enable the right-click menu function

  • ContextMenu {Object} // Right-click menu contents

  • ShortcutMenu {Array} // shortcutMenu

    // Default values ["fontfamily", "fontsize", "bold", "italic", "underline", "forecolor", "backcolor", "insertorderedList ", "insertunorderedlist"]Copy the code
  • ElementPathEnabled {Boolean} [Default: true] // Whether element paths are enabled, display by default

  • WordCount {Boolean} [default: true] // whether to enable wordCount

  • MaximumWords {Number} [Default: 10000] // Maximum Number of characters allowed

  • WordCountMsg {String} [Default: ] // The current input {#count} characters, you can also input {#leave} characters, word count hint, {#count} represents the current number of characters, {#leave} represents the number of characters can be input, support multi-language automatic switch, otherwise press this configuration display

    \ Default: '{#count} characters have been entered. You can also enter {#leave} characters. 'Copy the code
  • WordOverFlowMsg {String} [Default value:] // If the number of words exceeds the limit, the message is left blank

    \ Default: '<span style="color:red; > The number of characters you entered has exceeded the maximum allowed value, the server may refuse to save! </span>'Copy the code
  • TabSize {Number} [default: 4] // How far to move when clicking TAB, tabSize multiple, tabNode what character unit

  • TabNode {String} [default: “”]

  • RemoveFormatTags // Tags and attributes that can be removed when formatting

    / / the default value: 'b, big, code, del, DFN, em, the font, I, ins, KBD, q, samp, instead, small span, strike, strong, sub, sup, tt, u, var'Copy the code
  • RemoveFormatAttributes [default value: ‘class, style, lang, width, height, align, img tags like hspace, valign’

  • MaxUndoCount {Number} [Default: 20] // Maximum Number of rollback operations. The default value is 20

  • MaxInputCount {Number} [Default: 1] // Undo operation. If the Number of characters entered exceeds the value, the system saves the operation onsite

  • AutoHeightEnabled {Boolean} [default: true] // Indicates autoheightening, default: true

  • ScaleEnabled {Boolean} [Default: false] // Whether you can stretch height, default: true(automatic height is disabled when enabled)

  • MinFrameWidth {Number} [default: 800] // Minimum width when the editor drags. Default: 800

  • MinFrameHeight {Number} [default: 220] // Minimum height when the editor is dragged. Default: 220

  • AutoFloatEnabled [Default: true] // Whether to keep the location of the Toolbar unchanged. Default: true

  • TopOffset [Default: 30] // Height of the toolbar from the top of the browser when floating, used for some pages with fixed headers

  • ToolbarTopOffset [default: 400] // The height between the bottom of the editor and the toolbar (the setting is invalid if the parameter is greater than or equal to the height of the editor)

  • PageBreakTag [Default: ‘uEditorPageBreakTag ‘] // Page identifier, default is uEditorPageBreakTag

  • Autotypeset {Object} // Automatic typeset parameters Default values:

    {mergeEmptyline: true, // mergeEmptyline removeClass: true, // remove redundant class removeEmptyline: false, // removeEmptyline textAlign: ImageBlockLine: 'center', imageBlockLine: 'center', imageBlockLine: 'center', imageBlockLine: 'center', imageBlockLine: 'center' PasteFilter: false, clearFontSize: clearFontSize: ClearFontFamily: false, // Remove all inline fonts and use the editor's default font removeEmptyNode: IndentValue: '2em', // The size of the indent: bdc2sb: false, tobdc: false }Copy the code
  • TableDragable {Boolean} [default: true] // Whether the table can be dragged

  • DisabledTableInTable {Boolean} [Default: true] // Disable table nesting

  • SourceEditor {String} [Default: “Codemirror “] // View the source code, codemirror is code highlight, textarea is a text box, the default is codemirror, note that the default codemirror can only be used in IE8 + and non-IE

  • CodeMirrorJsUrl {Path String} [Default: URL + “third – party/codemirror codemirror. Js”] / / if the sourceEditor codemirror, need to configure the codemirror js loading paths

  • CodeMirrorCssUrl {Path String} [Default: URL + “third – party/codemirror codemirror. CSS”] / / if the sourceEditor codemirror, need to configure the codemirror CSS loading paths

  • SourceEditorFirst {String} [default: false] // Whether the editor enters source mode after initialization, default: no.

  • IframeUrlMap {Object} // The path of the dialog content ~ is replaced with the URL, and the tevatron property, once turned on, overrides the default path of all dialog

    / / the default value: {' anchor ':' ~ / dialogs/anchor, the anchor. HTML ',}Copy the code
  • WebAppKey {String} / / webAppKey baidu application APIkey, each director must first go to baidu website to register a key rear can normal use function of app, register, app.baidu.com/static/cms/…

  • AllowDivTransToP {Boolean} converts Div tags into P tags by default in HTML data that comes in from outside, including pasting and calling the setContent interface into the editor. If set to false, the conversion will not be done.

  • Dialogs: Displays the resource and JS file corresponding to the dialog box

  • Lang: The editor internationalizes the file displayed

  • PHP or JSP or ASP or NET: Background files that involve server-side operations

  • Themes: Style images and style files

  • Third-party: third-party plug-ins (including code highlighting, source editing, etc.)

  • Ueditor.all. js: The result of the development code merge, a package of all the files in the directory

  • Ueditor.all.min. js: compressed version of the ueditor.all.js file, recommended for official deployment

  • Ueditor.config. js: configuration file for the editor. It is recommended that you place it in the same directory as the editor instantiation page

  • Ueditor.parse. js: The edited content displays page references and automatically loads tables, lists, code highlighting, and other styles

  • _doc: Partial documents in Markdown format

  • _example: An example of using uEditor

  • _parse: ueditor.parse. Js source code

_src: ueditor.all.js source code

  • _src\core: uEditor core code
  • _src\plugins: plug-in file
  • _src\ UI: UI-related files
  • _src\ Adapter: Bridge layer file that connects to the uEditor core and UI code

Expand your capabilities.

UE.registerUI('uiname', function(editor, uiname) {
    //do something
}, [index, [editorId]]);
Copy the code

The UEditor provides a registerUI interface that allows developers to dynamically inject the content of an extension, considering that almost all functions extend a UI and what that UI does.

  1. Uiname, that’s the name that you give to your new UI, which can be one or more, “uiname,” which is “uiname1 uiname2 uiname3.”
  2. Function is what you’re actually going to do, and you’re going to provide two arguments here, and editor is an instance of an editor, and if you have multiple instances of an editor, then after each instance of an editor is instantiated, it’s going to call this function and pass in editor,uiname, the name that you gave your UI, If you added multiple versions earlier, function will be called multiple times, passing in each UI name. If a function returns a UI instance, that UI instance is added to the toolbar by default. You can also return no UI at all. For example, if you want to monitor the SelectionChange event and pop up a float in some scenarios, you don’t need to return any UI.
  3. Index, which is where you want to put it in the toolbar, defaults to last
  4. EditorId, when you have multiple editor instances on your page and you want to extend this UI to that editor instance, the editorId is the ID that you pass in when your editor is initialized, and the default is that each instance adds your extension

Append editor content:

ue.ready(function() {
    ue.setContent('<p>new text</p>', true);
});
Copy the code
ue.ready(function() {
    var html = ue.getContent();
});
Copy the code
ue.getContentTxt();
Copy the code
ue.getPlainTxt();
Copy the code
ue.selection.getText();
Copy the code
ue.execCommand('bold'); / / bold ue. ExecCommand (" italic "); ExecCommand ('subscript'); // Set the superscript ue.execCommand('supscript'); ExecCommand ('forecolor', '#FF0000'); ExecCommand ('backcolor', '#0000FF'); // Set the font background colorCopy the code

Inserts HTML content at the current cursor position

ue.execCommand('inserthtml', '<span>hello! </span>');Copy the code

Fex.baidu.com/ueditor/#st…

vuex-module-decorators

The installation

npm install -D vuex-module-decorators
Copy the code

This package generates code in ES2015 format. If your Vue project is for ES6 or ES2015, you don’t need to do anything. But if your project uses es5 targets (to support older browsers), then you need to tell Vue CLI/Babel to translate this package.

// in your vue.config.js
module.exports = {
  /* ... other settings */
  transpileDependencies: ['vuex-module-decorators']
}
Copy the code

Vuex module used to be written:

const moduleA = {
  state: { ... },
  mutations: { ... },
  actions: { ... },
  getters: { ... }
}

const moduleB = {
  state: { ... },
  mutations: { ... },
  actions: { ... }
}

const store = new Vuex.Store({
  modules: {
    a: moduleA,
    b: moduleB
  }
})
Copy the code
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
  }
}
Copy the code
import { Module, VuexModule, MutationAction } from 'vuex-module-decorators' import { ConferencesEntity, EventsEntity } from '@/models/definitions' @Module export default class HGAPIModule extends VuexModule { conferences: Array<ConferencesEntity> = [] events: Array<EventsEntity> = [] // '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 } }Copy the code
@Module
class MyModule extends VuexModule {
  wheels = 2

  @Mutation
  incrWheels(extra) {
    this.wheels += extra
  }

  get axles() {
    return this.wheels / 2
  }
}
Copy the code
const module = {
  state: { wheels: 2 },
  mutations: {
    incrWheels(state, extra) {
      state.wheels += extra
    }
  },
  getters: {
    axles: (state) => state.wheels / 2
  }
}
Copy the code
import Vuex, { Module } from 'vuex'

Vue.use(Vuex)
Copy the code
@Module({ stateFactory: true })
class MyModule extends VuexModule {
  wheels = 2

  @Mutation
  incrWheels(extra) {
    this.wheels += extra
  }

  get axles() {
    return this.wheels / 2
  }
}
Copy the code
const module = {
  state() {
    return { wheels: 2 }
  },

  mutations: {
    incrWheels(state, extra) {
      state.wheels += extra
    }
  },
  getters: {
    axles: (state) => state.wheels / 2
  }
}
Copy the code

Dynamic module

Vuex allows us to register modules with the Store at run time after building the store.

To create dynamic modules

interface StoreType {
  mm: MyModule
}
// Declare empty store first
const store = new Vuex.Store<StoreType>({})

// 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
  }
}
Copy the code

If you want to preserve status

. -- @Module({ dynamic: true, store: store, name: 'mm' }) ++ @Module({ dynamic: true, store: store, name: 'mm', preserveState: true }) class MyModule extends VuexModule { ...Copy the code

Or when it has no initial state and you load the state from localStorage

. -- @Module({ dynamic: true, store: store, name: 'mm' }) ++ @Module({ dynamic: true, store: store, name: 'mm', preserveState: localStorage.getItem('vuex') ! == null }) class MyModule extends VuexModule { ...Copy the code

Vue Property Decorator

The installation

npm i -S vue-property-decorator
Copy the code

usage

There are several decorators and 1 function (Mixin) :

@Prop @PropSync @Model @ModelSync @Watch @Provide @Inject @ProvideReactive @InjectReactive @Emit @Ref @VModel @component (provided by vue-class-Component) Mixins (provided by vue-class-component named helper function)Copy the code

@Prop(options: (PropOptions | Constructor[] | Constructor) = {})decorator

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 }Copy the code
export default {
  props: {
    propA: {
      type: Number,
    },
    propB: {
      default: 'default value',
    },
    propC: {
      type: [String, Boolean],
    },
  },
}
Copy the code
import 'reflect-metadata' import { Vue, Component, Prop } from 'vue-property-decorator' @Component export default class MyComponent extends Vue { @Prop() age! : number }Copy the code

@PropSync(propName: string, options: (PropOptions | Constructor[] | Constructor) = {})decorator

import { Vue, Component, PropSync } from 'vue-property-decorator' @Component export default class YourComponent extends Vue { @PropSync('name', { type: String }) syncedName! : string }Copy the code
export default {
  props: {
    name: {
      type: String,
    },
  },
  computed: {
    syncedName: {
      get() {
        return this.name
      },
      set(value) {
        this.$emit('update:name', value)
      },
    },
  },
}
Copy the code

@Model(event? : string, options: (PropOptions | Constructor[] | Constructor) = {})decorator

import { Vue, Component, Model } from 'vue-property-decorator' @Component export default class YourComponent extends Vue { @Model('change', { type: Boolean }) readonly checked! : boolean }Copy the code
export default {
  model: {
    prop: 'checked',
    event: 'change',
  },
  props: {
    checked: {
      type: Boolean,
    },
  },
}
Copy the code

@ModelSync(propName: string, event? : string, options: (PropOptions | Constructor[] | Constructor) = {})decorator

import { Vue, Component, ModelSync } from 'vue-property-decorator' @Component export default class YourComponent extends Vue { @ModelSync('checked', 'change', { type: Boolean }) readonly checkedValue! : boolean }Copy the code
export default {
  model: {
    prop: 'checked',
    event: 'change',
  },
  props: {
    checked: {
      type: Boolean,
    },
  },
  computed: {
    checkedValue: {
      get() {
        return this.checked
      },
      set(value) {
        this.$emit('change', value)
      },
    },
  },
}
Copy the code

@Watch(path: string, options: WatchOptions = {})decorator

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) {}
}
Copy the code
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) {},
  },
}
Copy the code

@Provide(key? : string | symbol)/@Inject(options? : { from? : InjectKey, default? : any } | InjectKey)decorator

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' }Copy the code
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,
    }
  },
})
Copy the code

@ProvideReactive(key? : string | symbol)/@InjectReactive(options? : { from? : InjectKey, default? : any } | InjectKey)decorator

If the parent component modifies the supplied value, the child component can capture the change.

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 }Copy the code

@Emit(event? : string)decorator

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)
    })
  }
}
Copy the code
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)
      })
    },
  },
}
Copy the code

@Ref(refKey? : string)decorator

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 }Copy the code
export default {
  computed() {
    anotherComponent: {
      cache: false,
      get() {
        return this.$refs.anotherComponent as AnotherComponent
      }
    },
    button: {
      cache: false,
      get() {
        return this.$refs.aButton as HTMLButtonElement
      }
    }
  }
}
Copy the code

@VModel(propsArgs? : PropOptions)decorator

import { Vue, Component, VModel } from 'vue-property-decorator' @Component export default class YourComponent extends Vue { @VModel({ type: String }) name! : string }Copy the code
export default {
  props: {
    value: {
      type: String,
    },
  },
  computed: {
    name: {
      get() {
        return this.value
      },
      set(value) {
        this.$emit('input', value)
      },
    },
  },
}
Copy the code

❤️ follow + like + favorites + comments + forward ❤️, original is not easy, encourage the author to create better articles

Likes, favorites and comments

I’m Jeskson, and thanks for your talent: likes, favorites and comments. See you next time! ☞ Thank you for learning with me.

See you next time!

Github: 1024bibi.com

“Welcome to the discussion in the comments section. The excavation authorities will draw 100 nuggets in the comments section after project Diggnation. See the event article for details.”