preface

Pre-alpha version of Vue 3.x. There will be an Alpha, Beta, and so on, and the 3.0 release is not expected until at least the first quarter of 2020. Therefore, we should step up to lay a good foundation for Vue2. Vue basic usage is easy to get started, but there are many optimized writing method you may not know, this article from the list of 36 Vue development skills; The follow-up Vue 3.x will be updated continuously.

1.require.context()

1. Scenario: If multiple components need to be imported to the page, the original writing method is:

import titleCom from '@/components/home/titleCom'
import bannerCom from '@/components/home/bannerCom'
import cellCom from '@/components/home/cellCom'
components:{titleCom,bannerCom,cellCom}
Copy the code

2. This is a lot of repetitive code, which can be written using require.context

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

This method can be used no matter how many components are introduced into the page

3. The API method

Is actually a webpack method, vue engineering based on webpack commonly, so you can use the require. The context (directory, useSubdirectories, regExp) receiving three parameters: Directory: specifies the directory to be searched. UseSubdirectories: Specifies whether to search subdirectories. RegExp: Specifies the regular expression of the matching file, usually the file nameCopy the code

2.watch

2.1 Common Usage

1. Scenario: When the table comes in initially, the query interface getList() needs to be queried, and then the input changes will be queried again

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

2.2 Immediate Execution

2. You can use the immediate and handler properties of watch

watch: {
  inpVal:{
    handler: 'getList',
      immediate: true
  }
}
Copy the code

2.3 Deep monitoring

3. The deep property of watch, that is, listening on complex data types

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

OldVal is the same as newVal; Because they index the same object/array,Vue does not keep a copy of the previous value; So although deep listening can listen to the change of the object, but can not listen to the change of the property in the specific object

3. Communication of 14 components

3.1 props

This is supposed to be a very special property, which is a parent to child property; Props can be an array or object;

Props :[] // Object props:{inpVal:{type:Number, / / / / incoming value limit type type value can be a String, Number, Boolean, Array, Object, the Date, the Function, the Symbol / / type can also be a custom constructor, And check with instanceof to confirm required: Default :200, // the default value, object or array must be obtained from a factory function such as default:()=>[] validator:(value) {// this value must match one of the following strings return ['success', 'warning', 'danger'].indexOf(value) ! == -1}}Copy the code

3.2 $emit

This should also be very common, triggering the child component to trigger the event that the parent component bound to itself is the child to the parent method

/ / parent component < home @ title = "title" > / / subcomponents enclosing $emit (' title ', [{title: 'this is the title'}])Copy the code

3.3 vuex

This is also very common. Vuex is a state manager. 2

$store.state or mapState to access the getter: To get the value of the store, which can be considered as a calculated property of the store, through this MapGetters access mutation: synchronously changes the store value. Why is it designed to be synchronous? Because mutation changes the store value directly, vUE records the operation and cannot track the change if it is asynchronous. Action is called through mapMutations: the mutation is invoked asynchronously to change the store value, which can be accessed through this.$Dispatch or mapActions Modules: If there are too many states, you can split them into modules. The introduction of deconstructionCopy the code

3.4
a t t r s and Attrs and
listeners

These two attributes are not commonly used, but advanced usage is common; 1. Attrs scenario: If the parent child has many values, the child component needs to define multiple props (attrs) : if the parent has many props, then the child component needs to define multiple props. (attrs) : Gets the props that are not defined in the parent

Mounted () {console.log(this.$attrs) //{title: // <home title=" width="80" height="80" imgUrl="imgUrl"/> "Width: this is the title", "80", height: "80", imgUrl: "imgUrl"}},Copy the code

Correspondingly, if the child component defines props, the printed value is the property that is removed

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

2. Listeners: The child component needs to call the method of the parent component to resolve the problem: the method of the parent component can be solved by using v−on=” Listeners “Scenario: The child component needs to call the method of the parent component to solve the problem: the parent component can be solved by using the method of the parent component V-on =” Listeners “Scenario: Child components need to call methods from parent components: Methods from parent components are passed in to internal components via V −on=” Listeners” — useful when creating higher-level components

// Parent < home@change =" listeners "/ / parent < home@change =" listeners "/ / Parent < home@change =" listeners "/ / Parent < home@change =" listeners "/ / Parent < home@change =" listeners "/ / Parent < home@change =" listeners "/ / Parent < home@change =" listeners"Copy the code

If a grandchild wants to access properties and call methods of the parent, it can be passed down to the parent

3.inheritAttrs

Mounted () {console.log(this.$attrs) //{title: // <home title=" width="80" height="80" imgUrl="imgUrl"/> ImgUrl = 1; width: 80; height: 80; "ImgUrl "}}, the default value of inheritAttrs is true, where true means to add the properties of the parent component to the root node of the child component (except props). A child component can still obtain the props attribute using $attr. After inheritAttrs:false, the attribute will not be displayed on the root nodeCopy the code

3.5 dojo.provide and inject

2.2.0 New description: provide and Inject mainly provide use cases for high-level plug-ins/component libraries. Not recommended for use directly in application code; And these 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, for as long as the upstream and downstream relationships are established.

// Parent: provide: {//provide is an object that provides a property or method foo: 'This is foo', fooMethod:()=>{console.log(' parent component fooMethod is called ')}}, // child or grandson component inject: ['foo','fooMethod'], // Array or object, inject into child component mounted() {this.foomethod () console.log(this.foo)} // All child components under the parent component can utilize injectCopy the code

Provide and Inject bindings are not responsive. This is official. However, if you pass in an object that can be listened to, then the object’s properties are still responsive because the object is a reference type

// parent component: provide: {foo: 'this is foo'}, mounted(){this.foo=' this is new foo'} // child or grandson component inject: ['foo'], mounted() {console.log(this.foo)}Copy the code

Provide and inject response methods

// Parent provide() {return {staticValue: this.staticValue, // Returns a value directly, not responding to staticObject: This.staticobject, // returns an object that responds to getReactiveValue: () => this.staticValue // returns an object that responds to getReactiveValue: () => this.staticValue // returns an object that responds to getReactiveValue}}, // subcomponent inject: ["staticValue", "getReactiveValue", "staticObject"], computed: { reactiveValue() { return this.getReactiveValue(); // Return an injected object function that evaluates properties to listen for changes in value},},Copy the code

So provide returns an object or function that can respond, because the object and function are reference types, and the actual change is not done by vue, but by JS’s reference type properties

3.6
p a r e n t and The parent and
children

Parent: parent instance parent: parent instance children: child instance

// parent (){console.log(this.$children)} // Parent (){console.log(this.$children)} // Parent (){console.log(this.$children)} // Parent (){console.log(this.$children)} Console. log(this.$parent) // get the parent properties and methods}Copy the code

Children and children do not guarantee order, and are not responsive to getting only level 1 parent and child components

3.7 $refs

// parent <home ref="home"/> mounted(){console.log(this.$refs.home)} // Parent <home ref="home"/> mounted(){console.log(this.$refs.home)}Copy the code

3.8 $root

Mounted (){console.log(this.$root.$children[0]); // Mount (){console.log(this.$root.$children[0]) $children[0].$children[0].$children[0].Copy the code

3.9. The sync

At [email protected], it is used as a bidirectional binding function, that is, the child component can change the value in the parent component; – one at [email protected] was killed for violating the single data stream design; The.sync modifier has been reintroduced in versions above [email protected]+;

// Parent <home :title.sync="title" /> // will be extended to <home :title="title" @update:title="val => title= val"/> // child // Mounted (){this.$emit("update:title", 'this is the new title')} $emit("update:title",' this is the new title')}Copy the code

3.10 v – slot

1. Slot,slot-cope and scope are deprecated in 2.6.0, but not removed 2. Pass the template from the parent component to the child component. Anonymous slots (also called default slots): there is no name, but only one;

// Parent component <todo-list> <template v-slot:default> Anything <p> I am the anonymous slot </p> </template> </todo-list> // child component <slot> I am the default </slot> //v-slot:default; //v-slot:defaultCopy the code

B. Named slot: the slot label of a relatively anonymous slot component is named by name.

// Parent component <todo-list> <template v-slot:todo> Any content <p> I am anonymous slot </p> </template> </todo-list> // child component <slot Name ="todo"> I am the default </slot>Copy the code

C. Scope slots: Data in the child can be accessed by the parent page (resolved that data can only be passed from the parent page to the child)

// </todo-list> <template v-slot:todo="slotProps" > {{slotProps.user.firstName}} </template> </todo-list> //slotProps V -bind:user="user" // subcomponent <slot name="todo" :user="user" :test="test"> {{ }} </slot> data() {return {user:{lastName:"Zhang", firstName:"yue"}, test:[1,2,3,4]}}, // {{user.lastname}} is the default data v-slot:todo when the parent page does not have (="slotProps")Copy the code

3.11 EventBus

1. Declare a global Vue instance variable EventBus, and store all communication data and event listeners in this variable; 2. Similar to Vuex. However, this method is only suitable for very small projects. 3. The principle is to use on and on and on and emit and instantiate a global VUE for data sharing

$eventbus. $emit('eventTarget',' this is the value passed by eventTarget') // emit(' this is the value passed by eventTarget' this.$eventBus.$on("eventTarget",v=>{ console.log('eventTarget',v); // This is the value passed by eventTarget})Copy the code

4. You can achieve flat, nested component value passing, but the corresponding event name eventTarget must be globally unique

3.12 broadcast and dispatch

Vue 1.x has these 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); }}}Copy the code

3.13 Route transmission Parameters

1. One way

{path: '/describe/:id', name: 'describe ', component: describe} ` / go / ${id} `,}) / / page for this. $route. Params. IdCopy the code

2. 2

{path: '/describe', name: 'describe', component: describe}} 'Describe', params: {id: id}}Copy the code

3. Three

{path: '/describe', name: 'describe', component: describe}} '/describe', query: {id: id '}Copy the code

4. Comparison of the three schemes Parameter 2 of scheme 2 will not be spliced after the route, and the page refresh parameter will be lost. Parameter 1 and parameter 3 of scheme 1 will be spliced after the route, which is ugly and exposes information

3.14 the Vue. Observables

2.6.0 New usage: make an object responsive. Vue internally uses this to process objects returned by the data function; The returned objects can be used directly in rendering functions and computational properties, and are updated when changed; It can also be used as a minimal cross-component state store for simple scenarios. The communication principle is to implement a simple VUEX using Vue.Observable

Import Vue from 'Vue' export const store = Vue. Observable ({count: 5}) export const mutations = {setCount (count) {store.count = count}} // Use <template> <div> <label for="bookNum"> <span style =" box-sizing: border-box; color: RGB (93, 93, 93); line-height: 20px; font-size: 13px! Important; white-space: normal; @click="setCount(count-1)">-</button> </div> </template> <script> import { store, mutations } from '.. // Vue2.6 new API Observable export default {name: 'Add', computed: { count () { return store.count } }, methods: { setCount: mutations.setCount } } </script>Copy the code

4. The render function

1. Scenario: Some code is written in a template that is too repetitive, so render is useful

/ / label / / was generated according to props primary < template > < div > < div v - if = "level = = = 1" > < slot > < / slot > < / div > < p v - else - if = "level = = = 2" > <slot></slot> </p> <h1 v-else-if="level === 3"> <slot></slot> </h1> <h2 v-else-if="level === 4"> <slot></slot> </h2> <strong v-else-if="level === 5"> <slot></slot> </stong> <textarea v-else-if="level === 6"> <slot></slot> </textarea> < span style =" box-sizing: border-box; color: RGB (74, 74, 74); font-size: 13px! Important; word-break: inherit! Important;" </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>Copy the code

The former is suitable for complex logic, while the latter is suitable for simple logic. The latter belongs to the declaration is Render, the former belongs to the custom Render function; The former has higher performance while the latter has lower performance.

5. Asynchronous components

Scenario: Large projects tend to load slowly, so asynchronous components that load on demand are a must. There are three ways to register components asynchronously

// The factory function executes the resolve callback Vue.component('async-webpack-example', Function (resolve) {// This special 'require' syntax will tell WebPack // to automatically split your build code into multiple packages, Require (['./my-async-component']), Resolve)}) // The factory function returns Promise Vue.component('async-webpack-example', // the 'import' function returns a 'Promise' object. () => import('./ my-async-Component ')) // Factory function returns a configured component object const AsyncComponent = () => ({// Component to load (should be a 'Promise' Object) Component: import('./ myComponent.vue '), // Asynchronous component LoadingComponent loading: LoadingComponent error: ErrorComponent, // Shows how long the component is delayed when loading. The default value is 200 (milliseconds) delay: 200, // If a timeout is provided and the component loading has timed out, the component used when the loading failed is used. Default is: 'Infinity' timeout: 3000})Copy the code

Rendering an asynchronous component is essentially doing two or more renderings, rendering the current component as an annotation node, and then re-rendering the component once it has been loaded via forceRender. Or render it as a comment node, then render it as a Loading node, and then render it as a requested completed component

2. Routes are loaded on demand

Webpack < 2.4 {path:'/', name:'home', Resolve =>require(['@/components/home'],resolve)} webpack> 2.4 {path:'/', name:'home', Components :()=>import('@/components/home')} import() method is proposed by es6. The import() method is dynamically loaded and returns a Promise object, and the argument to the then method is the module loaded. Similar to node.js's require method, the main import() method is loaded asynchronously.Copy the code

Dynamic components

Scenario: Dynamic component loading is involved when a TAB switch is made

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

But it works because every time the component is reloaded, it consumes a lot of performance

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

There is no animation for this switching effect, so don’t worry about this either, you can use the built-in

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

7. Recursive components

Scenario: If you develop a tree component where the hierarchy is determined based on background data, you need dynamic components

// Recursive component: a component can recursively call itself within its template by naming the component. // House will be used recursively in the component template, but it must be given a condition to limit the number, otherwise it will throw an error: Max stack size exceeded // The component recursion will be used to develop independent components with an undefined hierarchy. // <template> <div v-for="(item,index) in treeArr"> subcomponent, current level value: {{index}} <br/> <! -- call itself recursively, --> <tree :item="item.arr" v-if="item.flag"></tree> </div> </template> <script> export default {// Name: 'tree', data(){return {}}, // props: {item: {type:Array, default: ()=>[] } } } </script>Copy the code

The recursive component must set the name and end thresholds

8. Functional components

Definition: stateless, cannot be instantiated, and does not have any internal lifecycle handling rules: Prior to 2.3.0, the props option was required if a functional component wanted to receive a prop. In versions 2.3.0 and above, you can omit the props option. All features on components are automatically and implicitly resolved to prop. If you are using single-file components (plain.vue files), you can declare directly on the template that everything the functional component needs is passed through the context argument

Children: an array of VNode children. 3. Slots: a function that returns an object containing all the slots. (2.6.0+) An object that exposes the incoming scope slot. Normal slots are also exposed as functions. Parent: a reference to the parent component 7. Listeners: (2.3.0+) An object containing all event listeners registered by the parent component for the current component. This is an alias for data.on. 8.injections: (2.3.0+) If the Inject option is used, the object contains properties that should be injected

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

9. com ponents and Vue.com ponent

Components: Locally registered components

export default{
  components:{home}
}
Copy the code

Vue.component: global registration component

Vue.component('home',home)
Copy the code

10.Vue.extend

Extend extends a component’s syntax:

Var Profile = vue.extend ({template: '<p>{{extendData}}</br> {{propsExtend}}</p>'; function () { return { extendData: }}, props:['propsExtend']}) New Profile({propsData:{propsExtend:' I am the data passed in by the instance '}}).$mount('#app-extend') // Via Components or Vue.com ponent () registered Vue.com ponent (' Profile, Profile)Copy the code

11.mixins

Scenario: Some components have duplicate JS logic, such as verify the phone captcha, parse time, etc. Mixins can implement this mixins value is an array

Const mixin={created(){this.dealtime ()}, methods:{dealTime(){console.log(' this is the method in mixin's dealTime '); } } } export default{ mixins:[mixin] }Copy the code

12.extends

Extends is similar to mixins except that the parameters it receives are simple option objects or constructors, so extends extends only one component at a time

Const extend={created(){this.dealtime ()}, methods:{dealTime(){console.log(' this is the method in the mixin dealTime '); } } } export default{ extends:extend }Copy the code

13.Vue.use()

When we use an element, we import it first, then use() to register the component and trigger the install method. This is often used in component calls; Multiple registrations of the same plug-in are automatically organized.

14.install

Scenario: In vue.use (), executing this method triggers install to be a plug-in that develops Vue. The first argument to this method is the Vue constructor, and the second argument is an optional option object (optional).

var MyPlugin = {}; MyPlugin.install = function (Vue, options) { // 2. Vue. Directive ('click', {bind(el, binding, vnode,}) OldVnode) {// to prepare for binding, add time to listen on console.log(' bind for my-directive was executed '); }, inserted: function(el){// Get the bound element console.log(' directive my-directive inserted implemented '); }, update: function(){// perform the corresponding update based on the obtained new value // call console.log once for the original value (' update my-directive '); }, componentUpdated: function(){console.log(' componentUpdated for my-directive was executed '); }, unbind: function(){// remove the event listener bound by bind // console.log(' the unbind of my-directive was executed '); }}) // 3. Inject component vue.mixin ({created: function () {console.log(' Injected component created was called '); Console. log('options value is ',options)}}) // 4. $myMethod = function (methodOptions) {console.log(' myMethod was called '); } // Call MyPlugin vue.use (MyPlugin,{someOption: true}) //3. Mount new Vue({el: '#app'});Copy the code

Extend, mixins, extends, Components, and install in vue

15. Vue.nextTick

2.1.0 New scenario: The text box needs to get focus when the page loads Usage: Delayed callback after the next DOM update loop ends. Use this method immediately after modifying the data to get the updated DOM

$nextTick() => {this.$refs.inputs. Focus () => {this.$refs.inputs. Focus () => {this.$refs And bind the focus method})}Copy the code

16.Vue.directive

16.1 the use of

Context: We are given a lot of instructions, but if we want to define the color of the text as a directive to use, we need to use vue. directive

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

16.2 Life Cycle

1. Bind is called only once, when the directive is first bound to an element. Use this hook to define the initialization action to be performed once on the binding. 2. Inserted: Called when the bound element is inserted into the parent node (called when the parent node is present, not in the document) Call when the template to which the element is bound is updated, and ignore unnecessary template updates by comparing the binding values before and after the update, regardless of whether the binding values have changed. It’s called only once, when the directive month element is unbundled

17. Vue.filter

This is a public method, so it can be extracted and used as a filter

/ / using / / in a pair of curly braces {{message | capitalize}} / / in ` v - bind ` in < div v - bind: id = "rawId | formatId" > < / div > / / global registration Vue.filter('stampToYYMMDD', (value) =>{// process logic}) // Register the filters: {stampToYYMMDD: // SRC /common/filters.js let dateServer = value => {// process logic}} // let dateServer = value => value.replace(/(\d{4})(\d{2})(\d{2})/g, '$1-$2-$3') export { dateServer } // /src/main.js import * as custom from './common/filters/custom' Object.keys(custom).forEach(key => Vue.filter(key, custom[key]))Copy the code

18.Vue.compile

Scenario: Compile the template string in the Render function. Only valid at standalone builds

var res = Vue.compile('<div><span>{{ msg }}</span></div>')

new Vue({
  data: {
    msg: 'hello'
  },
  render: res.render,
  staticRenderFns: res.staticRenderFns
})
Copy the code

19.Vue.version

Scenario: Some development plug-ins need to be compatible with different VUE versions, so they will use vue.version usage: vue.version () can obtain 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
}
Copy the code

20.Vue.set()

When you set an array item directly with an index or when you change the length of the array, the data will not be updated in a responsive manner due to the limitations of the object.defineprototype () method.

$set(arr,index,item) push(),splice()Copy the code

21.Vue.config.keyCodes

Scenario: Custom key modifier alias

F2 vue.config.keycodes. f2 = 113; // Set the key code to 113 as f2 vue.config.keycodes. f2 = 113; <input type="text" @keyup.f2="add"/>Copy the code

22.Vue.config.performance

Scenario: Monitoring performance

Vue.config.performance = true
Copy the code

Only available in development mode and on browsers that support the Performance. Mark API

23.Vue.config.errorHandler

1. Scenario: Specifies the handler 2 that did not catch errors during rendering and observation of the component. Rule: As of 2.2.0, this hook also catches errors in component lifecycle hooks. Also, when the hook is undefined, the caught error will be output via console.error to avoid application crash. As of 2.4.0, the hook will also catch errors inside the Vue custom event handler. This hook will also catch errors thrown from within the V-ON DOM listener. In addition, if any overridden hook or handler returns a Promise chain (such as async), errors from its Promise chain are also handled 3. use

Vue.config.errorHandler = function (err, vm, info) {// handle error // 'info' is Vue specific error message, For example, the lifecycle hook where the error occurred // only available in 2.2.0+}Copy the code

24.Vue.config.warnHandler

2.4.0 Added 1. Scenario: Assign a custom handler to Vue’s run-time warnings, which only takes effect in developer environments 2. Usage:

Vue.config.warnHandler = function (MSG, vm, trace) {// 'trace' is the trace of the component}Copy the code

25.v-pre

Scenario: VUE is a responsive system, but some static tags do not need to be compiled more than once, saving performance

<span v-pre>{{this will not be compiled}}< span v-pre>{{this will not be compiled}}</span> So even if we define MSG in our data we're still displaying {{MSG}}Copy the code

26.v-cloak

Scenario: A variable flicker occurs when rendering the page using vue binding data during slow network speeds. Usage: This instruction remains on the element until the associated instance finishes compiling. Used together with CSS rules such as [v-cloak] {display: None}, this directive hides the uncompiled Mustache tag until the instance is ready

// template <div class="#app" v-cloak> <p>{{value. Name}}</p> </div> // CSS <div class="#app" v-cloak> <p>{{value. }Copy the code

This will solve the flicker, but it will appear as a white screen, which can be used in conjunction with the skeleton screen

27.v-once

Scenario: Some Templates have no static DOM changes, so you only need to render once, reducing performance overhead

<span style = "box-sizing: border-box; color: RGB (74, 74, 74); line-height: 22px; white-space: inherit! Important;"Copy the code

The difference between v-once and V-pre: V-once only renders once; The V-PRE is not compiled and output as is

28. Event modifier

Stop: prevents bubble. Prevent: prevents default behavior. Self: only the binding element is triggered. 2.3.0 Added: The default behavior of a rolling event (i.e. the rolling behavior) will be triggered immediately and cannot be used with.preventCopy the code

Key modifiers and key codes

Scenario: Sometimes you need to listen to the behavior of the keyboard, such as pressing Enter to query the interface

// The corresponding key on the keyboard is.enter.tab.delete (capturing the delete and backspace keys).esc.space.up.down.left.rightCopy the code

30.Vue-router

Scenario: Vue-Router is an official routing plug-in

30.1 Cache and animation

1. The official component vue-router is used for routing. I believe you are familiar with how to use it. 2. Here I describe the route cache and animation; 3. Exclude or include, added in 2.1.0

<transition> <keep-alive :include="['a', 'b'] "> / / or include =" a, b ": the include =" / / "a | b, a and b component name / / because of some pages, such as try data statistics, to real time refresh, so there is no need to cache the < the router - view / > / / routing label </keep-alive> <router-view exclude="c"/> </transition>Copy the code

Note: Matching first checks the component’s own name option, and if the name option is not available, matches its locally registered name (the key of the parent component’s Components option). 4. Using v-if, the components will be rerendered without enumerating the names of each component

30.2 Global routing hook

1.router.beforeEach

Router-beforeeach ((to, from, next) => {console.log(' Global front guard: BeforeEach -- next needs to call ') // Normal login interception uses this, also called navigation hook guard if (path === '/login') {next() return} if (token) {next(); }})Copy the code

BeforeResolve (V 2.5.0+) is similar to beforeEach, except that beforeEach guard is called after beforeEach, before navigation is confirmed, and after all components guard and asynchronous routing component are resolved

These hooks are called at the end of all route hops without accepting the next function or changing the navigation itself

30.3 Component routing hooks

BeforeRouteEnter is called before the corresponding route of the rendering component is confirmed. The usage and parameters are similar to router.beforeeach. Next needs to be called when the component instance has not been created. The callback is performed when the navigation is confirmed, and the component instance is taken as a parameter to the callback method

BeforeRouteEnter (to, from, next) {// This === undefined next(vm => {// access the component instance via 'vm'})}Copy the code

2. BeforeRouteUpdate (v 2.2+) is called when the current route changes and the component is being reused. The instance can be accessed through this

3. BeforeRouteLeave is called when the navigation leaves the corresponding route of the component. This can be accessed by the component instance

30.4 Routing mode

Set the mode attribute :hash or History

30.5 the Vue. $router

This.$router.push(): jump to a different URL, but this method adds a record back to the history stack, This.$route.replace (): no record this.$route.go (n):n can be positive or negative. Positive numbers forward, negative numbers backward, similar to window.history.go(n)Copy the code

30.6 the Vue. $route

Represents the route object of the current jump. The attributes are: Name: route name path: path Query: received parameter params: received parameter fullPath: parsed URL with query parameters and hash matched: copy of route record redirectedFrom: If redirection exists, The name of the route that redirects to the source

$route.query. Id: gets the parameter passed by params or /:id. This.$route.queryCopy the code

30.7 the router – the view of the 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, it will no longer execute created or Mounted hooks

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

Then both created and Mounted components will be executed

31.Object.freeze

Vue is a new feature in ES5 that can freeze an object and prevent it from being modified. Vue 1.0.18+ supports this feature. Vue does not translate getters and setters for objects frozen in data or vuex with freeze. Note: the freeze is only a single property within the freeze. The reference address can still be changed

List: object.freeze ([{value: 1}, {value: 1}, {value: 1}) }, mounted () {this.list[0].value = 100; This.list = [{value: 100}, {value: 200}]; this.list = Object.freeze([ { value: 100 }, { value: 200 } ]); }})Copy the code

32. The debugging of the template

Scenario: During Vue development, it is common for JavaScript variables to fail while the Template is being rendered. In this case, you may want to debug using console.log

// main.js Vue.prototype.$log = window.console.log; {$log(info)}}</div>Copy the code

33. Vue – loader tips

33.1 preserveWhitespace

Scenario: Developing vUE code usually has Spaces. In this case, if you do not remove Spaces, the package size will be increased. Configure preserveWhitespace to reduce the size of the package

{
  vue: {
    preserveWhitespace: false
  }
}
Copy the code

33.2 transformToRequire

Scenario: When writing Vue, it is common to write code that requires an image to a variable before passing it to a component

< img SRC ="imgSrc"></avatar> </div> </template> <script> export default {created () { this.imgSrc = require('./assets/default-avatar.png') } } </script>Copy the code

Now: After you configure transformToRequire, you can configure it directly, so that the Ue – Loader automatically requires the corresponding properties to the component

// Vue-cli 2.x in vue-loader.conf.js default configuration is transformToRequire: {video: [' SRC ', 'poster'], source: 'SRC ', img: 'SRC ', image: 'xlink:href'} // configure file, if it is vue-cli2.x modify avatar in vue-loader.conf. ['default-src'] // Vue-cli 3.x in vue.config.js // Vue-cli 3.x change the transformToRequire attribute to transformAssetUrls module.exports =  { pages, chainWebpack: config => { config .module .rule('vue') .use('vue-loader') .loader('vue-loader') .tap(options => { options.transformAssetUrls = { avatar: 'img-src', } return options; }); </div> </template> <avatar img-src="./assets/ default-Avatar-.png "></avatar> </div> </template>Copy the code

34. Set an alias for the path

1. Scene: In the development process, we often need to introduce various files, such as pictures, CSS, JS, etc., in order to avoid writing a long relative path (.. /), we can configure an alias for different directories

2. Vue – cli 2. X configuration

// Add the alias name resolve: {extensions: ['.js', '.vue', '.json'], alias: { 'vue$': 'vue/dist/vue.esm.js', '@': resolve('src'), } },Copy the code

3. Vue – cli 3. X configuration

Var path = require('path') function resolve (dir) {console.log(__dirname) return path.join(__dirname, dir) } module.exports = { chainWebpack: Config => {config.resolve.alias.set (key, value) // set(key, value).Copy the code

35. Img failed to load

Scene: Sometimes the background returned image address may not open, so this time should add a default image

<img: SRC ="imgUrl" @error="handleError" Alt =""> <script> export default{data(){return{imgUrl: "}}, Methods :{handleError(e){e.target.src=reqiure(' transformToRequire ')}}} </script>Copy the code

36.css

36.1 Local styles

1. The scoped property of the style tag in Vue means that its style applies only to the current module, making it private.

2. Render rules/principles: Add a unique data property to the HTML DOM node to represent uniqueness. Add a data property selector to the current component at the end of the corresponding CSS selector to make the style private. . Demo [data-V-2311c06a]{} will only set on the last element if less or sass is introduced

<span class="content"> vue.js scoped </span> </div> </template> <style lang="less"  scoped> .demo{ font-size: 16px; .content{ color: red; }} </style> <div data-v-fed36922> Vue. Js scoped </div> <style type="text/ CSS ">. font-size: 14px; }.demo. content[data-V-039c5b43] {// There is no data attribute in. Demo color: red; } </style>Copy the code

36.2 deep property

// <style lang="less" scoped>. Demo {font-size: 14px; } .demo /deep/ .content{ color: blue; < span style =" box-sizing: border-box! Important; word-wrap: break-word! Important;" } .demo[data-v-039c5b43] .content { color: blue; } </style>Copy the code

After the language

Original code word is not easy, welcome star!