36 tips for Vue development

Transferred from: Micro reading   https://www.weidianyuedu.com


This paper lists 36 vue development skills; Subsequent vue 3 After X comes out, it will be updated continuously


1. Scenario: if the page needs to import multiple components, the original writing method:

import titleCom from "@/components/home/titleCom"import bannerCom from "@/components/home/bannerCom"import cellCom from "@/components/home/cellCom"components:{titleCom,bannerCom,cellCom}

2. In this way, a lot of repeated code is written, using require Context can be written as

const path = require("path")const files = require.context("@/components/home", false, /\.vue$/)const modules = {}files.keys().forEach(key => {  const name = path.basename(key, ".vue")  modules[name] = files(key).default || files(key)})components:modules

In this way, no matter how many components are introduced into the page, you can use this method 3 API method

Actually webpack Method of,vue Engineering is generally based on webpack,So you can use require.context(directory,useSubdirectories,regExp)Receive three parameters:directory: Describe the directory to retrieve useSubdirectories: Whether to check the subdirectory regExp: Regular expressions that match files,Usually the file name


2.1 common usage 1 Scenario: the initial entry of the table needs to call the query interface getList(), and then the input will be changed to re query

created(){  this.getList()},watch: {  inpVal(){    this.getList()  }}

2.2 execute immediately 2 You can directly use the shorthand of the immediate and handler properties of watch

watch: {  inpVal:{    handler: "getList",      immediate: true  }}

2.3 deep monitoring 3 The deep attribute of watch is to listen deeply, that is, to listen for complex data types

watch:{  inpValObj:{    handler(newVal,oldVal){      console.log(newVal)      console.log(oldVal)    },    deep:true  }}

At this time, it is found that the values of oldVal and newVal are the same; Because they index the same object / array, Vue will not keep a copy of the value before modification; Therefore, although deep monitoring can monitor the changes of the object, it cannot monitor the changes of the attribute in the specific object

3. 14 component communication

3.1 props should be a special attribute, that is, the attribute passed from parent to child; Props value can be an array or object;

// Array: props: [] / / object props: {inpval: {type: number, / / pass in the value to limit the type. / / the value of type can be string, number, Boolean, array, object, date, function, symbol / / type can also be a user-defined constructor, and check through instanceof to confirm that required: true, / / whether default:200 must be passed, / / default value. The default value of object or array must be obtained from a factory function, such as default: () = > [] Validator: (value) {/ / this value must match a return ["success", "warning", "danger"]. Indexof (value)! = = - 1}}

3.2 $emit should also be very common. Triggering a child component to trigger an event that the parent component binds to itself is actually the way the child passes to the parent

// Parent component < home @ title = "title" > / / child component this$ Emit ("title", [{Title: "this is the title"}])

3.3 vuex1. This is also very common. Vuex is a state manager 2 It is an independent plug-in, which is suitable for projects with more data sharing, because if it is only simple communication, it will be more heavy to use. 3 API

state:Define the warehouse for storing data ,Can pass this.$store.state or mapState visit getter:obtain store value,Can be considered store Calculation properties of,Can pass this.$store.getter or       mapGetters visit mutation:Synchronous change store value,Why is it designed to be synchronous,because mutation It's a direct change store value,         vue The operation is recorded,If asynchronous, changes cannot be tracked.Can pass mapMutations call action:Asynchronous call function execution mutation,Then change store value,Can pass this.$dispatch or mapActions       visit modules:modular,If there are too many states,Can be split into modules,Finally pass at the entrance...Deconstruction introduction


listeners2.4.0 these two new attributes are not commonly used, but advanced usage is very common; one

attrs gets the value not defined in props in the child parent

// Parent component < home title = "this is the title" width = "80" height = "80" imgurl = "imgurl" / > / / child component mounted() {console.log (this. $attrs) / / {Title: "this is the title", width: "80", height: "80", imgUrl: "imgUrl"}},

Correspondingly, if the subcomponent defines props, the printed value is to eliminate the defined attributes

props: {  width: {    type: String,    default: ""  }},mounted() {  console.log(this.$attrs) //{Title: "this is the title", height: "80", imgUrl: "imgUrl"}},


listeners "pass in internal components -- useful when creating higher-level components

// Parent component < home @ change = "change" / > / / child component mounted() {console. Log (this. $listeners) / / you can get the change event}

If a child component wants to access the properties and calling methods of the parent component, it can be passed down directly level by level. 3 inheritAttrs

// Parent component < home title = "this is the title" width = "80" height = "80" imgurl = "imgurl" / > / / child component mounted() {console.log (this. $attrs) / / {Title: "this is the title", width: "80", height: "80", imgUrl: "imgUrl"}},inheritAttrs is true by default, True means to add the attributes other than props in the parent component to the root node of the child component (note that even if set to true, the child component can still obtain the unexpected attributes of props through $attr). After inheritAttrs:false, the attributes will not be displayed on the root node

3.5 provide and inject2 2.0 new description: provide and inject mainly provide use cases for high-level plug-in / component libraries. It is not recommended to use it directly in application code; And this pair of options need to be used together; To allow an ancestor component to inject a dependency into all its descendants, no matter how deep the component level is, and it will always take effect when the upstream and downstream relationship is established.

//Parent component: provide: {/ / provide is an object that provides an attribute or method foo: "this is foo", fooMethod: () = > {console.log ("parent component fooMethod is called")}}, / / child or grandson component input: ["foo", "fooMethod"], / / array or object, Injected into the child component mounted() {this. fooMethod() console. Log (this. Foo)} / / under the parent component, all child components can use inject

The provide and inject bindings are not responsive. This was deliberately done by the authorities. However, if you pass in an object that can listen, the properties of the object are still responsive because the object is a reference type

//Parent component: provide: {foo: "this is foo"}, mounted() {this. Foo = "this is a new foo"} / / child or grandson component: inject: ["foo"], mounted() {console. Log (this. Foo) / / whether the child component prints "this is Foo"}



children: sub instance

//The parent component mounted() {console.log (this. $children) / / can get the properties and methods of the first level child component / / so you can directly change the data or call the methods method} / / the child component mounted() {console.log (this. $parent) / / can get the properties and methods of the parent}

The parent does not guarantee the order, nor is it responsive. It can only get the first level parent and child components

3.7 $refs

// Parent component < home ref = "home" / > mounted() {console. Log (this. $refs. Home) / / you can get the instance of the child component and directly operate data and methods}

3.8 $root

// Parent component mounted() {console.log (this. $root) / / get the root instance. Finally, all components are mounted on the root instance console.log(this.$root.$children[0]) / / get the primary sub component console.log(this.$root.$children[0].$children[0]) of the root instance. / / get the secondary sub components of the root instance}

3.9 .sync in vue@1.x It used to exist as a two-way binding function, that is, the child component can modify the value in the parent component; In vue@2.0 Because of violating the design of single data flow, it was killed; In vue@2.3.0+ This is reintroduced in the above version sync modifier;

// Parent component < home: title Sync = "title" / > / / when compiling, it will be extended to < home: title = "title" @ update: title = "Val = > title = Val" / > / / subcomponents / / so subcomponents can trigger the update method through $emit to change mounted() {this. $emit ("update: title", "this is a new title")}

3.10 v-slot2.6.0 add 1 Slot, slot copy and scope are all discarded in 2.6.0, but not removed The function is to pass the template of the parent component into the child component 3 Slot classification: A. anonymous slot (also known as default slot): there is no name, and there is only one;

// Parent component < todo list > < template V-slot: default > any content < p > I am an anonymous slot < / P > < / template > < / todo list > / / sub component < slot > I am the default value < / slot > / / V-slot: default. The writing feeling and naming writing method are relatively unified, easy to understand, and you can not write

B. Named slot: the slot tag of the relative anonymous slot component is named with name;

// Parent component < todo list > < template V-slot: todo > any content < p > I am anonymous slot < / P > < / template > < / todo list > / / sub component < slot name = "todo" > I am the default value < / slot >

C. Scope slot: the data in the sub component can be obtained by the parent page (solves the problem that the data can only be passed from the parent page to the sub component)

// Parent component < todo list > < template v-slot:todo = "slotProps" > {slotProps. User. Firstname}} < / template > < / todo list > / / slotProps can be named at will / / slotProps receives the collection of attribute data on the sub component label slot. All v-bind:user="user" / / sub components < slot name = "todo": user = "user": test = "test" > {user. LastName}} < / slot > data() {return {user: {LastName: "Zhang", firstname: "Yue"}, test: [1,2,3,4]}, / / {user. LastName}} is the default data. v-slot:todo is not used as the parent page (= "slotProps")

3.11 EventBus1. It is to declare a global Vue instance variable eventbus and store all communication data and event listening on this variable; 2. Similar to Vuex. But this method is only applicable to very small projects 3 The principle is to use

emit and instantiate a global vue to realize data sharing

// In main jsVue. prototype.$ Eventbus = new vue() / / value transfer component this$ eventBus.$ Emit ("eventTarget", "this is the value passed from eventTarget") / / receive the component this$ eventBus.$ On ("eventTarget", v = > {console. Log ("eventTarget", V); / / this is the value passed from eventTarget})

4. Horizontal and nested components can pass values, but the corresponding event name eventTarget must be globally unique

3.12 broadcast and dispatchvue 1 X has two methods, event broadcast and dispatch, but Vue 2 X removes the following encapsulation of the two methods

function broadcast(componentName, eventName, params) {  this.$children.forEach(child => {    var name = child.$options.componentName;    if (name === componentName) {      child.$emit.apply(child, [eventName].concat(params));    } else {      broadcast.apply(child, [componentName, eventName].concat(params));    }  });}export default {  methods: {    dispatch(componentName, eventName, params) {      var parent = this.$parent;      var name = parent.$options.componentName;      while (parent && (!name || name !== componentName)) {        parent = parent.$parent;        if (parent) {          name = parent.$options.componentName;        }      }      if (parent) {        parent.$emit.apply(parent, [eventName].concat(params));      }    },    broadcast(componentName, eventName, params) {      broadcast.call(this, componentName, eventName, params);    }  }}

3.13 routing parameters 1 Scheme I

// Route definition {path: "/ describe /: Id", name: "describe", component: describe} / / the page refers to this$ router. Push ({path: ` / describe / ${ID} `,}) / / get this page$ route. params. id

2. Programme II

// Route definition {path: "/ describe", name: "describe", component: describe} / / the page passes this$ router. Push ({Name: "describe", params: {ID: ID}}) / / get this page$ route. params. id

3. Programme III

// Route definition {path: "/ describe", name: "describe", component: describe} / / the page passes this$ router. Push ({path: "/ describe", query: {ID: ID `}) / / get this on the page$ route. query. id

4. Comparison of the three schemes. The parameters of scheme 2 will not be spliced behind the route, and the page refresh parameters will be lost. The parameters of scheme 1 and scheme 3 are spliced behind, ugly and exposed information

3.14 Vue.observable2.6.0 new usage: make an object responsive. Vue will use it internally to handle the objects returned by the data function; The returned objects can be directly used in rendering functions and calculation attributes, and will trigger corresponding updates when changes occur; It can also be used as a minimized cross component state memory for simple scenarios. The communication principle is essentially the use of Vue Observable implements a simple vuex

// File path - / store / store jsimport Vue from "vue"export const store = Vue. Observable ({count: 0}) export const variations = {setcount (count) {store. Count = count}} / / use < template > < div > < label for = "booknum" > quantity < / label > < button @ Click = "setcount (count + 1)" > + < / button > < span > {count} < / span > < button @ Click = "setcount (count-1)" >-</button>    </div></template><script>import { store, mutations } from "../store/store" // Vue2. 6. Add API observableexport default {Name: "add", calculated: {count() {return store. Count}}, methods: {setcount: variations. Setcount} < / script >

4. render function

The function render is used in many scenarios

// Tags are being made on the basis of the Propps that make the tag from the props at the start of the process at the start of the tag / /atthe primary < template < template > < div < div < div < < slot > / slot > < / div > < a v-else-if-if = "level = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = 11" < a sort of the sort that's a sort of the sort that's a sort that makes it a sort of a sort of a sort of a sort of a sort of a sort of a sort of a sort of a sort of a sort of a sort of a sort of a sort of a sort of a sort of a tag if if = "level = = = = = = = = = = = 1" > < or a sort of a sort of a sort of a sort of a sort of a sort of a sort of a sort of a sort of a sort of a sort of sort of a sort of a sort of a sort of a sort of sort of sort of= = 6 " >< slot > < / slot > < / textarea > < / div > < / template > / / the optimized version uses the render function to reduce the code repetition rate < template > < div > < child: level = "level" > Hello world</ child>  </div></template><script type="text/javascript">  import Vue from "vue"  Vue. component("child", {    render(h) {      const tag = ["div", "p", "strong", "h1", "h2", "textarea"][this.level-1]      return h(tag, this.$slots.default)    },    props: {      level: {  type: Number,  required: true  }    }  })  export default {    name: "hehe",    data() { return { level: 3 } }  }</script>

2. Comparison between Render and template: the former is suitable for complex logic, while the latter is suitable for simple logic; The latter belongs to the declaration of rendering, and the former belongs to the custom Render function; The former has higher performance and the latter has lower performance.

5. Asynchronous component

Scenario: too large a project will lead to slow loading, so asynchronous components must be loaded on demand. 1 Three methods of asynchronously registering components

// The factory function executes the resolve callback Vue Component ("async webpack example", function (resolve) {/ / this special 'require' syntax will tell webpack / / automatically cut your build code into multiple packages. These packages / / will load require ([". / my async component"], resolve)}) through Ajax request / / the factory function returns promisevue Component ("async webpack example", / / the 'import' function will return a 'Promise' object. () = > Import (". / my async component") / / the factory function returns a configured component object const asynccomponent = () = > ({/ / the component to be loaded (it should be a 'Promise' object) component: import("./MyComponent.vue") , / / component used during asynchronous component loading: LoadingComponent, / / component used when loading fails error: ErrorComponent, / / shows the delay time of the component during loading. The default value is 200 (milliseconds) delay: 200, / / if the timeout is provided and the component loading also times out, / / the component used when the loading fails is used. The default value is: ` infinity ` timeout: 3000})

In essence, the rendering of asynchronous components is to render two or more times. First render the current component as an annotation node. When the component is loaded successfully, re render it through forceRender. Or render it as an annotation node, and then render it as a loading node, and then render it as a component 2 On demand loading of routes

webpack< 2.4 Time{  path:"/",  name:"home",  components:resolve=>require(["@/components/home"],resolve)}webpack> 2.4 Time{  path:"/",  name:"home",  components:()=>import("@/components/home")}import()Method by es6 Put forward, import()The method is dynamic loading and returns a Promise Object, then Method is the module loaded into. be similar to Node.js of require Method, main import()Methods are loaded asynchronously.

6. Dynamic component

Scenario: dynamic loading of components will be involved when making a tab switch

<component v-bind:is="currentTabComponent"></component>

But in this way, the components will be reloaded every time, which will consume a lot of performance, so it works

<keep-alive>  <component v-bind:is="currentTabComponent"></component></keep-alive>

In this way, the switching effect has no animation effect. There is no need to worry about this. You can use the built-in

<transition><keep-alive>  <component v-bind:is="currentTabComponent"></component></keep-alive></transition>

7. Recursive component

Scenario: if a tree component is developed, its level is determined according to the background data, and dynamic components are needed at this time

// Recursive component: the component can call itself recursively in its template. Just set the name component to the component// If set, House can be used recursively in the component template. However, it should be noted that / / a condition must be given to limit the number, otherwise an error will be thrown: max stack size exceeded / / component recursion is used to develop some independent components with unknown hierarchical relationship. For example: / / cascade selector and tree control < template > < div V-for = "(item, index) in treearr" > subcomponents, current level value: {index}} < br / > <-- Recursively call itself, and the background judges whether there is no value change -- > < tree: item = "item. Arr" V-IF = "item. Flag" > < / tree > < / div > < / template > < script > export default {/ / name must be defined before recursively Calling Name: "tree", data() {return {}} inside the component, //Receive external incoming value props: {item: {type: array, default: () = > []}}} < / script >

Recursive components must set thresholds for name and end

8. Functional component

Definition: stateless, cannot be instantiated, and there is no internal life cycle processing method rule: in versions before 2.3.0, if a functional component wants to receive prop, the props option is required. In version 2.3.0 or above, you can omit the props option, and the features on all components will be automatically and implicitly resolved to prop. In version 2.5.0 or above, if you use a single file component (that is, an ordinary. vue file), you can directly declare the functional component on the template. Everything you need is passed through the context parameter. The context attribute is as follows: 1 Props: provide objects of all props 2 Children: array of vnode child nodes 3 Slots: a function that returns an object containing all slots 4 Scopedslots: (2.6.0 +) an object that exposes the incoming scope slot. Ordinary slots are also exposed in the form of functions. 5.data: the entire data object passed to the component, which is passed into the component as the second parameter of createElement 6 Reference to parent component: 7.7 Listeners: (2.3.0 +) an object that contains all event listeners registered by the parent component for the current component. This is data An alias for on. 8.injections: (2.3.0 +) if the inject option is used, the object contains the attributes that should be injected

<template functional>  <div v-for="(item,index) in props.arr">{{item}}</div></template>

9. components and Vue component

Components: locally registered components

export default{  components:{home}}

Vue.component: global registration component



Scenario: some vue components need to mount some elements to the elements. At this time, extend plays a role. It is the syntax of constructing a component:

// Create constructor var profile = Vue Extend ({template: "< p > {extenddata}} < / BR > the data passed in by the instance is: {propextend}} < / P >", / / the outermost layer of the label corresponding to the template must have only one label data: function() {return {extenddata: "this is the data extended by extend",}}, props: ["propextend"]}) / / the created constructor can be attached to the element or through components or Vue Component () is registered and used / / to mount to an element. Parameters can be passed through propsData New profile ({propsData: {propextend: "I am the data passed in by the instance"}})$ Mount ("#app extend") / / via components or Vue Component() registers Vue component("Profile",Profile)


Scenario: some components have some duplicate js logic, such as checking the mobile phone verification code, parsing time, etc. mixins can realize this mixing. The mixins value is an array

const mixin={    created(){      this.dealTime()    },    methods:{      dealTime(){        console.log("This is mixin of dealTime Inside method");      }  }}export default{  mixins:[mixin]}


The usage of extensions is very similar to mixins, except that the parameters received are simple option objects or constructors, so extensions can only extend one component at a time

const extend={    created(){      this.dealTime()    },    methods:{      dealTime(){        console.log("This is mixin of dealTime Inside method");      }  }}export default{  extends:extend}


Scenario: when using element, we will first import and then Vue Use (), in fact, is to register the component and trigger the install method; This is often used in component calls; It will automatically organize to register the same plug-in multiple times


Scenario: in Vue Use () says that executing this method will trigger install, which is a plug-in for developing Vue. The first parameter of this method is Vue constructor, and the second parameter is an optional option object (optional)

var MyPlugin = {};  MyPlugin.install = function (Vue, options) {    // 2. Add global resources. The second parameter passes a value. The default value is Vue corresponding to update Directive ("click", {bind (EL, binding, vnode, oldvnode) {/ / prepare for binding and add time to listen to console.log("the bind of my directive has been executed");}, inserted: function(el) {/ / get the bound element console.log("the inserted instruction of my directive has been executed");}, update: function() {/ / execute the corresponding update according to the obtained new value / / for the initial value, call console.log("update of my directive is executed");}, componentUpdated: function() {console.log("componentUpdated of my directive has been executed");}, unbind: function() {/ / clean up / / for example, the event listener console.log bound when removing bind ("unbind of my directive executed");}})// 3. Injection assembly Vue Mixin ({created: function() {console.log("created of the injected component has been called"); console.log("the value of options is", options)}}) / / 4 Add instance method Vue prototype.$ myMethod = function (methodoptions) {console.log("instance method myMethod called");}}// Call myplugin Vue use(MyPlugin,{someOption: true })  //3. Mount new Vue ({El: "#app"}); Author: fire wolf 1 link: https://juejin.im/post/5d9d386fe51d45784d3f8637 Source: the copyright of nuggets belongs to the author. For commercial reprint, please contact the author for authorization. For non-commercial reprint, please indicate the source.

For more information, please stamp several operations of extend, mixins, extends, components and install in vue

15, Vue.nextTick

2.1.0 new scenario: the text box needs to get the focus when the page is loaded. Usage: execute delayed callback after the next DOM update cycle. Use this method immediately after modifying the data to get the updated dom

mounted(){ //Because the dom in the mounted stage is not rendered, you need $nexttick this$ Nexttick (() = > {this. $refs. Inputs. Focus() / / get dom through $refs and bind the focus method})}


16.1 usage scenario: the official has provided us with many instructions, but if we want to change the text into a specified color to define the use of instructions, we need to use Vue directive

// Global definition Vue directive("change-color",function(el,binding,vnode){  el.style["color"]= binding.value;})//  Use < template > < div v-change-color = "color" > {message}} < / div > < / template > < script > export default {data() {return {color: "green"}}} < / script >

16.2 life cycle 1 Bind is called only once. It is called when the instruction is bound to the element for the first time. This hook can be used to define an initialization action to be performed once when binding. 2.inserted: called when the bound element is inserted into the parent node (it can be called if the parent node exists, and it does not have to exist in the document) 3 Update: called when the bound template is updated with the template where the element is located. No matter whether the binding value changes or not, by comparing the binding values before and after the update, unnecessary template updates are ignored. 4 Componentupdate: called when the template of the bound element completes an update cycle Unbind: called only once, when the instruction month element is unbound


Scenario: time stamp is converted to month, year and day. This is a public method, so it can be extracted and used as a filter

// Use / / in double curly brackets {{message | capitalize}} / / in 'v-bind' < div v-bind: id = "rawid | formatid" > < / div > / / register Vue globally Filter ("stamptoyymmdd", (value) = > {/ / processing logic}) / / local registration of filters: {stamptoyymmdd: (value) = > {/ / processing logic} / / global registration of multiple filters / / / SRC / common / filters jslet dateServer = value => value. replace(/(\d{4})(\d{2})(\d{2})/g, "$1-$2-$3")export { dateServer }// /src/main. jsimport * as custom from "./common/filters/custom"Object. keys(custom). forEach(key => Vue.filter(key, custom[key]))


Scenario: compile template string in render function. Valid only when built independently

var res = Vue.compile("<div><span>{{ msg }}</span></div>")new Vue({  data: {    msg: "hello"  },  render: res.render,  staticRenderFns: res.staticRenderFns})


Scenario: some development plug-ins need to be compatible with different vue versions, so vue will be used Version usage: vue Version() can get the vue version

var version = Number(Vue.version.split(".")[0])if (version === 2) {  // Vue v2.x.x} else if (version === 1) {  // Vue v1.x.x} else {  // Unsupported versions of Vue}


Scenario: when you use the index to directly set an array item or when you modify the length of the array, due to object The defineprototype () method limits that the data is not updated in response, but Vue 3. X will use proxy to solve this problem:

// Use setthis$ Set (arr, index, item) / / use the array push(),splice()


Scene: custom key modifier alias

// Define key code 113 as f2vue config. keyCodes. f2 = 113;< input type="text" @keyup. f2="add"/>


Scenario: monitoring performance

Vue.config.performance = true

Only applicable to development mode and support performance Mark API browser


1. Scene: handler function that does not catch errors during rendering and observation of specified components 2 Rule: from 2.2.0, this hook will also catch errors in the component life cycle hook. Similarly, when the hook is undefined, the captured error will pass through the console Error output to avoid application crash. From 2.4.0, this hook will also catch the internal errors of Vue custom event handler. From 2.6.0, this hook will also catch the internal errors thrown by v-on DOM listener. In addition, if any overridden hook or processing function returns a Promise chain (such as async function), the error from its Promise chain will also be processed 3 use

Vue.config.errorHandler = function (err, vm, info) {  // Handle error / / ` info ` is Vue specific error information, such as the life cycle hook / / only available in 2.2.0 +}


2.4.0 add 1 Scenario: assign a custom processing function to Vue's runtime warning, which will only take effect in the developer environment. 2 Usage:

Vue.config.warnHandler = function (msg, vm, trace) {  // `Trace ` is the inheritance relationship trace}


Scenario: vue is a responsive system, but some static tags do not need to be compiled multiple times, which can save performance

<span v-pre>{{ this will not be compiled }}</span>   It shows{{ this will not be compiled }}<span v-pre>{{msg}}</span>     even if data It defines msg It is still shown here{{msg}}


Scene: in the case of slow network speed, when using vue to bind data, variable flicker will appear when rendering the page. Usage: this instruction remains on the element until the associated instance finishes compiling. When used with CSS rules such as [v-cloak] {display: none}, this instruction can hide the uncompiled Mustache tag until the instance is ready

// template < div class = "#app" v-cloak > < p > {{value. Name}} < / P > < / div > / / CSS [v-cloak] {display: none;}

In this way, flickering can be solved, but a white screen will appear, which can be used in combination with the skeleton screen


Scene: some static DOMS in the template have not changed, so you only need to render once, which can reduce the performance overhead

<span v-once> At this time, you only need to load the label once</span>

The difference between v-once and v-pre: v-once only renders once; V-pre does not compile and outputs as is

28. Event modifier

.stop:Stop bubbling.prevent:Block default behavior.self:Triggered only by the binding element itself.once: 2.1.4 newly added,Trigger only once.passive: 2.3.0 newly added,Default behavior for scrolling events (Rolling behavior) Will be triggered immediately,Not with.prevent Use together

29. Key modifier and key code

Scenario: sometimes it is necessary to monitor the behavior of the keyboard, such as pressing enter to query the interface, etc

// Corresponding to the keyword on the keyboard enter.tab.delete (capture the "delete" and "backspace" keys) esc.space.up.down.left.right


Scenario: Vue router is an official routing plug-in

30.1 caching and animation 1 Routing is the use of the official component Vue router. I believe you are very familiar with the use method; 2. Here I will describe the cache and animation of routing; 3. You can use exclude (except) or include (including), and add 2.1.0 to judge

<transition>  <keep-alive :include="["a", "b"]">  //Or include = "a, b": include = "/ a | b /", a and b represent the name of the component / / because some pages, such as trying data statistics, need to be refreshed in real time, there is no need to cache < router view / > / / routing tag < / keep alive > < router view exclude = "C" / > / / C represents the name value of the component < / transition >

Note: first, check the name option of the component itself. If the name option is unavailable, match its local registered name (the key value of the parent component components option). Anonymous components cannot be matched 4 Judging by v-if, the component will be re rendered, but there is no need to list the component names one by one

30.2 global routing hook 1 router. beforeEach

router.beforeEach((to, from, next) => {  console.log("Global front guard: beforeEach -- next Need to call") //This is commonly used for login interception, also known as navigation hook guard if (path = = = "/ login") {next() return} if (token) {next();})

2.router.beforeResolve (v 2.5.0+) is similar to beforeEach. The difference is that before the navigation is confirmed, at the same time, after guarding and asynchronous routing components are parsed in all components, the guard is invoked, that is, calling 3. after beforeEach. router. After each global post hook is called at the end of all route jumps. These hooks will not accept the next function and will not change the navigation itself

30.3 component routing hook 1 BeforeRouteEnter calls before the corresponding routing of the component is rendered, usage and parameters and router. Similar to beforeeach, next needs to be actively called. At this time, the component instance has not been created and cannot access this. You can access the component instance by passing a callback to next. Execute the callback when the navigation is confirmed, and take the component instance as the parameter of the callback method

beforeRouteEnter (to, from, next) {  // This = = = undefined next (vm = > {/ / access component instance through 'vm'})}

2.beforeRouteUpdate (v 2.2 +) is called when the current route is changed and the component is reused. You can access the instance through this. The next needs to be actively called and cannot send a callback. 3 Beforeroutleave is called when the navigation leaves the corresponding route of the component. You can access the component instance this. The next needs to be actively called and cannot send a callback

30.4 routing mode setting mode attribute: hash or history

30.5 Vue.$router

this.$router.push():Jump to a different url,But this method goes back history Add a record to the stack. Click back to return to the previous page this.$router.replace():There will be no record this.$router.go(n):n Can be positive or negative. A positive number returns to the previous page,similar window.history.go(n)

30.6 Vue.$route indicates the route object that is currently skipped. The attributes are: Name: route name path: path query: pass parameter receive value params: pass parameter receive value fullPath: URL after parsing, complete path including query parameters and hash matched: copy of route record redirectedFrom: if there is redirection, it is the name of the route from which the redirection originates

this.$route.params.id:Get through params or/:id Parameters of parameter transmission this.$route.query.id:Get through query Parameters of parameter transmission

30.7 router view key scenario: because Vue will reuse the same components, i.e. / page / 1 = > / page / 2 or / page? id=1 => /page? When a link with id = 2 jumps, hooks such as created and mounted will not be executed

<router-view :key="$route.fullPath"></router-view>

In this way, both created and mounted components will be executed


Scenario: a long list of data will not be changed, but vue will do the conversion of getter and setter. Usage: it is a new feature in ES5, which can freeze an object to prevent it from being modified. Support: vue 1.0.18 + provides support for it. For objects frozen by using free in data or vuex, vue will not do the conversion of getter and setter. Note: freezing only freezes a single attribute in it, The reference address can still be changed

new Vue({    data: {        // vue will not bind the objects in the list with getter s and setter s Free ([{value: 1}, {value: 2}])}, mounted() {/ / the interface will not respond because a single attribute is frozen. this.list[0].value = 100; / / the interface will respond to this. List = [{value: 100}, {value: 200}] in the following two methods; this. list = object. freeze([            { value: 100 },            { value: 200 }        ]);    }})

32. Debug template

Scenario: in the process of Vue development, you often encounter the problem of JavaScript variable error during template rendering. At this time, you may use console Log to debug. At this time, you can mount a log function in the development environment

// main.jsVue.prototype.$log = window.console.log;//  Component internal < div > {{$log (info)}} < / div >

33. Vue loader tips

33.1 preserveWhitespace scenario: the development vue code usually has spaces. At this time, if the spaces are not removed, the volume of the package will be increased. Configuring preserveWhitespace can reduce the volume of the package

{  vue: {    preserveWhitespace: false  }}

33.2 transformto require scenario: in the past, when writing Vue, we often wrote such code: pass the picture to a variable in advance and then to the component

// page code < template > < div > < Avatar: IMG SRC = "imgsrc" > < / avatar > < / div > < / template > < script > export default {created() {this. Imgsrc = require (". / assets / default avatar. PNG")} < / script >

Now: after you configure transformToRequire, you can configure it directly. In this way, Vue loader will automatically require the corresponding attributes and then pass them to the component

// vue-cli 2.x in Vue loader Conf.js the default configuration is transformToRequire: {Video: ["SRC", "poster"], source: "SRC", IMG: "SRC", image: "Xlink: href"} / / configuration file. If it is vue-cli2 X in Vue loader Modify avatar in conf.js: [default SRC] / / Vue cli 3 X in Vue config. js// vue-cli 3. X change the transformToRequire attribute to transformasseturlsmodule exports = {  pages,  chainWebpack: config => {    config      .module        .rule("vue")        .use("vue-loader")        .loader("vue-loader")        .tap(options => {      options.transformAssetUrls = {        avatar: "img-src",      }      return options;      });  }}//  The page code can be simplified to < template > < div > < avatar img SRC = ". / assets / default avatar. PNG" > < / avatar > < / div > < / template >

34. Set alias for path

1. Scenario: in the development process, we often need to introduce various files, such as pictures, CSS, JS, etc. in order to avoid writing long relative paths (.. /), we can configure an alias for different directories. 2 vue-cli 2. X configuration

// On webpack base. config. For the resolve configuration item in JS, add the alias resolve: {extensions: [". JS", ". Vue", ". JSON"], alias: {Vue $":" Vue / dist / Vue. ESM. JS ", @: Resolve (" SRC "),}},

3.vue-cli 3.x configuration

// Create vue.exe in the root directory config. jsvar path = require("path")function resolve (dir) {  console.log(__dirname)  return path.join(__dirname, dir)}module. Exports = {chainwebpack: config = > {config.resolve.alias. Set (key, value) / / key and value are self-defined, such as. set("@@", resolve("src/components"))}}

35. img loading failed

Scene: sometimes the picture address returned from the background may not be opened, so a default picture should be added at this time

// page code < img: SRC = "imgurl" @ error = "handleerror" ALT = "" > < script > export default {data() {return {imgurl: ""}}, methods: {handleerror (E) {e.target. SRC = reqiure ("image path") / / of course, if the project is configured with transformToRequire, refer to 27.2}} < / script >


36.1 local style 1 The scoped attribute of the style tag in Vue indicates that its style only works on the current module, which is style privatization. 2 Rendering rule / principle: add a non repeated data attribute to the DOM node of HTML to represent uniqueness, and add a data attribute selector of the current component at the end of the corresponding CSS selector to privatize the style, such as: demo[data-v-2311c06a]{} if less or sass is introduced, it will only be set on the last element

// Original code < template > < div class = "demo" > < span class = "content" > Vue js scoped    </span>  </div></template><style lang="less" scoped>  . demo{    font-size: 16px;    .content{      color: red;    }  }</ Style > / / browser rendering effect < div data-v-fed36922 > Vue js scoped</div><style type="text/css">. demo[data-v-039c5b43] {  font-size: 14px;}. demo . Content [data-v-039c5b43] {/ /. Demo does not add data attribute color: red;}</ style>

36.2 deep attribute

// Add a style = "scoped /. Eples" / > above demo{    font-size: 14px;  }  . demo /deep/ . content{    color: blue;  }</ Style > / / browser compiled < style type = "text / CSS" > demo[data-v-039c5b43] {  font-size: 14px;}. demo[data-v-039c5b43] . content {  color: blue;}</ style>


The codeword is not easy. Welcome to like it and forward it

Keywords: Javascript Front-end Programming Vue.js

Added by james182 on Sat, 26 Feb 2022 07:16:38 +0200