[Direct collection] Front-end VUE high-level interview questions (3)

86. Talk about the vue life cycle, which stage of the life cycle is sending the request, why can't it be beforeMount, mounted

answer:

 1. The life cycle of vue

1) What is the life cycle?  A Vue instance has a complete life cycle, that is, a series of processes from the beginning of creation, initialization of data, compilation of templates, mounting of Dom -> rendering, update -> rendering, unloading, etc. We call this the life cycle of Vue.

2), each life cycle stage and its hook function

The core of Vue's life cycle has gone through four stages, and there are two hook functions before and after the four stages.

The first stage: data mounting stage: assign the attributes in the configuration item data to the vue object itself, and perform data hijacking.

Two hook functions before and after this stage: beforeCreate and created

The second stage: template rendering stage: render the data of the vue object to the template.

Two hook functions before and after this stage: beforeMount and mounted

The third stage: component update stage: when the data transmission changes, the component will be re-rendered, so, to be precise, the component re-rendering stage.

Two hook functions before and after this stage: beforeUpdate and updated

The fourth stage: component destruction stage: component destruction.

Two hook functions before and after this stage: beforeDestroy and destroyed

Optionally add:

When wrapping components with keep-alive, there will be components activated and deactivated. These two hook functions are: activated and deactivated

 2. At what stage of the life cycle is the sending request, why can't it be beforeMount, mounted.

(If the initial data of the component comes from the backend) It is recommended to send the request in the hook function created. This hook function is the fastest and can also help consistency.

  Why?

  1) Why can't it be placed in beforeCreate?

  because:

 Generally speaking, after the data is returned from the backend, it will be assigned to the attributes in vue (mounted by data). In the beforeCreate hook function, the data of data has not been mounted on the vue object itself, so it cannot be used in this Used in hook functions. In the created hook function, the data has been mounted to the vue object.

2), why can't it be beforeMount, mounted

because:

    First, in these two hook functions, sending the request is a bit late, which will increase the page loading time;

    Second, vue's SSR does not support beforeMount and mounted hook functions, so putting them in created will help consistency

87. Brothers and parent-child components, how many solutions are there when vuex cannot be used, please list them?

answer:

1. Pass value between parent and child:

  1), parent to child: props, child to parent: $emit

  2)、$ref、$parent

  3), event bus (event-bus)

  4), centralized management ($root)

2. Transfer value between brothers:

  1), event bus (event-bus)

  2), centralized management ($root)

 3), first from son to father (using events), then from father to son (using props)

88. Can v-if and v-for be used at the same time?

answer:

  It can be used, but it is recommended not to use it when only a small amount of data can be obtained through v-if during the loop.

  Reason:  v-for has a higher priority than v-if, if the number of array elements traversed is relatively large, but the v-if conditions are relatively few. Will waste performance. Moreover, such inefficient code is executed every time the page is refreshed.

 Solution: You can loop the array in computed, and filter out the required data by means of filter. v-for directly loops over the results of the calculated properties (without v-if). Computed is cached, so when the original data does not change, the data will not be filtered multiple times, thus improving efficiency.

89. How to configure cross-domain in vue-cli

answer:

Using reverse proxy, in the vue-cli3+ project, create (edit) the vue.config.js file, and (add) the configuration code as follows:

module.exports = {

  devServer:{
    //设置代理
    proxy: { //代理是从指定的target后面开始匹配的,不是任意位置;配置pathRewrite可以做替换
      '/api': { //这个是自定义的,当axios访问以/api开头的请求时,会代理到 target + /api
             target: 'http://localhost:3001', //最终要访问的服务器地址
            changeOrigin: true, //创建虚拟服务器
             pathRewrite: {
                '^/api': ''    //重写接口,去掉/api, 在代理过程中是否替换掉/api/路径
          }
        }
      }
   }
}

90. What is v-bind used for?

answer:

      The v-bind command handles the attribute of the tag as dynamic . The attribute name and attribute value can be processed into attributes in vue respectively, and the attribute value is usually processed into dynamic.

The format is as follows:

1. Dynamic binding of attribute valuesv-bind:html属性="数据" :   shorthand: html attribute="data"`  

Example:

<img v-bind:src="imgstr"></div>

new Vue({
    data:{
        imgstr:'./imgs/1.jpg'
    }
})

2.  Dynamic binding of attribute names :v-bind:[属性名]="数据"

At this point, the attribute value is also dynamic

Example:

<div v-bind:[attr]="idname"  >我是div</div>

  new Vue({
        el: "#app",
        data:{
            attr:"class",
            idname:"div01"
        }
    })

91. Talk about the understanding of slots

answer:

1. The function of the slot:

     Slots are used to handle the content of components. Slots determine where in the component's template the content of the component is placed. <slot>The slot is completed using the official components provided by vue .

2. The slots in vue are divided into:

1), a single slot

   When there is only one slot in the component, the slot does not need to be named. The default name is: default

Example:

//1、定义组件
let book = {
        template: `
            <div>
               <p>我是上p</p>
           <!--这是插槽,该组件的内容将会渲染在此处 -->
               <slot></slot>
               <p>我是下p</p>
            </div>
        `,
    }

//2、父组件的模板
<div id="box">
    <book>
       <!--放在组件book标签的内容,最终会渲染在book标签的<slot>处。-->
       <img src="imgs/2.jpg" />
    </book>
</div>

2), named slot

    But when there are more than one slot in the component, you need to name the component and use the name to distinguish different slots. Use the name attribute of the official component slot to name the slot

Format:

<slot name="插槽的名字"></slot>

Example:

//1、组件:
    let book = {
        template: `
            <div>
               <p>我是上p</p>
        <!--具名插槽,该插槽起名为s1-->
               <slot name="s1"></slot>
               <p>我是中p</p>
        <!--具名插槽,该插槽起名为s2-->
               <slot name="s2"></slot>
               <p>我是下p</p>
            </div>
        `,
    }

//2、父组件模板里:

<div id="box">
    <book>
      <!--以下内容插在name为s1的插槽处-->
        <template v-slot:s1>
            <img src="imgs/2.jpg" />
        </template>
      <!--以下内容插在name为s2的插槽处-->
        <template v-slot:s2>
            <div>我是div</div>
        </template>
  </book>
</div>

92. What is the difference between $nextTick understanding and timer? Delayed execution

answer:

1, $nextTick understanding:

     When vue updates the DOM, it uses an asynchronous update queue. The purpose is to improve performance and avoid unnecessary repeated DOM updates. That is: after the data is updated in vue, the DOM will not be updated immediately, but the DOM update caused by the data will be put into the asynchronous update queue. Wait for the next event loop (tick), and render the UI between two ticks.

     According to this idea, the programmer cannot immediately obtain the updated DOM after changing the data, and does not know when the DOM can be updated. Based on this, vue provides the $nextTick function. Programmers only need to   put the " code for manipulating the updated DOM "   into the callback function of $nextTick. Callback function called by $nextTick after updating the DOM.

Example:

this.msg = "hello"

this.$nextTick(()=>{

     操作“this.msg影响的DOM”的代码。

})

2. What is the difference between $nextTick understanding and timer

Same: both lazy loading, both use event queue

different:

1) The timer is the head of the next queue.

2) $nextTick()It is the last one in the current queue. The callback function of $nextTick() is executed before the timer.

93. How is event-bus used?

event-bus is an event bus , which uses a global vue object to complete event binding and event triggering.

When: We need to pass the data of A component to B component, introduce the global vue object in both components A and B. Then, bind the event in the B component, trigger the event in the A component, and then pass the data of the A component to the B component.

Example:

//1、全局的vue对象: bus.js
export default new Vue();//vue 对象具有 $on  和 $emit  方法

//2、B组件的代码
import bus from "./bus.js"

export default {
  ………………
    data(){
        return {
            bookmsg:""
        }
    },
    created(){
        // 绑定事件(用全局变量bus绑定一个事件)
        bus.$on("eclick",str=>{
           this.bookmsg = str;
        })
    }
}

//3、A组件的代码

import bus from "./bus.js"

export default {
  ………………
    data(){
        return {
             msg:"要传给B组件的数据"
        }
    },
    methods:{
        chuan(){
            // 触发事件(用全部变量bus触发事件)
            bus.$emit("eclick",this.msg);
        }
    }
}

94. The difference between mounted and created

answer:

Mounted and created are both hook functions of the Vue object life cycle, and the timing of execution is different.

1. created is a hook function that will be called after the data  of the data configuration item is mounted to the vue object itself .

 at this time,

 1) Use this. to get the data in data.

  2), but the data has not been rendered to the template. Therefore, when accessing the dom, the content is still the original template content.

2. mounted is a hook function that will be called after the component's template is rendered for the first time .

 at this time,

    The data in data has been rendered to the template. Therefore, when accessing the dom, the effect is already the same as that seen on the page.

95. What is the principle of v-model

answer:

1. The role of the v-model command

 The v-model directive in vue completes two-way binding and is used on form elements. Two-way binding means that M affects V. V also affects M. That is: the value entered on the page can be updated synchronously to the data attribute of the relevant binding, and the value of the input control on the page will also be updated when the data binding attribute is updated.

2. The principle of v-model      

  The v-model directive is a syntactic sugar for property bindings and events. Vue uses different properties and events based on different form elements.

as follows:

  • The text and textarea elements use  value properties and  input events;

  • checkbox and radio use  checked properties and  change events;

  • The select field will  value act as a prop and will  change act as an event.

Taking the text box as an example to analyze the principle, the following is the code:

<!-- V -->
 <div id="app">
     <!--文本框使用value属性和input事件-->
     <input type="text" v-bind:value="msg" @input="changeMsg"  >
 </div>

//M:

 let vm = new Vue({
       el: "#app",
       data: {
           msg:"hi"
       },
       methods: {
           changeMsg(e){
               this.msg = e.target.value;
           }
       }
 })

However, the code for using v-model to accomplish the above functions is as follows:

<!-- V-->
<div id="app">
  <!-- 此处不需要使用value属性和input事件,直接使用v-mdoel指令即可 -->
    <input type="text" v-model="msg"  >
</div>

// M:model

let vm = new Vue({
    el: "#app",
    data: {
        msg:"hi"
    }
})

96. Why must the data configuration in the vue component be a function (each component is an instance of vue)

In order to ensure the independence of data on each instance, vue stipulates that functions must be used instead of objects. Because of the use of objects, the data used on each instance (component) affects each other, which is of course not what we want. An object is a reference to a memory address. If an object is defined directly, this object will be used between components, which will cause data between components to affect each other. Functions have inner scope, which can solve this problem.

97. The difference between computed and watch in vue

  1. Both watch and computed are based on Vue's dependency tracking mechanism. When a certain dependent data (dependent data: simple understanding is the instance data placed under objects such as data) changes, all dependencies that depend on this data The data will change automatically, that is, the relevant functions are automatically called to realize the data change. When the value of the dependency changes, some complex operations can be done in watch, but the dependency in computed is just that one value depends on another value, which is a value dependency.

  2. Application scenarios: computed: used to process complex logical operations; one data is affected by one or more data; used to handle situations that cannot be handled by watches and methods, or are inconvenient to handle. For example, complex expressions in the processing template, the change relationship between the quantity of products in the shopping cart and the total amount, etc. watch: It is used to deal with the need to perform certain specific business logic operations when an attribute changes, or to perform asynchronous or expensive operations when data changes; a data change affects multiple data. For example, it is used to monitor routes, special processing of input input box values, etc.

  3. the difference:

  • computed

    • Called when the initialization display or related data, props and other attribute data change;

    • The calculated attribute is not in data, it is a new value calculated based on the data in data or props, and this new value changes according to the change of the known value;

    • The method of defining the computed attribute in the computed attribute object is called in the form of attribute access, just like the data attribute in the data object;

    • If the computed attribute value is a function, then the get method will be used by default, and there must be a return value. The return value of the function is the attribute value of the attribute;

    • The computed attribute value will cache the calculation results by default. In repeated calls, as long as the dependent data remains unchanged, the calculation results in the cache are directly fetched. Only when the dependent data changes, computed will be recalculated;

    • In computed, attributes have a get and a set method, and when the data changes, the set method is called.

  • watch

    • It is mainly used to monitor the changes of some specific data, so as to perform some specific business logic operations, which can be regarded as a combination of computed and methods;

    • Data sources that can be monitored: data, props, data in computed;

    • watch supports asynchronous;

    • Caching is not supported, and the monitored data changes will directly trigger the corresponding operation;

    • The listening function has two parameters, the first parameter is the latest value, the second parameter is the value before input, the order must be new value, old value.

98. The life cycle of vue? Why should network requests be mounted in mounted?

  1. The life cycle of vue2

  • Initialization phase:

    • beforeCreate

    • created

  • mount phase

    • beforeMount

    • mounted

  • update phase

    • beforeUpdate

    • updated

  • uninstall phase

    • beforeDestroy

    • destroyed

  • Cache component related

    • activated

    • deactivated

  • Handling errors related

    • errorCaptured

  1. The life cycle of vue3 is added on the basis of vue2:

  • renderTracked: Called when tracking virtual DOM re-rendering. The hook receives the debugger event as a parameter. This event tells you which action tracked the component and the action's target object and key.

  • renderTriggered: Called when a virtual DOM re-render is triggered. Similar to renderTracked, it accepts debugger event as a parameter. This event tells you what action triggered the re-render, and the target object and key for that action. 13 in total

  1. BeforeCreate and created are removed from the life cycle of the combination API of vue3, because the events at creation time can be called directly in the setup. Add on to the front of the other 11 life cycles, such as: mounted -> onMounted, beforeDestroy -> onDeforeDestroy

  2. Why should network requests be mounted in mounted? Data is only generated in the Created life cycle, and the data returned by the request needs to be mounted on the data, so the request can be initialized in Created, but the DOM has not been initialized at the time of Created; the DOM is initialized and rendered in the Mounted life cycle. However, the requests are asynchronous, so they don't block the main thread of page rendering. So it is feasible to place the request in both created and mounted. If our request does not need to obtain/rely on/depend on/change the DOM, then the request can be placed in Created. Otherwise, it can be placed in Mounted. Doing so will be more secure, and it will also ensure that the page will not flicker.

99. Vue's instructions encapsulate those commonly used instructions in the project?

In vue we can use the Vue.directive() method to register global directives. It is also possible to register only local directives with the directives option.

  • Input box anti-shake command v-debounce

const debounce = {
  inserted: function (el, binding) {
    let timer;
    el.addEventListener("keyup", () => {
      if (timer) {
        clearTimeout(timer);
      }
      timer = setTimeout(() => {
        binding.value();
      }, 1000);
    });
  },
};

export default debounce;
  • Copy and paste command v-copy

const copy = {
  bind(el, { value }) {
    el.$value = value;
    el.handler = () => {
      if (!el.$value) {
        // 值为空的时候,给出提示。可根据项目UI仔细设计
        console.log("无复制内容");
        return;
      }
      // 动态创建 textarea 标签
      const textarea = document.createElement("textarea");
      // 将该 textarea 设为 readonly 防止 iOS 下自动唤起键盘,同时将 textarea 移出可视区域
      textarea.readOnly = "readonly";
      textarea.style.position = "absolute";
      textarea.style.left = "-9999px";
      // 将要 copy 的值赋给 textarea 标签的 value 属性
      textarea.value = el.$value;
      // 将 textarea 插入到 body 中
      document.body.appendChild(textarea);
      // 选中值并复制
      textarea.select();
      const result = document.execCommand("Copy");
      if (result) {
        console.log("复制成功"); // 可根据项目UI仔细设计
      }
      document.body.removeChild(textarea);
    };
    // 绑定点击事件,就是所谓的一键 copy 啦
    el.addEventListener("click", el.handler);
  },
  // 当传进来的值更新的时候触发
  componentUpdated(el, { value }) {
    el.$value = value;
  },
  // 指令与元素解绑的时候,移除事件绑定
  unbind(el) {
    el.removeEventListener("click", el.handler);
  },
};

export default copy;
  • Long press command v-longpress

const longpress = {
  bind: function (el, binding, vNode) {
    if (typeof binding.value !== "function") {
      throw "callback must be a function";
    }
    // 定义变量
    let pressTimer = null;
    // 创建计时器( 2秒后执行函数 )
    let start = (e) => {
      if (e.type === "click" && e.button !== 0) {
        return;
      }
      if (pressTimer === null) {
        pressTimer = setTimeout(() => {
          handler();
        }, 2000);
      }
    };
    // 取消计时器
    let cancel = (e) => {
      if (pressTimer !== null) {
        clearTimeout(pressTimer);
        pressTimer = null;
      }
    };
    // 运行函数
    const handler = (e) => {
      binding.value(e);
    };
    // 添加事件监听器
    el.addEventListener("mousedown", start);
    el.addEventListener("touchstart", start);
    // 取消计时器
    el.addEventListener("click", cancel);
    el.addEventListener("mouseout", cancel);
    el.addEventListener("touchend", cancel);
    el.addEventListener("touchcancel", cancel);
  },
  // 当传进来的值更新的时候触发
  componentUpdated(el, { value }) {
    el.$value = value;
  },
  // 指令与元素解绑的时候,移除事件绑定
  unbind(el) {
    el.removeEventListener("click", el.handler);
  },
};

export default longpress;
  • Prohibition of emoticons and special characters v-emoji

let findEle = (parent, type) => {
  return parent.tagName.toLowerCase() === type
    ? parent
    : parent.querySelector(type);
};

const trigger = (el, type) => {
  const e = document.createEvent("HTMLEvents");
  e.initEvent(type, true, true);
  el.dispatchEvent(e);
};

const emoji = {
  bind: function (el, binding, vnode) {
    // 正则规则可根据需求自定义
    var regRule = /[^u4E00-u9FA5|d|a-zA-Z|rns,.?!,。?!…—&$=()-+/*{}[]]|s/g;
    let $inp = findEle(el, "input");
    el.$inp = $inp;
    $inp.handle = function () {
      let val = $inp.value;
      $inp.value = val.replace(regRule, "");

      trigger($inp, "input");
    };
    $inp.addEventListener("keyup", $inp.handle);
  },
  unbind: function (el) {
    el.$inp.removeEventListener("keyup", el.$inp.handle);
  },
};

export default emoji;

Image lazy loading v-LazyLoad

const LazyLoad = {
  // install方法
  install(Vue, options) {
    const defaultSrc = options.default;
    Vue.directive("lazy", {
      bind(el, binding) {
        LazyLoad.init(el, binding.value, defaultSrc);
      },
      inserted(el) {
        if (IntersectionObserver) {
          LazyLoad.observe(el);
        } else {
          LazyLoad.listenerScroll(el);
        }
      },
    });
  },
  // 初始化
  init(el, val, def) {
    el.setAttribute("data-src", val);
    el.setAttribute("src", def);
  },
  // 利用IntersectionObserver监听el
  observe(el) {
    var io = new IntersectionObserver((entries) => {
      const realSrc = el.dataset.src;
      if (entries[0].isIntersecting) {
        if (realSrc) {
          el.src = realSrc;
          el.removeAttribute("data-src");
        }
      }
    });
    io.observe(el);
  },
  // 监听scroll事件
  listenerScroll(el) {
    const handler = LazyLoad.throttle(LazyLoad.load, 300);
    LazyLoad.load(el);
    window.addEventListener("scroll", () => {
      handler(el);
    });
  },
  // 加载真实图片
  load(el) {
    const windowHeight = document.documentElement.clientHeight;
    const elTop = el.getBoundingClientRect().top;
    const elBtm = el.getBoundingClientRect().bottom;
    const realSrc = el.dataset.src;
    if (elTop - windowHeight < 0 && elBtm > 0) {
      if (realSrc) {
        el.src = realSrc;
        el.removeAttribute("data-src");
      }
    }
  },
  // 节流
  throttle(fn, delay) {
    let timer;
    let prevTime;
    return function (...args) {
      const currTime = Date.now();
      const context = this;
      if (!prevTime) prevTime = currTime;
      clearTimeout(timer);

      if (currTime - prevTime > delay) {
        prevTime = currTime;
        fn.apply(context, args);
        clearTimeout(timer);
        return;
      }

      timer = setTimeout(function () {
        prevTime = Date.now();
        timer = null;
        fn.apply(context, args);
      }, delay);
    };
  },
};

export default LazyLoad;

Permission verification command v-premission

function checkArray(key) {
  let arr = ["1", "2", "3", "4"];
  let index = arr.indexOf(key);
  if (index > -1) {
    return true; // 有权限
  } else {
    return false; // 无权限
  }
}

const permission = {
  inserted: function (el, binding) {
    let permission = binding.value; // 获取到 v-permission的值
    if (permission) {
      let hasPermission = checkArray(permission);
      if (!hasPermission) {
        // 没有权限 移除Dom元素
        el.parentNode && el.parentNode.removeChild(el);
      }
    }
  },
};

export default permission;
  • Implement page watermark v-waterMarker

function addWaterMarker(str, parentNode, font, textColor) {
  // 水印文字,父元素,字体,文字颜色
  var can = document.createElement("canvas");
  parentNode.appendChild(can);
  can.width = 200;
  can.height = 150;
  can.style.display = "none";
  var cans = can.getContext("2d");
  cans.rotate((-20 * Math.PI) / 180);
  cans.font = font || "16px Microsoft JhengHei";
  cans.fillStyle = textColor || "rgba(180, 180, 180, 0.3)";
  cans.textAlign = "left";
  cans.textBaseline = "Middle";
  cans.fillText(str, can.width / 10, can.height / 2);
  parentNode.style.backgroundImage = "url(" + can.toDataURL("image/png") + ")";
}

const waterMarker = {
  bind: function (el, binding) {
    addWaterMarker(
      binding.value.text,
      el,
      binding.value.font,
      binding.value.textColor
    );
  },
};

export default waterMarker;
  • Drag command v-draggable

const draggable = {
  inserted: function (el) {
    el.style.cursor = "move";
    el.onmousedown = function (e) {
      let disx = e.pageX - el.offsetLeft;
      let disy = e.pageY - el.offsetTop;
      document.onmousemove = function (e) {
        let x = e.pageX - disx;
        let y = e.pageY - disy;
        let maxX =
          document.body.clientWidth -
          parseInt(window.getComputedStyle(el).width);
        let maxY =
          document.body.clientHeight -
          parseInt(window.getComputedStyle(el).height);
        if (x < 0) {
          x = 0;
        } else if (x > maxX) {
          x = maxX;
        }

        if (y < 0) {
          y = 0;
        } else if (y > maxY) {
          y = maxY;
        }

        el.style.left = x + "px";
        el.style.top = y + "px";
      };
      document.onmouseup = function () {
        document.onmousemove = document.onmouseup = null;
      };
    };
  },
};
export default draggable;

100. How to adapt the mobile terminal of vue, how to use rem

We can refer to the solution provided by the vant-ui component library for the mobile adaptation of vue. Use the amfe-flexible (for automatic definition and font size) plugin and postcss-pxtorem (for automatically converting px to rem) plugin to import "amfe-flexible" in main.ts and create a new .postcssrc.js file in the root directory

module.exports = {
  plugins: {
    "postcss-pxtorem": {
      rootValue: 37.5,
      propList: ["*"],
    },
  },
};

rem is relative to the multiple of the font. If our entire project uses rem as the unit, then when we make the mobile terminal responsive, we only need to change the size of the font to achieve adaptation.

101. Background management system user verification authority

  1. After the login user fills in the account number and password, verify to the server whether it is correct. After the login is successful, the server will return a token (the token is a key that can uniquely identify the user's identity), and then we will store the token in the local localstorage In this way, the user's login status can be remembered when the page is opened or refreshed next time, and there is no need to go to the login page to log in again. In order to ensure security, all token validity periods (Expires/Max-Age) in the background are Session, that is, they are lost when the browser is closed. Re-opening the browser requires re-login verification, and the back-end will re-refresh the token at a fixed time every week to allow all background users to log in again to ensure that the background users will not be used by others due to computer loss or other reasons.

  2. Intercepting the route to judge the page will first check whether there is a token in localstorage. If not, go through the previous part of the process to log in again. If there is a token, it will return the token to the backend to pull user_info to ensure that the user information is Newest. Of course, if you have done single sign-on, it is also possible to store user information locally. When you log in on one computer, the other is pulled offline, so always log back in to get the latest content.

  3. The authority control front end will have a routing table, which represents the authority accessible to each route. After the user logs in, obtain the user's role through the token, dynamically calculate the corresponding authorized route according to the user's role, and then dynamically mount the route through router.addRoutes. But these controls are only at the page level. To put it bluntly, no matter how the front-end permission control is done, it is not absolutely safe, and the back-end permission verification cannot escape. The front-end controls the page-level permissions. Users with different permissions display different sidebars and limit the pages they can enter (also do a little button-level permission control), and the back-end will verify every operation involving the request. Whether it has permission for this operation, every background request, whether it is get or post, will let the front-end carry the user's token in the request header, and the back-end will verify whether the user has permission to perform the operation based on the token. If there is no permission, a corresponding status code is thrown, and the front end detects the status code and makes corresponding operations.

  4. Use vuex to manage the routing table, and render sidebar components according to the routes accessible in vuex.

  • When creating a vue instance, mount vue-router, but at this time, vue-router mounts some login or public pages that do not require permissions.

  • After the user logs in, obtain the role, compare the role with the required authority of each page of the routing table, and generate a routing table accessible to the end user.

  • Call router.addRoutes(store.getters.addRouters) to add user-accessible routes.

  • Use vuex to manage the routing table, and render sidebar components according to the routes accessible in vuex.

102. How to solve the problem that data may be lost when vuex makes a data request to refresh the page

Because the data in the store is stored in the running memory, when the page is refreshed, the page will reload the vue instance, and the data in the store will be reassigned and initialized. So we can save a copy of the data to the local storage (localStorage or sessionStorage) while modifying the store data. The content of the local storage is stored in the browser and will not be lost due to refresh. We can also use third-party packages such as vuex-persistedstate to help us persist data in vuex.

103. What are the specific differences between vue2 and vue3, please list them one by one

  1. The use of ts to rewrite the source code is now very popular in typescript. There is a reason for its rise, because for large-scale projects, there is no type declaration, and later maintenance and code reading are headaches. Therefore, the majority of coders urgently need Vue can perfectly support ts. Vue2 uses Facebook's Flow for type checking, but because of inference problems in some cases, vue3 uses typescript to rewrite the source code. One for better type checking and the other for embracing ts.

  2. Use proxy instead of defineProperty. We know that the core of vue2.x two-way binding is Object.defineProperty(), so Vue's deep monitoring of array objects cannot be realized. So vue3 uses proxy to rewrite the two-way binding. Proxy can monitor the whole without caring what properties are in it, and there are 13 configuration items in Proxy, which can do more detailed things, which was not possible with the previous defineProperty.

  3. Improvement of Diff algorithm Vue3 adds optimizations such as static markup, element promotion and event caching on the basis of vue2's diff algorithm. makes it faster.

  4. Package volume change Vue2 officially says that the runtime packager is 23k, but this is only when dependencies are not installed. With the increase of dependent packages and framework features, sometimes unnecessary, unused code files are packaged in, so In the later stage, the project will be large, and the packaged files will be particularly large and large. In Vue 3, we've done this by moving most of our global API and internal helpers to Javascript's module.exports property. This allows the module bundler in modern mode to statically analyze module dependencies and remove code related to unused module.exports properties. The template compiler also generates tree-shaking-friendly code that imports helpers for a feature only when that feature is actually used in a template. Despite the many new features added, Vue 3's minified baseline size is about 10 KB, less than half that of Vue 2.

  5. Other Api and function changes

  • Global API

  • template directive

  • components

  • render function

  • vue-cli provides Vue 3 presets since v4.5.0

  • Vue Router 4.0 provides Vue 3 support with many breaking changes

  • Vuex 4.0 provides Vue 3 support, and its API is basically the same as 2.x

  1. Component Basic Structure

We don't have to write the only root element when creating components. Removed filters in vue2.

  1. life cycle difference

Added two new life cycles, renderTracked and renderTriggered.

  1. Added composition api

We can use the setup function to use the function of custom hooks similar to react, mainly to solve the problem of separation of logical concerns.

104. What are the advantages of vue operating virtual DOM? Didn’t he make an extra layer of virtual DOM, why is it faster than native DOM manipulation

It is necessary for us to understand the whole process of converting a template into a view:

  • Vue.js converts the template template into a rendering function (render) through compilation, and a virtual node tree can be obtained by executing the rendering function.

  • When operating on the Model, it will trigger the Watcher object in the corresponding Dep. The Watcher object will call the corresponding update to modify the view. This process is mainly to compare the differences between the old and new virtual nodes, and then perform DOM operations to update the view according to the comparison results.

To put it simply, on the underlying implementation of Vue, Vue compiles templates into virtual DOM rendering functions. Combined with Vue's built-in response system, when the state changes, Vue can intelligently calculate the minimum cost of re-rendering the component and apply it to the DOM operation.

picture

So what are the advantages of vue operating virtual DOM?

  • Have the advantage of cross-platform Since Virtual DOM is based on JavaScript objects and does not depend on the real platform environment, it has cross-platform capabilities, such as browser platforms, Weex, Node, etc.

  • The operation of DOM is slow, and the efficiency of js operation is high. We can put the DOM comparison operation in the JS layer to improve efficiency. Because the execution speed of DOM operations is far lower than that of Javascript, a large number of DOM operations are transferred to Javascript, and the patching algorithm is used to calculate the nodes that really need to be updated, and the DOM operations are minimized, thereby significantly improving performance. . Virtual DOM is essentially a cache between JS and DOM. It can be compared to CPU and hard disk, since the hard disk is so slow, we add a cache between them; since DOM is so slow, we add a cache between their JS and DOM. The CPU (JS) only operates on the memory (Virtual DOM), and writes the changes to the hard disk (DOM) at the end

  • Improving rendering performance The advantage of Virtual DOM is not a single operation, but a reasonable and efficient update of the view under a large number of frequent data updates. In order to achieve efficient DOM operations, a set of efficient virtual DOM diff algorithms is necessary. We use the diff algorithm, the core of the patch, to find out the nodes that need to be updated in the DOM this time and update them, and not update the others. For example, modify a certain model 100 times, from 1 to 100, then with the Virtual DOM cache, only the last modified patch will be applied to the view. What is the implementation process of the diff algorithm?

So why is it faster than native DOM manipulation? First of all, every time we operate the dom, we will execute the 5 steps of the browser, especially when there are a lot of loops, we don’t know whether to modify it after each loop, so we have to repeat this process every time , causing unnecessary rendering. But in the actual development process, we will find that the virtual dom is not faster than the real dom. You Yuxi has answered this question on Zhihu: This is a trade-off between performance vs. maintainability. The meaning of the framework is to cover up the underlying DOM operations for you, allowing you to describe your purpose in a more declarative way, thus making your code easier to maintain. No framework can be faster than pure manual optimization of DOM operations, because the DOM operation layer of the framework needs to deal with any operations that may be generated by the upper-level API, and its implementation must be universal. For any benchmark, I can write manual optimizations that are faster than any framework, but what's the point? When building an actual application, do you do manual optimization for every place? For maintainability reasons, this is obviously not possible. The guarantee that the framework gives you is that I can still provide you with decent performance without manual optimization.

105. How do you deal with token expiration? Have you ever done token renewal?

In development, we often encounter the use of tokens. The role of tokens is to verify whether users are logged in. Therefore, when requesting some resources that can only be viewed when they are logged in, we need to carry tokens.

The token set by the general back-end interface is time-sensitive, and it will become invalid after timeout. After the expiration, the processing strategy will generally do two kinds of processing:

  • One is to jump directly to the login page and log in again.

  • Another way is to automatically refresh the token if the token invalidation information is returned, and then continue to complete the unfinished request operation.

106. The underlying implementation principle of vue

  • Use Object.defineProperty to hijack the data on data.

  • Vue2.0 monitors data changes by setting the setter/getter methods of object properties, collects dependencies through getters, and each setter method is an observer, notifying subscribers to update the view when data changes.

107. The life cycle of Vue, the difference between created and mounted

1、created

Indicates that the component instance has been fully created, the data data has been hijacked by Object.defineProperty, and the properties have been successfully bound, but the real dom has not been generated, and $el is not yet available.

2、mounted

The view node corresponding to the el option has been replaced by the newly created vm.$el and mounted to the instance. At this point, the responsive data has been rendered.

108. I wrote the mall with vue, click to enter the details page from the list page, and when exiting from the details page, how to keep the page scrolling value before entering the details page.

Use <keep-alive> to wrap the list page, and the wrapped list page has two life cycles: activated and deactivated. When leaving the list page, record the scroll bar position of the page in deactivated. When entering the list page again, use this.$el.scrollTop in activated to scroll the page to the position recorded when leaving.

109. Talk about your understanding of vue

  • Vue is a data-driven MVVM framework. Compared with traditional DOM libraries, Vue has a layer of virtual DOM. Whenever data is updated, the virtual DOM is triggered to perform a diff operation to find the smallest change node, which greatly saves DOM operation performance.

  • Vue is componentized. In a single-page application, each component is equivalent to a building block to build a huge application system. Components can be understood as more granular "HTML elements", which is conducive to rapid development and efficient reuse of components.

  • Vue has a complete set of instructions, which greatly reduces the development difficulty of developers and improves development efficiency.

  • Although Vue has many advantages, it still has some defects. For example, complex business pages are usually too long, and the data and logic corresponding to data, methods, computed, and watches are intertwined and difficult to maintain.

110. Talk about the understanding of virtual DOM

  • In Vue, virtual DOM is essentially a fixed-format JSON data, which is used to describe the real DOM structure, and uses various flags to mark dynamic DOM nodes.

  • The virtual DOM data is stored in the corresponding memory structure of the application, which has a faster data exchange speed.

  • Whenever there is a change in data, a new virtual DOM will be generated, and further diff operations will occur to find the smallest dirty node and reduce unnecessary DOM overhead. This is also the root cause of Vue's better performance.

111. Talk about the usage of provide

  • In the parent component, use the provide option to "provide data" to the vue component tree, the syntax is: provide:{a: 1}

  • In descendant child components, use the inject option to "take out data" from the vue component, the syntax is: inject: ['a']

112. Talk about the pitfalls encountered by element ui

  1. The form setting trigger event is blur, but when ctrl+A is selected and then deleted, the change event is triggered again, and an original error is prompted

    • Solution: trigger is set totrigger: ['blur', 'change']

  2. Use the el-dialog mask layer to cover the display content

    • Reason: When the position value of the outer layout of the Dialog is one of fixed, absolute, and relative, it will be covered by the mask.

    • Solution:v-bind:modal-append-to-body="false"

  3. Using el-select cannot inherit the width of the parent element

    • Reason: el-select itself is inline-block

    • Solution: Manually set the width of el-select

113. How to modify the style of element ui dynamic components

To modify the style of the elementUI component, you can use the following two methods

1. Global styles

Override the style of the elementUI component by selecting the weight, such as modifying the check box to rounded corners:

<style>
        .edit-item .el-checkbox__inner {
          border-radius: 50%;
        }
</style>

However, this method is a global style, which will affect all check boxes on the page. If you do not want to affect the styles of other pages, you can use the second method

2. Partial style

<style scoped>
        .edit-item .el-checkbox__inner {
          border-radius: 50%;
        }
</style>

However, if only the scoped attribute is set, the style cannot take effect, because the above style will be compiled into an attribute selector, but the internal structure of the elementUI component cannot add the html attribute, and the above style will be compiled into the following code:

.edit-item[data-v-6558bc58] .el-checkbox__inner[data-v-6558bc58] {
      border-radius: 50%;
    }

>>>The solution is also very simple, just add in the selector

<style scoped>
        .edit-item >>> .el-checkbox__inner {
          border-radius: 50%;
        }
</style>

If it is written in sass or less, you can also use/deep/

<style scoped lang="scss">
        .edit-item /deep/ .el-checkbox__inner {
          border-radius: 50%;
        }
</style>

The above writing styles will be compiled into the following styles:

.edit-item[data-v-6558bc58] .el-checkbox__inner{}
  1. So the styles in elementUI can be successfully overwritten

114. What are the key values ​​in vue and react mainly used for?

The key is the identification of the virtual DOM object. The key plays an extremely important role when updating the display. Both vue and react use the diff algorithm to compare the old and new virtual nodes. The function of the key is to execute the diff algorithm faster and more efficiently. Accurately find the corresponding virtual node, thereby improving the diff speed.

115. The difference between route and router

route and  router are two objects that are often operated in vue-router, which  routerepresent the current routing information object, including the information obtained by parsing the current URL, including the current path, parameters, query object, etc., and are generally used to pass in when obtaining a jump parameters. routerThe object is an instance of global routing, an instance of the router construction method, general user routing jumps, such as router.push(), router.replace() and other methods

116. What are the advantages and performance advantages of vue and react compared to traditional ones

  1. Component-based development, higher development efficiency

    Both React and Vue encourage the use of component development. This essentially suggests that you split your application into modules with well-defined functions, and each module can be related in a specific way. This enables better management of functional modules and reuse, and better division of labor and collaboration in team projects

  2. VirtualDOM, higher performance

    The operation on the real DOM is very slow, so both Vue and React have implemented the virtual DOM. The user's modification of the data is first reflected on the virtual DOM instead of directly operating the real DOM, and then optimized in the virtual DOM link, such as only modifying the difference item , merge when frequently modifying the virtual DOM, and then modify the part that needs to be changed in the real DOM at one time, and finally perform typesetting and redrawing in the real DOM, reducing the loss of too many DOM node typesetting and redrawing, etc.

  3. Separation of Data and Structure

  4. two-way data binding

    Vue can be implemented through the v-model directive, and react can be implemented through one-way binding + events

  5. Strong Surrounding Ecology

    Both Vue and React have a powerful ecology, such as routing, state management, scaffolding, etc. Users can choose according to their needs without reinventing the wheel

117. Principles of virtual DOM implementation

Let's first take a look at the process of rendering a page by the browser. It takes about 5 steps:

  1. Parse HTML elements and build a DOM tree

  2. Parse CSS and generate page CSS rule tree (Style Rules)

  3. Associate the DOM tree with the CSS rule tree to generate a render tree

  4. Layout (layout/reflow): The browser sets the position and size of each node in the Render tree on the screen

  5. Draw the Render tree: draw page pixel information to the screen

As we all know, the biggest overhead of a page in a browser is the operation of DOM nodes. Most of the performance problems of the page are caused by DOM operations. When we use libraries such as native js or jquery to operate the DOM, the browser will build the DOM tree from Start to execute the entire process above, so frequent manipulation of the DOM will cause unnecessary calculations, rearrangement and redrawing, resulting in page freezes and affecting user experience

Therefore, reducing the operation of DOM can achieve the purpose of performance optimization. In fact, this is what virtual DOM does. The realization principle of virtual DOM (VirtualDOM) mainly includes the following three parts:

  1. Use JavaScript objects to simulate the real DOM tree and abstract the real DOM

  2. diff algorithm — compare the old and new virtual DOM to get the difference object

  3. The pach algorithm — applies diffed objects to the real DOM tree

Virtual DOM is essentially a javascript object. Data modification will generate a new virtual DOM (a new javascript object), and then compare it with the old virtual DOM to get the difference between the two objects, and finally only update the difference object content to the real DOM, so that the real DOM can be modified as little as possible to achieve performance optimization

118. How to implement role authority assignment

There is more or less a problem involved in the process of developing mid- and background applications: permissions , which simply means that different users have different operating capabilities in the system.

However, in practical applications, we generally do not directly assign permissions to users, because such operations are too cumbersome for systems with a large number of users, so we generally introduce the concept of roles based on the RBAC (Role-Based Access Control) permission model . Through the media transition of the role, the authority is first assigned to the role, and then the corresponding user is associated, and the corresponding user inherits the authority of the role

Users and roles, roles and permissions are many-to-many relationships

Advantages of introducing character media:

  1. Realized the decoupling of users and permissions

  2. Improve the efficiency of permission configuration

  3. Reduced post-maintenance costs

119. Advantages and disadvantages of two-way data binding and one-way data flow

The so-called data binding refers to the mapping relationship between Viewlayers Model.

  • One-way data binding:Model the update of the data will trigger Viewthe update of the data, but Viewthe update of the code will not trigger Modelthe update of the data, and their functions are one-way.

    Advantages: All state changes can be recorded and tracked, state changes are triggered by manual calls, and the source is easy to trace.

    Disadvantage: There will be a lot of similar boilerplate codes, and the amount of code will increase accordingly.

  • Two-way data binding:Model the update of the data will trigger Viewthe update of the data, and Viewthe update of the code will also trigger Modelthe update of the data, and their functions are mutual.

    Advantages: It is convenient and simple v-modelto use , and tedious or repetitive onChangeevents can be omitted to handle the change of each form data (reduce the amount of code).

    Disadvantages: It is a black-box operation and cannot track the changes of two-way bound data well.

120. How does Vue implement two-way binding?

Vue's two-way data binding is achieved through data hijacking combined with the publisher-subscriber model. To achieve this two-way data binding, the necessary conditions are:

  1. Implement a data listener Observer, which can monitor all the properties of the data object, and if there is any change, it can get the latest value and notify the subscribers

  2. Implement a command parser Compile, scan and parse the command of each element node, replace the data according to the command template, and bind the corresponding update function

  3. Implement a Watcher as a bridge connecting Observer and Compile, which can subscribe to and receive notifications of each property change, and execute the corresponding callback function bound by the instruction to update the view

  4. MVVM entry function, integrating the above three

supplementary answer

In the new Vue, by achieving data hijacking in the Observer  Object.defineProperty() , the getter and setter properties of all data are proxied. Every time the setter is triggered, the Watcher will be notified through Dep. The Watcher acts as a link between the data listener and the template parser Observer. CompileBridge, when Observer detects data changes, Updater is used to notify Compile to update the view, and Compile subscribes to the corresponding data through Watcher, binds the update function, and adds subscribers through Dep to achieve two-way binding.

121. Pros and cons of Proxy and Object.defineProperty?

The advantages of Proxy are as follows

  • Proxy can directly monitor the entire object instead of properties.

  • Proxy can directly monitor the changes of the array.

  • Proxy has 13 interception methods, such as ownKeys、deleteProperty、has etc. are  Object.defineProperty not available.

  • Proxy returns a new object, we can only operate the new object to achieve the purpose, but Object.definePropertycan only traverse the object properties and directly modify;

  • As a new standard, Proxy will be subject to continuous performance optimization focused by browser manufacturers, which is the legendary performance bonus of the new standard.

The advantages of Object.defineProperty are as follows

  • It has good compatibility and supports IE9, but Proxy has browser compatibility problems, and it cannot be smoothed out with polyfill.

The disadvantages of Object.defineProperty are :

  • Object.defineProperty Only the properties of objects can be hijacked, so we need to traverse each property of each object.

  • Object.definePropertyArrays cannot be listened to. The array is monitored by the 7 methods that can change the data by rewriting the data.

  • Object.defineProperty It is also not possible   to listen to these data structures that are es6 newly generated  .MapSet

  • Object.definePropertyIt is also not possible to monitor the addition and deletion operations, and  implement responsiveness through Vue.set()and  .Vue.delete

122. How do you understand Vue's responsive system?

It is the ability to automatically track changes in data without having to manually trigger view updates. Vue2.X does data hijacking through Object.defineProperty(), and Vue3 uses Proxy as a data proxy to capture the get and set of data.

  • What is Data Responsive?

Simply put, when the user changes the data (Data), the view can be automatically refreshed, and the page UI can respond to the data change.

  • Why do you need to understand Vue data response?

Because this is the foundation of Vue, even You Yuxi said in the document, "One of the most unique features of Vue is its non-intrusive responsive system."

Vue operates on data through getters and setters. A virtual property can be generated through get() and set() functions to directly call functions to manipulate data. This step is encapsulated and we cannot see it.

 In addition, an important media API is needed, which is Object.defineProperty, because after the object is defined, if you want to change or add properties (such as get and set properties), you can only add them through this Object.defineProperty. Then it is necessary to monitor the reading and writing of data attributes. Being able to monitor means that vm (generally generated instances) can know that the data has changed, thereby triggering the render(data) function, and the page UI will respond.

123. Since Vue can accurately detect data changes through data hijacking, why does it need virtual DOM for diff detection differences?

1. Reduce operations on the real DOM

The Diff algorithm discusses how to generate a DOM tree update patch after the virtual DOM tree changes. Compare the change differences between the old and new virtual DOM trees, apply the update patch to the real DOM, and complete the view update with the minimum cost.

specific process:

  1. There is a mapping relationship between real DOM and virtual DOM. This mapping relationship depends on the establishment of JSX at the time of initialization;

  2. When the virtual DOM changes, a patch will be generated according to the gap calculation. This patch is a structured data, and the content includes addition, update, removal, etc.;

  3. Finally, update the real DOM according to the patch and feed it back to the user interface.

Such a process of generating patches and updating differences is collectively called the diff algorithm.

There are 3 main points involved here:

  1. Update timing: the update occurs after operations such as setState and Hooks calls

  2. Traversal algorithm: Depth-first traversal is adopted, starting from the root node and traversing vertically along the direction of the left subtree until a leaf node is found. Then go back to the previous node and traverse the right subtree nodes until all reachable nodes are traversed

  3. Optimization strategy: optimize the complexity at the three levels of tree, component and element

    1. Element comparison mainly occurs at the same level, and patches are generated by marking node operations. Node operations include insert, move, delete, etc. Among them, the reordering of nodes involves three operations of inserting, moving, and deleting at the same time, so the efficiency consumption is the largest. At this time, strategy three plays a crucial role. By marking the key, React can directly move the DOM node to reduce internal friction

    2. In the process of component comparison: if the components are of the same type, perform tree comparison; if not, put them directly into the patch. As long as the parent component type is different, it will be re-rendered. This is why shouldComponentUpdate, PureComponent and React.memo can improve performance

    3. This strategy requires tree comparisons, which are hierarchical comparisons of trees. The tree comparison method is very "violent", that is, two trees only compare nodes at the same level. If a node is found to no longer exist, the node and its child nodes will be completely deleted, and will not be used. For further comparison, this improves the comparison efficiency

    4. Ignore node cross-level operation scenarios to improve comparison efficiency.

    5. If the class of the component is the same, it will default to a similar tree structure, otherwise it will default to a different tree structure

    6. Child nodes at the same level can be compared by marking the key

Through the diff algorithm, specific nodes can be accurately obtained for targeted operations! ! !

124. Why doesn't Vue have a life cycle similar to shouldComponentUpdate in React?

Because Vue's responsive system already collects rendering-dependent data items when it is first rendered, it can get quite good performance in an automatic way. However, in some scenarios, manually controlling refresh checks can further improve rendering performance

The mechanism of vue is actually a dependency management mechanism. Regardless of the calculated attributes, watcher, and renderer, the model is the same from the outside. That is, when the initialization is performed, some methods are used to analyze who the module depends on. When the dependent data is updated, these modules are recalculated to produce Out of things (actually not always, for example, computed properties have an inert mechanism).

Specifically for the renderer, which data changes will cause dom changes have been determined when the template is compiled, and are hard-coded in the generated code.

React does not have such an automatic mechanism. The only reason it executes render is that you ask him to render. So when do you let it render? In engineering, a data flow tool is generally used. When the data changes, an event is sent, and the data is pushed over without distinguishing which field has changed (it’s useless for you to distinguish, the renderer doesn’t recognize it at all). If this data flow model is shared by multiple components, there must be a hook before render to give us an opportunity to tell the components "this time is none of your business", which is conducive to performance optimization.

So, is it possible for us to figure out what data the react renderer relies on without adding code static analysis, and then automatically eliminate this judgment? In my opinion, it is unlikely, because we can't guarantee that if we run the render once at runtime, it will access all the data it may access at one time.

125. What is the use of the key in Vue?

1. The function of the key is mainly to update the virtual dom funny. The principle is that vue can accurately judge whether the two nodes are the same through the key during the patch process, so as to avoid frequent updates of different elements, making the entire patch process more efficient and reducing The amount of dom operations improves performance. 2. In addition, if the key is not set, some hidden bugs may be caused when the list is updated. 3. When transitioning elements with the same tag name in vue, the key attribute is also used. The purpose is also to allow vue to distinguish them. Otherwise, vue will only replace its internal properties without triggering the transition effect.

126. Cannot use index as key

After reading the above introduction, it is actually easy to understand why index cannot be used as a key.

1. Affect performance: When index is used as the key, deleting all nodes behind the node will cause re-rendering, because the index changes, it can also change

Some people say that when your list data does not change, you can use index as the key. That is to say, the list will not trigger updating elements, only static display. What do you think of this statement? The reason why this issue is mentioned is that a group of people in the official vue group should discuss this issue for a long time. Let me reply weakly, do not use index as a key under any circumstances. The result was bombarded, hey! (Unless the front-end hard-coded list, and no operation will not cause key changes, as long as it is back-end data, how can the front-end ensure that the data remains unchanged). On this issue, I have three thoughts:

1. The standardization of the code 2. Compared with typescript, why do variables need to be typed? In addition to specification, it is also convenient to locate errors. 3. It is difficult to guarantee the stability of the order of the list.

127. Use jsx syntax in vue project

JSX is a format that combines Javascript and XML. React invented JSX, which uses HTML syntax to create a virtual DOM. When encountering <, JSX is parsed as HTML, and when encountering { is parsed as JavaScript.

Why should I use JSX in vue?

It is the template syntax used. Vue's template is actually compiled into a render function, which also supports JSX syntax. In the Vue official website, the functions in the template used in the createElement function are provided.

<script>
   export default {
       name: "item",
       props:{
         id:{
           type:Number,
           default:1
         }
       },
     render(){
         const hText=`
                       <h${this.id}>${this.$slots.default[0].text}</h${this.id}>
                     `
       return <div domPropsInnerHTML={hText}></div>
     }
   }
</script>

But a very small number of VUE projects use JSX syntax JSX syntax is rooted in react, and the template is still comfortable on Vue!

 

Guess you like

Origin blog.csdn.net/sdasadasds/article/details/132490893