Custom instruction

1) Basic usage:

Basic create custom instruction syntax:

Vue.directive('focus',{ inserted:function(el){ el.focus(); }})Copy the code

Custom instruction usage:

<input type="text" v-focus>
Copy the code
<! DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, Initial-scale =1.0" /> <title> <body> <div id="app"> <input type="text" V-focus /> </div> <script SRC ="vue.js"></script> <script> vue.directive ("focus", {inserted: function (el) {//el: el.focus(); }}); const vm = new Vue({ el: "#app", data: {}, }); </script> </body> </html>Copy the code

[insert] We use the directive method to create a focus directive, which must be inserted with a V -. [Insert] The hook function of the directive, which is called when the bound element is inserted into the parent node.

Custom instructions with parameters

Example: changes the background color of an element

Vue. Directive ('color',{inserted:function(el,binging){// binging indicates the parameters el.style. BackgroundColor = binging. }})Copy the code

Instruction usage:

<input type="text" v-color='{color:"orange"}' />
Copy the code

Complete usage:

<! DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, Initial-scale =1.0" /> <title> </head> <body> <div id="app"> <input type="text" V-color =" MSG "/> </div> <script SRC ="vue.js"></script> <script> // custom directive - with arguments vue.directive ("color", {bind: function (el, binding) { el.style.backgroundColor = binding.value.color; }}); const vm = new Vue({ el: "#app", data: { msg: { color: "blue", }, }, }); </script> </body> </html>Copy the code

The above code defines a color directive, which is used to pass the MSG object, so the object is given the binding parameter, and the value of the color attribute in the MSG object is obtained by the value attribute of this parameter. The bind hook function is called only once, the first time the bind instruction is called to an element, and you can initialize the binding only once.

Custom local directives

Basic syntax:

Inserted :function(EL){el.focus()}}Copy the code

Add the cache code in the Vue instance:

<! DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, </head> <body> <div id="app"> <input type="text" v-color=" MSG "/> </div> <script src="vue.js"></script> <script> const vm = new Vue({ el: "#app", data: { msg: { color: "red", }, }, directives: { color: { bind: function (el, binding) { el.style.backgroundColor = binding.value.color; }},}}); </script> </body> </html>Copy the code

Rendering function

Vue recommends using templates to create your HTML in the vast majority of cases, but there are scenarios where you really need the full programming power of JavaScript, that is, using JavaScript to create HTML, where you can use rendering functions, which are closer to the compiler than templates

Basic structure of render function

Render :function(createElement){// Render :function(createElement){render:function(createElement){ Return createElement(tag, // tag name data, // pass data children // array of child nodes)}Copy the code

Example of creating a component code using the render function:

// Heading component //<heading :level="1">{{title}}</heading Vue.component("heading", { props: { level: { type: String, required: Return h("h" + this.level, // parameter 1, which indicates the element to be created this.$slot.default // parameter 3, VNode array of child nodes. {{tile}} is a child element without argument 2. }});Copy the code

Then you can use the heading component

<heading level="1"> {{title}} </heading>Copy the code

Ofcause You need to define the title attribute in data

Data :{num:100, totalCount:0, users: [], height: 0, userInfo: "ABC ", title:" userInfo ", // isShow: false, // showwarn: False, // Control display and hide of warning window},Copy the code

The complete code

<! DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, <style>. Actived {background-color: # DDDDDD; background-color: # DDDDDD; } .message-box { padding: 10px 20px; } .success { background-color: #4fc; border: 1px solid #42b; } .warning { background-color: red; border: 1px solid #42b; } .message-box-close { float: right; } </style> </head> <body> <div id="app"> <! <message ref="msgSuccess" class="success"> <! -- Titile slot --> <template v-slot:title> <h2> Congratulations </h2> </template> <! -- Default slot --> <template> Add user successfully </template> </message> <! <message ref="msgWaring" class="warning"> <! -- Titile slot --> <template v-slot:title> <h2> Warning </h2> </template> <! -- Default slot --> <template> Please enter user name </template> </message> <! <heading level="1"> {{title}} </heading> <! - clear hint bar - > < div class = "toolbar" > < button @ click = "$bus. $emit (' message - close ')" > clear hint bar < / button > < / div > <! <p> <input type="text" v-model.number="height" /> <button @click="batchUpdate"> </button> </p> <! - new users - > < user - add @ the add - user = "addUser" v - model = "the userInfo" > < / user - add > <! -- User list component --> <user-list :users="users"></user-list> <p> {{totalCount}} </p> </div> <script SRC ="vue.js"></script> <script> // Heading component //<heading :level="1">{{title}}</heading Vue.component("heading", { props: { level: { type: String, required: },}, render(h) {return h("h" + this.level, // 1, this.$slots.default // 3, VNode array. {{tile}} is a child element without argument 2. }}); Vue.component("message", {//show the meaning of the message, control the pop-up window display and hide. //slot: indicates slot occupation. The contents of the window are passed through external components. // props: ["show"], data() { return { show: false, }; }, template: `<div class='message-box' v-if="show"> <! </slot> </slot> <span class="message-box-close" @click='toggle'> </span> </div> ', mounted() {// Attach a message-close event to the bus. this.$bus.$on("message-close", () => { // this.$emit("close", false); // Close the warning window and prompt message window when it is displayed. if (this.show) { this.toggle(); }}); }, methods: { toggle() { this.show = ! this.show; ,}}}); / / new users component Vue.com ponent (" user - add, "{/ / data () {/ / return {/ / the userInfo:" ", / /}; // }, props: ["value"], template: ` <div> <p> <input type="text" :value="value" @input="onInput" von:keydown.enter="addUser" ref="inp" /> </p> <button </button> </div> ', methods: $emit("add-user", this.userinfo); $emit("add-user", this.userinfo); this.$emit("add-user"); // this.userInfo = ""; }, onInput(e) { this.$emit("input", e.target.value); }, }, mounted() { this.$refs.inp.focus(); }}); Vue.com ("user-list", {data() {return {selectItem: "",}; Vue.com ("user-list", {data() {return {selectItem: ",}; }, props: { users: { type: Array, default: [], }, }, template: '<div> <p v-if="users.length===0"> No user data </p> <ul V-else > <li V-for ="(item,index) in users" :key="item.id" :style="{backgroundColor:selectItem===item? '# DDDDDD ':'transparent'}" @mousemove="selectItem=item" > {{item. Id}} name: {{item. The name}} - height: {{item. Height}} < / li > < / ul > < / div > `,}); New Vue({el: "#app", data: {num: 100, totalCount: 0, users: [], height: 0, userInfo: "ABC ", title:" userInfo ", // isShow: False, // showWarn: false, // Control warning window display and hide}, // component instance created async created() {const Users = await this.getUserList(); this.users = users; This.batchupdate (); this.batchupdate (); }, methods: {// closeWindow closeWindow(data) {this.isShow = data; this.showWarn = data; }, // addUser info addUser() {if (this.userinfo) {if (this.users.length > 0) {this.users.push({id: this.users[this.users.length - 1].id + 1, name: this.userInfo, }); this.userInfo = ""; // This. IsShow = true; // This. this.$refs.msgSuccess.toggle(); }} else {// Display error warning message // this.showWarn = true; this.$refs.msgWaring.toggle(); }}, batchUpdate() {this.users.foreach ((c) => {// c.eight = this.height; // Vue.set(c, "height", this.height); this.$set(c, "height", this.height); }); }, getTotal: function () { console.log("methods"); Return this.users.length + ""; }, getUserList: function () { return new Promise((resolve) => { setTimeout(() => { resolve([ { id: 1, name: "Joe,"}, {id: 2, name: "bill,"}, {id: 3, name: "Lao wang,"},]); }, 2000); }); },}, watch: {users: {immediate: true, // Handler (newValue, oldValue) {this.totalCount = newValue.length + "personal "; }},}}); </script> </body> </html>Copy the code

Virtual DOM

Does vue track how it changes the real DOM by creating a virtual DOM

CreateElement method parameter

The createElement function takes three arguments

CreateElement method (/ / {string | Object | Function} / / the first parameter, can be a string, also can be Object or Function 'div', / / the second parameter is the Object that represents an Object and the nature of the corresponding data in the template. This parameter is optional {}, and the third parameter is an array representing an array of children [])Copy the code

Next add the first property to the heading component

<heading level="1" :title="title">
{{title}}
</heading>

Copy the code

In the code above, we dynamically add a title attribute to the Heading component. For the heading component, we know that the final rendering is an H1 element, and the final effect is: < h1 title=’aaa’>

// Heading component //<heading :level="1">{{title}}</heading Vue.component("heading", { props: { level: { type: String, required: true, }, title: { type: String, default: ",},}, render(h) {return h("h" + this.level, // render(h) {attrs: {title: This. title}}, // parameter 2 this.$slots.default // parameter 3, VNode array. {{tile}} is a child element without argument 2. }});Copy the code

In the above code, we add a second argument to the h function in the render function and the attrs attribute to the final generated element

Functional component

When a component does not manage any state, does not listen for any state passed to it, and has no lifecycle methods, it can be marked as functional. This means that it is stateless (no responsive data) and has no instances (no this context) because it is just a function, so the rendering overhead is relatively small. The Render function in the functionalized component provides the second argument context. Data, props, slots, children, and parent can all be accessed through context.

Mixed with

Mixins provide a very flexible way to distribute reusable functionality in Vue components. A mixin object can contain any component option. When a component uses mixin, all mixin options are “blended” into the component’s own options.

Var myMixin={created:function(){this.hello()}, methods:{ hello:function(){ console.log('hello world') } } } Vue.component('comp',{ mixins:[myMixin] })Copy the code

Mixing improves component reuse. For example, the hello method written above is used not only in one component, but also in other components. Instead, we can define hello in a separate place and inject it directly into a component if it wants to use it

The plug-in

Mixing, component encapsulation, etc. can improve the reuse of components, but this method is not suitable for distribution, that is, it is not suitable for uploading these contents to Github, NPM. This is best achieved through plug-ins

Plug-ins are usually used to add global functionality to a Vue. The functions of plug-ins are generally as follows:

  • Add global methods or properties. For example: ‘element’
  • Adding a Global Resource
  • Add some component options through global blending. For example vue – the router
  • Add vUE instance methods by adding them to vue. Prototype
  • A library that provides its own API and also provides one or more of the features mentioned above, such as vue-Router

Plug-in statement

Vue.js plug-ins should expose an install method. The first argument to this method is the Vue constructor, and the second argument is an optional option object:

MyPlugin.install = function (Vue, options) { // 1. Property vue.myGlobalMethod = function () {// Logic... {bind (el, binding, vnode, oldVnode) {// bind (el, binding, vnode, oldVnode) {// bind (el, binding, vnode, oldVnode) {// bind (el, binding, vnode, oldVnode) {// }... Mixin ({created: function () {// logic... }... $myMethod = function (methodOptions) {$myMethod = function (methodOptions) {$myMethod = function (methodOptions); }}Copy the code

Vue – use the cli

NPM install -g@vue /cli Creates a project using vue-clie.