Several performance-improving techniques for vue

1. Dynamic components<component :is='组件名'></component>

Used in combination with v-for loop
  • Usage environment

    As shown in the picture, this is a list of v-for rendering (but this section has just started, and there is only one at present). The one in the circle is a component, which is a v-for dynamic component.Insert image description here

  • actual use

The basic components are introduced from the beginning

import ColorIn from '@/components/Magic/ColorIn.vue'
import LineIn from "@/components/Magic/LineIn.vue";
import LineIn from "@/components/Magic/Header.vue";
import LineIn from "@/components/Magic/Footer.vue";

export default{
    
    
      components:{
    
    
        ColorIn,
        LineIn,
        Header,
        Footer
    }
}

The next step is to use the dynamic v-for dynamic component.componentList:['ColorIn','LineIn','Header','Footer']Use the following code to cycle the code in sequence

<component v-for="(item,index) in componentList" :key="index" :is="item"></component>

The effect after compilation is

<ColorIn></ColorIn>
<LineIn></LineIn>
<Header></Header>
<Footer></Footer>

2.Advanced use of watch

Execute immediately
  • Usage environment

For example, the scenario is to call the pull list data as soon as the page comes ingetList(), then listen to the route$route.query.id and then trigger the update of the list data

  • actual use

In order for it to be executed from the beginning, we need to execute the method of pulling data once in the created() life cycle

watch:{
    
    
    '$route.query.id':{
    
    
        handle(){
    
    
            this.getList();
        },
    }
},
created(){
    
    
    this.getList();
},

But useimmediate to execute immediately. The code after rewriting is as follows

watch:{
    
    
    '$route.query.id':{
    
    
        handle(){
    
    
          this.getList();
        },
        immediate:true
    }
},
Deep monitoring
  • Usage environment

When monitoring an object, watch cannot detect changes in the internal properties of the object. In this case, you need to use deep monitoring.

  • actual use

You only need to set updeep:true to enable deep monitoring

data(){
    
    
    return{
    
    
        queryList:{
    
    
            count:0,
            name:'',
        }
    }
},
watch:{
    
    
    queryList:{
    
     
        handle(newValue,oldValue){
    
     
        //do something 
        }, 
        deep:true
    }
},

Computed property setter

  • In actual use, we usually use getter, but in fact there is another one: setter, when calculating attributes fullNameWhen an update is triggered, the callback will be triggeredsetter
data(){
    
    
    return{
    
    
        firstName:'',
        lastName:'',
    }
},
computed:{
    
    
    fullName:{
    
    
        get(){
    
    
            return `${
      
      this.firstName} ${
      
      this.lastName}`;
        },
        set(newValue){
    
    
            let names=newValue.split(' ');
            this.firstName=names[0];
            this.lastName=names[1];
        }
    }
},

$on(‘hook:lifecycle’) to simplify window monitoring

  • actual use

Let’s take a look at the usual usage first.

mounted () {
    
    
    window.addEventListener('resize', this.resizeHandler);
},
beforeDestroy () {
    
    
    window.removeEventListener('resize', this.resizeHandler);
}

The rewritten code is as follows. Compared with the above writing method, the advantage of this writing method is that it can open an event listener and at the same time mount a delete in the life cycle of beforeDestroy Event listener for events. It will be safer than the above writing method, and more helpful to avoid memory leaks and prevent event conflicts

mounted () {
    
    
  window.addEventListener('resize', this.resizeHandler);
  this.$on("hook:beforeDestroy", () => {
    
    
    window.removeEventListener('resize', this.resizeHandler);
  })
}

Subcomponent@hook:生命周期Listen to the life cycle callback of the subcomponent

  • actual use
<child @hook:mounted="listenChildMounted" />

in-for

  • Usage environment

HTML code that does not need to be compiled can use v-pre to improve performance.

  • actual use
<span v-pre>{
   
   {message}}</span>    //就算data里面定义了message,渲染完也是{
   
   {message}}

v-once

  • Usage environment

It only needs to be rendered once, which is suitable for content that will not be updated after rendering to reduce performance overhead.

  • actual use
<span v-once>{
   
   {message}}</span>    //message的值会编译后渲染,但是编译以后再次修改message的值不会触发更新
  • The difference between v-pre and v-once

v-pre is equivalent to not compiling, displaying it directly, v-once is equivalent to only compiling once, and subsequent updates will not be compiled.

View.set()

  • Usage environment

① When you directly set an array item using an index

② When you modify the length of the array

③ When adding or deleting object attributes

Due toObject.defineprototype() method limitation, the data is not updated responsively

  • actual use

Reference Detailed answers to advanced front-end interview questions

this.$set(arr,index,item);

$forceUpdate()

  • Usage environment

$set() also has certain usage restrictions. When the object does not have this attribute, $set() will report an error. In this case, directly modify the data and then use $forceUpdate() Just force the view to refresh

  • actual use
this.$forceUpdate();

keep-alive

  • Usage environment

This can be used when there is no data update on this page, or you want to save the status, and it will still look like this next time you come in. For example, if you view the list page on Taobao, click in to view the details, and then return to the list page and still go to the place you visited last time.keep-alive

  • Actual use is divided into use with routing, usemax,include,exclude, and special life cyclesactivated and deactivated

$route routing information

  • $route.query.id

Used to get the information passed by the route, such as the suffix of the route?id=1, the value obtained by $route.query.id is 1

  • $route.meta.flag

Used to get the information in the routing meta. The meta in the routing information can be customized. I usually use the nav currently selected in the navigation bar to match $route.meta.flag to get which page should be activated on the current page. a tab

  • base route

For example, all routes in Baidu need to be prefixed with/baidu, then you can set the base of the route to/baidu

export const router = new Router({
    
    
  base:'/baidu/',
}

In addition, when packaging, please modify in the block of config/index.js to '/baidu/' , otherwise the resource file path will not be found after packagingbuildassetsPublicPath

module.exports = {
    
    
    build:{
    
    
        assetsPublicPath: '/baidu/',
    }
}
  • Global routing hook

The usage scenario is generally user login authentication.

router.beforeEach((to, from, next) => {
    
    
  //一定要调用next()才能到下一个页面
  if (path === '/login') {
    
    
    next()
  }else{
    
    
    if(token){
    
    
      next();
    }else{
    
    
      next('/login');
    }  
  }
})
  • Access this in component routing hook

The hook of component routing has not been initialized at the beginning and cannot access the vue instance beforeRouteEnter (to, from, next) { // The component instance cannot be accessed here yet, this === undefined next( vm => { // Access component instance viavm}) }

$route routing information is not refreshed

  • scenes to be used

Sometimes, when you jump from /user?id=1 to /user?id=2, due to rendering the same User component, As a result, the route will be reused. At this time, the page will still be the information of user 1.

solution

  • Route guards within components
beforeRouteUpdate(to, from, next) {
    
    
    // 在当前路由改变,但是该组件被复用时调用
    // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
    // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
    // 可以访问组件实例 `this`
  },
  • <router-view>绑fix key
<router-view :key="$route.fullpath"></router-view>
  • Use watch to monitor routes
watch:{
    
    
   '$route':{
    
    
       hander(){
    
    
           // do something...
       },
       immediate:true   //如果要首次加载就触发
   }
}

$emit passes parameters and gets the values ​​​​of both parent and child components at the same time

In actual project development, you may encounter the situation where both the value of $emit and the index of the parent component must be obtained. However, according to the previous writing method, you can only get one of them. Value, either child component or parent component, you can’t have your cake and eat it too

  • Subcomponent input parameters
this.$emit('uploadSuccess',res);
  • Parent component input parameters
<Up @uploadSuccess="uploadLogoImage(index,arguments)"  />
  • Method taking parameters
uploadLogoImage(){
    
    
        console.log(arguments[0]);          //index
        console.log(arguments[1][0]);      //res
},

style penetration

  • Usage environment

Generally used when modifying plug-in styles

  • actual use

is divided into two types, generally used in and in ,No experience in use, no explanationstylus>>>less/deep/sass

>>>.el-dialog .el-dialog__body{
    
    
  padding 0
  text-align center
  border-radius 0 0 4px 4px
}
/deep/.el-dialog .el-dialog__body{
    
    
  padding 0
  text-align center
  border-radius 0 0 4px 4px
}

Object.freeze()

  • Usage environment

We all know thatvue uses Object.defineProperty for two-way binding of data, and for long lists that are only used for display, you can use Object.freeze () freezes it so that it cannot be modified, thereby improving performance

  • actual use
getList().then(res=>{
    
    
    this.list=Object.freeze(res.data.result);
})

It is worth noting that changing the value of the list will not update, but changing the reference will trigger an update.

Component communication skills

  • props
  • $emit
  • $attrs & $listeners
  • provide&inject
  • vuex
  • Observable
  • eventBus
  • $refs
  • slot-scope&v-slot
  • scopedSlots
  • $parent & $children & $root

Parent and child component parameters are obtained at the same time

  • Using environment, sometimes the parent component needs to get the value passed in the child component$emit, and also needs to get the parent componentv-for Currentindex value

Subcomponent input parameters

this.$emit('uploadSuccess',res);

Parent component input parameters

<Up @uploadSuccess="uploadLogoImage(index,arguments)"  />
  • actual use
uploadLogoImage(){
    
    
   console.log(arguments[0]);          //index
   console.log(arguments[1][0]);      //res
},

The use of mixins

  • Usage environment

Generally, mix-ins can be used in scenarios such as obtaining verification codes, favorites, likes, etc. that are common and have the same logic (some logic is different depending on the page and it is not recommended to use mix-ins).

  • actual use

Here I directly encapsulate a mix-in method for a new window in Vue. After introduction, all the mix-insdata,methods and the life cycle will be shared

//openWindow.js
export default {
    
    
  methods:{
    
    
    openUrl(url){
    
    
      const link= this.$router.resolve({
    
    path: url});
      window.open(link.href,'_blank');
    },
  }
}

//其他页面使用
import openWindow from "../../mixins/openWindow";

export default{
    
    
    mixins:[openWindow],
}
  • Note (the pages used are collectively called components)

① The mix-in is executed before the component

② When the property or method in the mix-in has the same name as the property or method in the component, the value in the component shall prevail (combined with the previous rule, because the mix-in is executed first, the component will overwrite the mix-in)

③ For example, if both page A and page B use the same mixin, the status of page A and page B are also independent.

qs

  • Usage scenario,get is transmitted using routing splicing method (?a=1&b=2) instead of json method a>

  • actual use

//安装依赖
npm install qs --save

//页面中或者直接api.js中直接序列化使用
import qs from 'qs'
qs.stringify(params)

//axios拦截器中直接使用
import qs from 'qs'
axios.interceptors.request.use(
  config => {
    
    
    if (config.method === 'get') {
    
    
      config.data = qs.stringify(config.data)
    }
)

v-for binding key is not recommended to use index

  • main reason

Sometimes the v-for list may existdelete, swap positions and other operations. In this caseThe order change of index will cause the same data to be replaced at the moment of index. Therefore, it is not recommended to bind the key of v-for to index

  • solution

It is recommended to use another variable with a unique value, such as the ID given to you by the background. Anyway, as long as it is unique and will not be repeated.

v-for is not recommended to be used with v-if

  • main reason

v-for has a higher priority than v-if. That is to say, assuming a total of 50 pieces of data, even after v-if, only 25 pieces are left to display. However, v-for has already looped through 50 pieces of data. The solution is to use a calculated attribute to filter the data first, and then v-for loops through the filtered data

  • solution

Use computed calculated attributes to filter the list, leaving only the data required after filtering

document.body.contentEditable

  • How to operate

Open the console, enterdocument.body.contentEditable=true, and then hit Enter. The webpage can be edited like word, which is very convenient for testing the page layout's ability to withstand stress

Guess you like

Origin blog.csdn.net/weixin_45506717/article/details/133634023