SoFunction
Updated on 2025-03-04

36 tips that Vue development must know (summary)

Preface

Vue's Pre-Alpha version. There should be Alpha, Beta and other versions later, and it is expected that the official version of 3.0 will not be released until at least the first quarter of 2020;
Therefore, we should lay a solid foundation before we even came out;

The basic usage of Vue is easy to get started, but you may not know the writing methods of many optimizations. This article lists 36 vue development techniques;

Continuous updates after Vue comes out.

()

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, which can be written using

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

This way, no matter how many components the page introduces, you can use this method

method

In fact, it is a webpack method. Vue project is generally based on webpack, so it can be used.
(directory,useSubdirectories,regExp)
Receive three parameters:
directory: Explain the directory to be retrieved
useSubdirectories: Whether to retrieve subdirectories
regExp: The regular expression matching the file, usually the file name


2.1 Common usage

1. Scenario: When the table comes in, you need to investigate the query interface getList(), and then the input changes will be requeried.

created(){
 ()
},
watch: {
 inpVal(){
 ()
 }
}

2.2 Execute immediately

2. You can directly use the watch's immediate and handler attribute abbreviation

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

2.3 In-depth monitoring

deep attribute, deep monitoring, that is, listen for complex data types

watch:{
 inpValObj:{
 handler(oldVal,newVal){
  (oldVal)
  (newVal)
 },
 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 does not retain a copy of the previous value;

Therefore, although deep monitoring can monitor the changes of the object, it cannot monitor the changes of the attribute in the specific object.

3. 4 types of component communication

3.1 props

This should be a very special attribute, which is the attribute of the father passing through the son;

The props value can be an array or object;

// Array: Not recommendedprops:[]

// Objectprops:{
 type:Number, //Incoming value limited type // The type value can be String, Number, Boolean, Array, Object, Date, Function, Symbol // type can also be a custom constructor, and check and confirm through instanceof required: true, //Is it necessary to pass default:200, //Default value, object or array default value 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
 }
}

3.2 $emit

This should also be very attributed. Triggering the custom event of the parent component is actually a method of passing the parent to the child.

// Parent component<home @title="title">
// Subcomponentsthis.$emit('title',[{title:'This is title'}])

3.3 vuex

1. This is also very commonly used, vuex is a state manager
2. It is an independent plug-in, suitable for projects with a lot of data sharing, because if it is just a simple communication, it will be more heavy to use.

state: Defines the repository for storing data, which can be accessed through this.$ or mapState
getter: Get the store value, which can be considered as a computed property of the store, which can be used through this.$ or
mapGetters access
mutation: Synchronously change store value, why is it designed to be synchronous? Because mutation directly changes store value,
vue records the operation, if it is asynchronous, it cannot be traced and changed. It can be called through mapMutations
action: Asynchronously call the function to execute mutation, and then change the store value, you can use this.$dispatch or mapActions
Visit
modules: module, if there are too many states, it can be split into modules, and finally introduced in the entrance through... destruction

3.4 $attrs and $listeners

2.4.0 New

These two are not commonly used properties, but advanced usage is very common;

1.$attrs

Scenario: If the parent passes through the child has many values, then multiple props need to be defined in the child component
Solution: $attrs gets the value not defined in props in the child pass parent

// Parent component<home title="This is the title" width="80" height="80" imgUrl="imgUrl"/>

// Subcomponentsmounted() {
 (this.$attrs) //{title: "This is the title", width: "80", height: "80", imgUrl: "imgUrl"}},

Correspondingly, if the child component defines props, the printed value is to remove the defined attribute.

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

2.$listeners

Scenario: The child component needs to call the parent component's method
Solution: The parent component's method can be passed into internal components via v-on="$listeners" - very useful when creating higher-level components

// Parent component<home @change="change"/>

// Subcomponentsmounted() {
 (this.$listeners) //You can get the change event}

If the grand component wants to access the properties and call methods of the parent component, it can be passed down one by one level and one level.

// Parent component<home title="This is the title" width="80" height="80" imgUrl="imgUrl"/>

// Subcomponentsmounted() {
 (this.$attrs) //{title: "This is the title", width: "80", height: "80", imgUrl: "imgUrl"}},

inheritAttrsThe default value is true,That is, the properties on the parent component will be displayed on the root component.
If set to false Will hide

3.5 provide and inject

2.2.0 New
describe:
Provide and inject mainly provide use cases for advanced plug-ins/component libraries. It is not recommended to be used directly in application code;
And this pair of options needs 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 always take effect during the time when the upstream and downstream relationship is established.

//Parent component:provide: { //provide is an object that provides a property or method foo: 'This is foo',
 fooMethod:()=>{
 ('The parent component fooMethod is called')
 }
},

// Children or grandchild componentinject: ['foo','fooMethod'], //Array or object, injected into child componentsmounted() {
 ()
 ()
}
//All child components under the parent component can use inject

Provide and inject bindings are not responsive. This is done deliberately by the official.

However, if you pass in an listenable object, then the properties of its object are still responsive, because the object is a reference type

//Parent component:provide: { 
 foo: 'This is foo'
},
mounted(){
 ='This is the new foo'
}

// Children or grandchild componentinject: ['foo'], 
mounted() {
 () //The subcomponent prints 'This is foo'}

3.6 $parent and $children

$parent:Parent instance
$children:Subin instance

// Parent componentmounted(){
 (this.$children) 
 //You can get the properties and methods of first-level subcomponents //So you can directly change data or call the methods method}

//Subcomponentmounted(){
 (this.$parent) //You can get the parent's properties and methods}

$children and $parent are not guaranteed in order, nor are they responsive.
Only get first-level parent and child components

3.7 $refs

// Parent component<home ref="home"/>

mounted(){
 (this.$) //You can get the instance of the subcomponent and directly operate data and methods}

3.8 $root

// Parent componentmounted(){
 (this.$root) //Get the root instance, and finally all components are mounted to the root instance (this.$root.$children[0]) //Get the first-level subcomponent of the root instance (this.$root.$children[0].$children[0]) //Get the secondary subcomponent of the root instance}

3.9 .sync

In vue@, it existed as a two-way binding function, that is, the child component can modify the values ​​in the parent component;
In [email protected], the design of the single data stream was eliminated;
This .sync modifier has been reintroduced in [email protected]+ or ​​above;

// Parent component<home :="title" />
//It will be expanded to<home :title="title" @update:title="val => title = val"/>

// Subcomponents// So the child component can be changed by triggering the update methodmounted(){
 this.$emit("update:title", 'This is the new title')
}

3.10 v-slot

2.6.0 New
,slot-cope,scope were all abandoned in 2.6.0, but not removed
2. The function is to pass the template of the parent component into the child component
3. Slot classification:
A. Anonymous slot (also called the default slot): There is no name, there is only one;

// Parent component<todo-list> 
 <template v-slot:default>
  Any content
  <p>I'm anonymous slot </p>
 </template>
</todo-list> 

// Subcomponents<slot>I'm the default value</slot>
//v-slot: The feeling and name writing method are relatively unified when writing, which is easy to understand, and you can also not write it without

B. Named slot: Relative anonymous slot component slot tag with name naming;

// Parent component<todo-list> 
 <template v-slot:todo>
  Any content
  <p>I'm anonymous slot </p>
 </template>
</todo-list> 

//Subcomponent<slot name="todo">I'm the default value</slot>

C. Scope slot: The data in the child component can be obtained by the parent page (solved that the data can only be passed from the parent page to the child component)

// Parent component<todo-list>
 <template v-slot:todo="slotProps" >
 {{}}
 </template> 
</todo-list> 
//slotProps can be named at will//slotProps is the collection of attribute data on the subcomponent tag slot. v-bind:user="user"
// Subcomponents<slot name="todo" :user="user" :test="test">
 {{  }}
 </slot> 
data() {
 return {
  user:{
  lastName:"Zhang",
  firstName:"yue"
  },
  test:[1,2,3,4]
 }
 },
// {{ }} is the default data v-slot:todo When the parent page does not have (="slotProps")

3.11 EventBus

1. It is to declare a global Vue instance variable EventBus, which stores all communication data and event listening on this variable;
2. Similar to Vuex. But this method is only suitable for very small projects
3. The principle is to use $on and $emit and instantiate a global vue to achieve data sharing

// exist.$eventBus=new Vue()

// Value transfer componentthis.$eventBus.$emit('eventTarget','This is the value passed by eventTarget')

// Receive componentthis.$eventBus.$on("eventTarget",v=>{
 ('eventTarget',v);//This is the value passed by eventTarget})

4. It can achieve horizontal level and nested component passing values, but the corresponding event name eventTarget must be globally unique.

3.12 broadcast and dispatch

vue has these two methods, event broadcasting and distribution, but vue deletes

The following is the encapsulation of two methods

function broadcast(componentName, eventName, params) {
 this.$(child => {
 var name = child.$;

 if (name === componentName) {
  child.$(child, [eventName].concat(params));
 } else {
  (child, [componentName, eventName].concat(params));
 }
 });
}
export default {
 methods: {
 dispatch(componentName, eventName, params) {
  var parent = this.$parent;
  var name = parent.$;
  while (parent && (!name || name !== componentName)) {
  parent = parent.$parent;

  if (parent) {
   name = parent.$;
  }
  }
  if (parent) {
  parent.$(parent, [eventName].concat(params));
  }
 },
 broadcast(componentName, eventName, params) {
  (this, componentName, eventName, params);
 }
 }
}

3.13 Routing parameters

1. Plan 1

//Route definition{
 path: '/describe/:id',
 name: 'Describe',
 component: Describe
}
// Page parametersthis.$({
 path: `/describe/${id}`,
})
// Page acquisitionthis.$

2. Plan 2

//Route definition{
 path: '/describe',
 name: 'Describe',
 omponent: Describe
}
// Page parametersthis.$({
 name: 'Describe',
 params: {
 id: id
 }
})
// Page acquisitionthis.$

3. Plan 3

//Route definition{
 path: '/describe',
 name: 'Describe',
 component: Describe
}
// Page parametersthis.$({
 path: '/describe',
 query: {
  id: id
 `}
)
// Page acquisitionthis.$

4. Comparison of three solutions
The parameter page refresh after plan 2 will be lost
Scheme one parameter is spliced ​​behind, ugly, and the information is exposed
Scheme 3 will not splice parameters later, and refresh parameters will not be lost.

3.14

2.6.0 New
Usage: Make an object responsive. Vue will use it internally to process the objects returned by the data function;

The returned object can be used directly in rendering functions and computed properties, and will trigger corresponding updates when changes occur;
It can also be used as a miniaturized cross-component state memory for simple scenarios.

The communication principle is essentially to use the implementation of a simple vuex

// File path - /store/import Vue from 'vue'

export const store = ({ count: 0 })
export const mutations = {
 setCount (count) {
  = count
 }
}

//use<template>
 <div>
  <label for="bookNum">number 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 adds API Observable
export default {
 name: 'Add',
 computed: {
 count () {
  return 
 }
 },
 methods: {
 setCount: 
 }
}
</script>

function

1. Scenario: Some codes are repeated a lot in template, so the render function is useful at this time.

// Generate tags based on props// Elementary<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>
 </div>
</template>

// Optimized version, using 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'
 ('child', {
 render(h) {
  const tag = ['div', 'p', 'strong', 'h1', 'h2', 'textarea'][]
  return h(tag, this.$)
 },
 props: {
  level: { type: Number, required: true } 
 }
 }) 
 export default {
 name: 'hehe',
 data() { return { level: 3 } }
 }
</script>

Comparison with template

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

5.Async Components

Scenario: Too large projects will lead to slow loading, so asynchronous components are required to implement on-demand loading.
1. Asynchronously register components
3 ways

// Factory function executes resolve callback('async-webpack-example', function (resolve) {
 // This special `require` syntax will tell webpack // Automatically cut your build code into multiple packages, these packages // Will load through Ajax request require(['./my-async-component'], resolve)
})

// Factory function returns Promise(
 'async-webpack-example',
 // This `import` function will return a `Promise` object. () => import('./my-async-component')
)

// Factory function returns a configurable component objectconst AsyncComponent = () => ({
 // Component that needs to be loaded (it should be a `Promise` object) component: import('./'),
 // Components used when loading asynchronous components loading: LoadingComponent,
 // Components used when loading fails error: ErrorComponent,
 // Shows the delay time of the component when loading.  The default value is 200 (ms) delay: 200,
 // If the timeout is provided and the component loading has also timed out, // Use the components used when loading fails.  The default value is: `Infinity` timeout: 3000
})

Rendering of an asynchronous component is essentially a 2 or more rendering times. First render the current component as an annotation node. After the component is loaded successfully, re-render is performed through forceRender. Or render as an annotation node, then render as a loading node, rendering as a component that is completed by the request

2. On-demand loading of routes

webpack< 2.4 hour
{
 path:'/',
 name:'home',
 components:resolve=>require(['@/components/home'],resolve)
}

webpack> 2.4 hour
{
 path:'/',
 name:'home',
 components:()=>import('@/components/home')
}

The import() method is proposed by es6. The import() method is dynamically loaded, returning a Promise object, and the parameters of the then method are the modules loaded to. Similar to the require method, the main import() method is loaded asynchronously.

6. Dynamic Components

Scenario: When doing a tab switch, it involves dynamic component loading

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

But this way, the component will be reloaded every time, which will consume a lot of performance, so <keep-alive> plays a role

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

This way, there is no animation effect in the switching effect, so there is no need to worry about this. You can use the built-in <transition>

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

7. Recursive components

Scenario: If you develop a tree component, the levels inside are determined based on background data, you need to use dynamic components at this time.

// Recursive component: The component can call itself recursively within its template, just set the name component for the component.// Settings then House can be used recursively within the component template, but 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 specific unknown hierarchical relationships.  for example:// Concategory selector and tree control
&lt;template&gt;
 &lt;div v-for="(item,index) in treeArr"&gt;
  Subcomponents,Current level value: {{index}} &lt;br/&gt;
  &lt;!-- Recursively call itself, Determine whether there is no change value in the background --&gt;
  &lt;tree :item="" v-if=""&gt;&lt;/tree&gt;
 &lt;/div&gt;
&lt;/template&gt;
&lt;script&gt;
export default {
 // Name must be defined so that the component can be called recursively name: 'tree',
 data(){
 return {}
 },
 // Receive external incoming values props: {
  item: {
  type:Array,
  default: ()=&gt;[]
 }
 }
}
&lt;/script&gt;

The recursive component must set the threshold value of name and end

8. Functional Components

Definition: stateless, cannot be instantiated, there is no lifecycle processing method inside

Rule: In versions prior to 2.3.0, if a functional component wants to receive props, the props option is required.

In versions 2.3.0 or above, you can omit the props option, and all features on components will be automatically implicitly parsed as props.
In version 2.5.0 and above, if you use a single file component (a normal .vue file), you can declare functional directly on template
Everything that the component needs is passed through the context parameter

The context attributes are:
: Provide all prop objects
: VNode array of child nodes
: A function that returns an object containing all slots
: (2.6.0+) An object that exposes the incoming scope slot. Normal slots are also exposed in function form.
: The entire data object passed to the component, passed to the component as the second parameter of createElement
: Reference to parent component
: (2.3.0+) An object containing the event listener registered by all parent components for the current component. This is an alias for .
: (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 ">{{item}}</div>
</template>

and

components: Local registration of components

export default{
 components:{home}
}

: Global registration of components

('home',home)


Scenario: Some of the vue components need to mount some elements onto the elements, and at this time extend will play a role

It is a syntax that constructs a component

Writing method:

// Create a constructorvar Profile = ({
 template: '&lt;p&gt;{{extendData}}&lt;/br&gt;The data passed in by the instance is:{{propsExtend}}&lt;/p&gt;',//The outermost layer of the corresponding tag of template must have only one tag data: function () {
 return {
  extendData: 'This is the data extended by extend',
 }
 },
 props:['propsExtend']
})

// The created constructor can be mounted on the element, or registered with components or ()// Mount to an element.  Parameters can be transferred through propsData.new Profile({propsData:{propsExtend:'I'm the data passed in by the instance'}}).$mount('#app-extend')

// Register through components or ()('Profile',Profile)


Scenario: Some components have some duplicate js logic, such as verifying mobile phone verification code, parsing time, etc., mixins can achieve this kind of mixing

The mixins value is an array

const mixin={
 created(){
  ()
 },
 methods:{
  dealTime(){
  ('This is the method inside the dealTime of the mixin');
  }
 }
}

export default{
 mixins:[mixin]
}


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

const extend={
 created(){
  ()
 },
 methods:{
  dealTime(){
  ('This is the method inside the dealTime of the mixin');
  }
 }
}

export default{
 extends:extend
}

()

Scenario: When we use element, we will import first, and then () it is actually registering the component and triggering the install method;
This is often used in component calls;
The same plug-in will be automatically organized to register multiple times.


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

var MyPlugin = {};
  = function (Vue, options) {
 // 2. Add global resources, pass a value in the second parameter to the default value corresponding to update ('click', {
  bind(el, binding, vnode, oldVnode) {
  //Preparing binding preparations, adding time monitoring  ('The command my-directive bind is executed');
  },
  inserted: function(el){
  //Get bound elements  ('The inserted command of my-directive is executed');
  },
  update: function(){
  //Execute corresponding update based on the obtained new value  //The initial value will also be called once  ('The update of the command my-directive has been executed');
  },
  componentUpdated: function(){
  ('The componentUpdated of the command my-directive is executed');
  },
  unbind: function(){
  //Do cleaning operations  //For example, the event listener bound when removing bind  ('The command my-directive unbind is executed');
  }
 })

 // 3. Inject components ({
  created: function () {
  ('Created injected component is called');
  ('options' value is',options)
  }
 })

 // 4. Add an instance method .$myMethod = function (methodOptions) {
  ('The instance method myMethod is called');
 }
 }

 //Call MyPlugin (MyPlugin,{someOption: true })

 //3. Mount new Vue({
 el: '#app'
 });

For more information, please click on the several operations of extend, mixins, extends, components, install in vue

15.

2.1.0 New
Scene: When the page loads, you need to get the focus of the text box
Usage: Execute a delayed callback after the next DOM update loop ends. Use this method immediately after modifying the data to obtain the updated DOM

mounted(){ //Because the mounted stage dom has not been rendered, $nextTick is needed this.$nextTick(() =&gt; {
 this.$() //Get the dom through $refs and bind the focus method })
}


16.1 Use

Scenario: The official provides us with a lot of instructions, but if we want to turn the text into a specified color and define it as a command to use it, we need to use it at this time

// Global definition("change-color",function(el,binding,vnode){
 ["color"]= ;
})

// use&lt;template&gt;
&lt;div v-change-color&gt;{{message}}
&lt;/div&gt;
&lt;/template&gt;
&lt;script&gt;
 export default{
 data(){
  return{
  color:'green'
  }
 }
 }
&lt;/script&gt;

16.2 Life cycle

It is called only once, and the command is called when the first time it is bound to an element. This hook can be used to define an initialization action that is performed once during binding.
: Called when the bound element is inserted into the parent node (it can be called if the parent node exists, and it does not need to exist in the document)
: Called when the template where the bound and element is located is updated, and regardless of whether the binding value has changed, by comparing the binding values ​​before and after the update, unnecessary template updates are ignored
: Called when the template where the bound element is located has completed an update cycle
: Called only once, and call it when the command month element is unbined

17.

Scenario: Timestamps are converted to year, month, and day. This is a public method, so it can be extracted into filters.

// use// in double braces{{ message | capitalize }}

// in `v-bind`&lt;div v-bind:&gt;&lt;/div&gt;

// Global registration('stampToYYMMDD', (value) =&gt;{
 // Processing logic})

// Local registrationfilters: {
 stampToYYMMDD: (value)=&gt; {
 // Processing logic }
}

// Global registration of multiple filters// /src/common/
let dateServer = value =&gt; (/(\d{4})(\d{2})(\d{2})/g, '$1-$2-$3') 
export { dateServer }
// /src/
import * as custom from './common/filters/custom'
(custom).forEach(key =&gt; (key, custom[key]))


Scenario: Compile template strings in render function. Only valid when built independently

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

new Vue({
 data: {
 msg: 'hello'
 },
 render: ,
 staticRenderFns: 
})


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

var version = Number(('.')[0])

if (version === 2) {
 // Vue 
} else if (version === 1) {
 // Vue 
} else {
 // Unsupported versions of Vue
}

()

Scenario: When you use the index to set an array item directly or when you modify the length of the array, due to the () method limitation, the data is not updated responsively

However, vue. will use proxy.
Solution:

// Use setthis.$set(arr,index,item)

//Use array push(), splice()


Scene: Custom key modifier alias

// Define the key code as 113 as f2.f2 = 113;
&lt;input type="text" @keyup.f2="add"/&gt;


Scenario: Monitoring performance

 = true

Applicable only to development mode and API-enabled browsers


1. Scenario: A handler function that specifies the component's rendering and observation period that has not caught errors during the process of errors
2. Rules:

  • Starting from 2.2.0, this hook will also catch errors in the component lifecycle hook. Similarly, when this hook is undefined, the captured error will prevent application crashes through the output.
  • Starting from 2.4.0, this hook will also catch errors inside Vue custom event handlers.
  • Starting from 2.6.0, this hook will also catch errors thrown inside the v-on DOM listener. Additionally, if any overwritten hook or handler returns a Promise chain (such as async function), errors from its Promise chain are also processed

3. Use

 = function (err, vm, info) {
 // handle error
 // `info` is a Vue specific error message, such as the life cycle hook where the error is located // Only available in 2.2.0+}


2.4.0 New
1. Scenario: Assign a custom processing function to the runtime warning of Vue, which will only take effect in the developer environment.
2. Usage:

 = function (msg, vm, trace) {
 // `trace` is the inheritance relationship tracking of the component}

-pre

Scenario: vue is a responsive system, but some static tags do not require multiple compilation, which can save performance

&lt;span v-pre&gt;{{ this will not be compiled }}&lt;/span&gt; Shown is{{ this will not be compiled }}
&lt;span v-pre&gt;{{msg}}&lt;/span&gt;  even thoughdataIt is defined in itmsgIt's still displayed here{{msg}}

-cloak

Scenario: When the network speed is slow, when using vue to bind data, variable flashes will occur when rendering the page.

Usage: This directive remains on the element until the associated instance ends compilation. When used with CSS rules such as [v-cloak] { display: none }, this directive can hide uncompiled Mustache tags until the instance is ready.

// template&lt;div class="#app" v-cloak&gt;
 &lt;p&gt;{{}}&lt;/p&gt;
&lt;/div&gt;

// css[v-cloak] {
 display: none;
}

This can solve the flickering, but there will be a white screen, which can be used in combination with the skeleton screen

-once

Scenario: Some static doms in templates have not changed, and only rendering is required once, which can reduce performance overhead

&lt;span v-once&gt; Only load the tag once&lt;/span&gt;

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

28. Event Modifier

.stop:Stop bubbles
.prevent: Block default behavior
.self: Only bind the element itself triggers
.once: 2.1.4 Added, triggered only once
.passive: 2.3.0 has added, the default behavior of the scroll event (i.e. scroll behavior) will be triggered immediately and cannot be used with .prevent

29. Key modifiers and key codes

Scenario: Sometimes you need to monitor the behavior of the keyboard, such as pressing enter to query the interface, etc.

// Corresponding keywords on the keyboard
.enter
.tab
.delete (Capture the "Delete" and "Backspace" keys)
.esc
.space
.up
.down
.left
.right

-router

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

30.1 Cache and animation

The routing uses the official component vue-router, and I believe everyone is very familiar with the usage method;
Here I will describe the cache and animation of the route;

&lt;transition&gt;
 &lt;keep-alive v-if="aliveFlag"&gt; //Because some pages, such as trying data statistics, need to be refreshed in real time, so there is no need to cache &lt;router-view/&gt; //Routing tag &lt;/keep-alive&gt;
 &lt;router-view v-else/&gt;
&lt;/transition&gt;

30.2 Global routing hook

((to, from, next) =&gt; {
 ('Global Pre-Guard: beforeEach -- next needs to be called') //This is usually used to log in and intercept, also called navigation hook guard if (path === '/login') {
 next()
 return
 }
 if (token) {
 next();
 } 
})

(v 2.5.0+)
Similar to beforeEach, the difference is that before navigation is confirmed, and after all components are resolved, the parsing guard is called.
That is, call after beforeEach


Global back hook
Called at the end of all routes
These hooks do not accept next function and do not change the navigation itself

30.3 Component routing hook


Called before rendering the corresponding route of the component is confirmed. The usage and parameters are similar. Next needs to be called actively
At this time, the component instance has not been created yet and this cannot be accessed
You can access the component instance by passing a callback to next. When the navigation is confirmed, the callback is executed and the component instance is used as a parameter of the callback method

beforeRouteEnter (to, from, next) {
 // The component instance is not accessible here, this === undefined next( vm =&gt; {
 // Access component instances through `vm` })
}

(v 2.2+)
When the current route changes and the component is reused, the instance can be accessed through this. Next needs to be called actively and cannot be called back.


Called when navigation leaves the corresponding route of the component, you can access the component instance. This, next needs to be called actively and cannot be called back.

30.4 Routing Mode
Set mode property: hash or history

30.5 Vue.$router

this.$():Jump to a differenturl,But this method is dedicatedhistoryAdd a record on the stack,Click Back to return to the previous page
this.$():There will be no record
this.$(n):nCan be positive or negative。Positive number returns to the previous page,similar (n)

30.6 Vue.$route

It indicates that the currently redirected routing object has properties:
name:Route name
path:path
query: transmit parameter to receive value
params: transfer parameter to receive value
fullPath: The parsed URL, containing the query parameters and the full path to hash
matched:Route record copy
redirectedFrom: If there is a redirection, it is the name of the route from the redirection source

this.$:Obtained by params or/:idParameters for passing parameters
this.$:Obtained by query Parameters for passing parameters

30.7 router-view key

Scenario: Since Vue will reuse the same components, that is, /page/1 => /page/2 or /page?id=1 => /page?id=2 links will not be executed when links such as created or mounted

<router-view :key="$"></router-view>

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


Scenario: A long list of data will not be changed generally, but vue will convert getter and setter
Usage: It is a new feature added by ES5. It can freeze an object to prevent it from being modified.
Support: vue 1.0.18+ provides support for it. For objects frozen in data or vuex using freeze, vue will not convert getters and setters.
Note: Freezing is just a single attribute inside, and the reference address can still be changed.

new Vue({
 data: {
  // vue will not bind getter or setter to the object in the list  list: ([
   { value: 1 },
   { value: 2 }
  ])
 },
 mounted () {
  // The interface will not respond because a single attribute is frozen  [0].value = 100;

  // The interface will respond in the following two ways   = [
   { value: 100 },
   { value: 200 }
  ];
   = ([
   { value: 100 },
   { value: 200 }
  ]);
 }
})

32. Debugging template

Scenario: During Vue development, you often encounter the problem of JavaScript variable errors when rendering templates. At this time, you may debug it through
At this time, you can mount a log function in the development environment.

// 
.$log = ;

// Inside the component&lt;div&gt;{{log(info)}}&lt;/div&gt;

-loader tips

33.1 preserveWhitespace

Scenario: Vue code development usually has spaces. At this time, if the space is not removed, the volume of the package will be increased.
Configuring preserveWhitespace can reduce the volume of the package

{
 vue: {
 preserveWhitespace: false
 }
}

33.2 transformToRequire

Scenario: When writing Vue in the past, I often wrote such code: pass the image to a variable in advance and then to the component.

// page code&lt;template&gt;
 &lt;div&gt;
 &lt;avatar :img-src="imgSrc"&gt;&lt;/avatar&gt;
 &lt;/div&gt;
&lt;/template&gt;
&lt;script&gt;
 export default {
 created () {
   = require('./assets/')
 }
 }
&lt;/script&gt;

Now: after configuring transformToRequire, you can configure it directly, so that the vue-loader will automatically require the corresponding attribute and then pass it to the component

// vue-cli in the default configuration istransformToRequire: {
 video: ['src', 'poster'],
 source: 'src',
 img: 'src',
 image: 'xlink:href'
}

// Configuration file, if it is modified avatar: ['default-src']

// vue-cli in{
 vue: {
 transformToRequire: {
  avatar: ['default-src']
 }
 }
}

// The page code can be simplified to&lt;template&gt;
 &lt;div&gt;
 &lt;avatar img-src="./assets/"&gt;&lt;/avatar&gt;
 &lt;/div&gt;
&lt;/template&gt;

34. Set an alias for the path

1. Scenario: During 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.

-cli configuration

// vue-cli in the default configuration istransformToRequire: {
 video: ['src', 'poster'],
 source: 'src',
 img: 'src',
 image: 'xlink:href'
}

// Configuration file, if it is modified avatar: ['default-src']

// vue-cli in{
 vue: {
 transformToRequire: {
  avatar: ['default-src']
 }
 }
}

// The page code can be simplified to&lt;template&gt;
 &lt;div&gt;
 &lt;avatar img-src="./assets/"&gt;&lt;/avatar&gt;
 &lt;/div&gt;
&lt;/template&gt;

-cli configuration

// Create in the root directoryvar path = require('path')
function resolve (dir) {
 (__dirname)
 return (__dirname, dir)
}
 = {
 chainWebpack: config =&gt; {
 
  .set(key, value) // key,value is defined by yourself, such as .set('@@', resolve('src/components')) }
}

Loading failed

Scenario: Sometimes the background image address may not be opened, so a default image should be added at this time.

// page code&lt;img :src="imgUrl" @error="handleError" alt=""&gt;
&lt;script&gt;
export default{
 data(){
  return{
   imgUrl:''
  }
 },
 methods:{
  handleError(e){
   =reqiure('Picture Path') //Of course if the project is configured with transformToRequire, refer to the above 27.2  }
 }
}
&lt;/script&gt;


36.1 Local styles

The scoped property of the style tag in the style indicates that its style only applies to the current module and is style privatization.

2. Rendering rules/principles:

Add a non-repeat data attribute to HTML DOM node to represent uniqueness

Add a data attribute selector for the current component to privatize the style at the end of the corresponding CSS selector, such as: .demo[data-v-2311c06a]{}
If less or sass is introduced, it will only be set on the last element

// Original code&lt;template&gt;
 &lt;div class="demo"&gt;
  &lt;span class="content"&gt;
    scoped
  &lt;/span&gt;
 &lt;/div&gt;
&lt;/template&gt;

&lt;style lang="less" scoped&gt;
 .demo{
  font-size: 16px;
  .content{
   color: red;
  }
 }
&lt;/style&gt;

// Browser rendering effect&lt;div data-v-fed36922&gt;
  scoped
&lt;/div&gt;
&lt;style type="text/css"&gt;
.demo[data-v-039c5b43] {
 font-size: 14px;
}
.demo .content[data-v-039c5b43] { //The data attribute is not added on the.demo color: red;
}
&lt;/style&gt;

36.2 deep attributes

// Add a /deep/ in the above style&lt;style lang="less" scoped&gt;
.demo{
font-size: 14px;
}
.demo /deep/ .content{
color: blue;
}
&lt;/style&gt;

// After the browser is compiled&lt;style type="text/css"&gt;
.demo[data-v-039c5b43] {
font-size: 14px;
}
.demo[data-v-039c5b43] .content {
color: blue;
}
&lt;/style&gt;

The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.