Summary of 2023 front-end interview questions

  1. Today I want to summarize the interview questions I read recently. During the project gap period, I read a lot of interview questions, but I didn’t sort them out. When I recall, I have to search again for those I can’t remember. Including the questions encountered in the interviews of friends around me are also summarized.
  2. The summary is all front-end basic (primary) interview questions.
  3. I will continue to update in March~~~ Scroll down
  4. From 2023.03.09——>3.15——>3.20——3.23

1. CSS interview questions

1. What are the three ways to hide elements in CSS?

  • Set display: none; style. This style will make the element disappear completely on the page. The space originally occupied by the element will also be occupied by other elements, so it will cause the browser to rearrange and redraw.
  • The second way is to set the visibilty: hidden; style. The difference between it and display: none; is that after the element disappears on the page, its original space will still be retained, so it will only cause the browser to redraw, not rearrange.
  • The third is to set opcity: 0; the transparency is 0. Elements are also hidden visually, so this is also a way to hide elements.
  • There are other methods, using positioning, so that elements do not appear in the visible area, and so on.

2. CSS box model?

  • What is the box model?
  • Classification of box models?
  • How to specify the box model?

1. Each html element can be regarded as a box. This box is composed of the content, border, padding, and margin of the element from the inside to the outside.

2. The box model is generally divided into the standard box model and the weird box model. The weird box model is also called the IE box model. What is the difference between these two box models?

3. Under the standard box model, the width attribute of the browser is the width of the content content. That is to say, if we set the width attribute for an element, then the width attribute is the width of the content. At this time, the total width of the element box is : width + padding + border + margin, height is the same. The weird box model refers to the fact that the browser's width attribute is not the width of the content, but the sum of the element's content + inner margin + border width.
In other words, if we set the width attribute to an element, then the total width of the box is: the sum of width + margins. Because width already includes content, padding, and borders.
Under normal circumstances, the default is the standard box model, but we can specify the box model through the box-sizing attribute. When its value is border-box, it is a weird box model. When the value is content-box, it is the standard box model, because the width of the standard box model is content.

3. What are the ways of page layout?

  • Commonly used methods for page layout include floating, positioning, flex, grid grid layout, and grid system layout
  1. Float: Advantages: Good compatibility. Cons: Floats break out of standard document flow, so clear floats. We can fix this problem.
  2. Absolute positioning. Pros: Fast. Disadvantages: The child elements are also separated from the standard document flow, and the practicability is poor.
  3. flex layout (present in CSS3). Advantages: Solve the shortcomings of the above two methods, and the fex layout is perfect. The mobile terminal basically uses flex layout.
  4. Grid layout (grid). The layout introduced in CSS3 is very useful. The amount of code is simplified a lot.
  • A self-adaptive layout in the middle of about 300px realized by grid layout:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
html * {
    
    
	padding: 0;
	margin: 0;
}
/* 重要:设置容器为网格布局,宽度为100% */
.layout.grid .left-center-right {
    
    
	display: grid;
	width: 100%;
	grid-template-rows: 100px;
	grid-template-columns: 300px auto 300px; /* 重要:设置网格为三列,并设置每列的宽度。即可。*/
}
.layout.grid .left {
    
    
background: red;
}
.layout.grid .center {
    
    
background: green;
}
.layout.grid .right {
    
    
	background: blue;
}
</style>
</head>
<body>
<section class="layout grid">
<article class="left-center-right">
	<div class="left">我是 left</div>
	<div class="center">
		我是 center
		<h1>网格布局解决方案</h1>
	</div>
	<div class="right">我是 right</div>
</article>
</section>
</body>
</html>

4. rem and em?

  • Both rem and em are relative length units in CSS. The difference between them is that rem is calculated relative to the font size of the root element. The default font of any browser is 16px, so generally 1rem = 16px.
  • And em is calculated relative to the font size of the current element, but why we often say relative to the parent element, it is actually easy to understand, because the attribute font-size font size can be inherited, so the font of the parent element The size will inevitably affect the font size of its child elements, that is to say, if the child element does not have its own font-size, then its font-size will inherit the parent element, then the value of 1em at this time can be considered relative to Parent element font size to calculate.
  • In addition, rem is a new relative unit of css3. r is the abbreviation of root. Its appearance is to solve the shortcomings of em. em is converted relative to the font size of the parent element or the current element. When the font size of an element changes, it has to be recalculated. When there are many layers, the conversion will become more and more complicated. Rem is only relative to the HTML root element. With the rem unit, we only need to adjust the root element HTML The font-size can achieve dynamic adaptation of all elements, avoiding some complicated hierarchical relationships.

Replenish:

  1. rem is calculated relative to the root element, while em is relative to the font size of the current element or parent element.
    rem can not only set the size of the font, but also supports attributes such as element width and height.
  2. em is converted relative to the current element or parent element, the deeper the level, the more complex the conversion. And rem is calculated relative to the root element, avoiding hierarchical relationships.

5. Briefly talk about flex layout?

  • When multiple div tags are written side by side, they will be arranged vertically downward. If we want to arrange multiple divs in a row, we have to use position, float, or display attributes. This is the traditional box model approach.
  • The flex layout is a new layout scheme. By modifying the display attribute of the parent div, the parent element becomes a flex container, so that the arrangement of the child elements (items) in the container can be freely manipulated.
  • For example, if we arrange multiple divs horizontally, the traditional method is to use floats, but after floating, the parent element will lose height because it is out of the document flow, which involves a series of problems such as clearing floats.
  • The flex layout is relatively simple. Modify the parent element display:flex, and you will find that the divs are automatically arranged in a row, and there is no side effect after floating. From the perspective of reflow, the performance of flex is better than float; as browsers continue to Compatibility and elimination of old versions, flex layout is destined to become a more popular layout scheme.

1. The flex-direction attribute determines the direction of the main axis (that is, the arrangement direction of the items).
Value: row (default) | row-reverse | column | column-reverse
2. The flex-wrap attribute determines whether the items in the container can wrap.
Value: nowrap (default) | wrap | wrap-reverse
3. The justify-content attribute defines the alignment of the item on the main axis.
Value: flex-start (default) | flex-end | center | space-between | space-around | space-evenly; 4. The
align-items attribute defines the alignment of items on the cross axis.
Value: flex-start | flex-end | center | baseline | stretch (default)
5. flex-flow: short form of flex-direction and f'lex-wrap.
Value: flex-flow: || ; The default value is row nowrap, which is useless.
6. align-content: Defines the alignment of multiple axes. If the project has only one axis, then this attribute will not work.
Values: align-content: flex-start | flex-end | center | space-between | space-around | stretch;

There are six attributes that can be applied to item items:

  1. order
  2. flex-basis: auto; Defines the main axis space occupied by the item before allocating excess space, and the browser calculates whether the main axis has excess space according to this property
  3. flex-grow: 0; flex-grow defines the enlargement ratio of the item
  4. flex-shrink: 1; defines the shrinkage ratio of the item
  5. flex
  6. align-self

6. What is reflow (reflow) and repaint?

  1. Redrawing: The font color, background color, and border color of the page elements are modified, but the page layout is not affected, because the size of the element has not changed, and other elements have not been affected by the position, and the opcity transparency is set. visibility: hidden; attribute also causes redrawing. Summary: When the page element style changes without affecting the layout, the process of the browser re-updating the element is called redrawing.
  2. Rearrangement: refers to modifying the size of the element, such as changing the width and height of the element, the thickness of the border, or setting the display:none attribute for an element, which will also cause reflow. Summary: When the size, structure, or certain properties of page elements change, the process of the browser re-rendering part or all of the document is called reflow, also known as reflow. So reflow will definitely cause redrawing.

Regardless of whether the page is redrawn or reflowed, they will affect performance (the most terrible thing is reflow, which should be avoided as much as possible)

7. Under what circumstances will rearrangement occur?

  1. page initial rendering
  2. Add/remove visible DOM elements
  3. change element position
  4. Change element size (width, height, margins, borders, etc.)
  5. Change element content (text or image, etc.)
  6. change window size

8. How to reduce reflow and repaint (improve performance)?

Since reflow and redrawing will bring a lot of performance overhead, we should try to avoid or reduce the number of reflow and redrawing in development to improve performance

  1. Avoid frequently reading properties that will cause reflow/redrawing. If you really need to use it multiple times, use a variable to cache it.
  2. Use absolute positioning for elements with complex animations to keep them out of the document flow, otherwise it will cause frequent reflow of parent elements and subsequent elements.
  3. To avoid frequently manipulating the DOM, you can create a documentFragment, complete all DOM operations, and finally add it to the document.
  4. To avoid frequent manipulation of styles, it is best to rewrite the style attribute at one time, or define the style list as a class and change the class attribute at one time.

9. What is the process of page rendering? (How does the browser render the page?)

  1. Parse the HTML code structure to generate a DOM tree. It is to parse the code into a DOM Tree, press the nodes on the tree into the document flow and then layout them in the order from top to bottom and from left to right.
  2. Parse the CSS file and generate CSSOM (css Object Model). The order is: browser default style -> custom style -> style in the page.
  3. Combining DOM and CSSOM forms the Render tree. The difference between this rendering tree and the DOM tree is that it is affected by styles. It does not include those invisible nodes.
  4. After the rendering tree is generated, the browser will render and display it on the screen according to the rendering tree.

When parsing HTML, the HTML document will be converted into a DOM tree. When the render tree is constructed, the DOM tree will be converted into a more structured rendering tree. When the render tree is laid out and drawn, the rendering tree will be converted into a visible pixel image.

10. How to center horizontally and vertically?

1. 通过定位,给父盒子相对定位,子盒子绝对定位,top、left为50%,再margin-left : -(子盒子宽的一半)px; margin-top: -(子盒子高的一半)px;
<style>
        div {
    
    
            position: relative;
            height: 400px;
            width: 400px;
            background-color: pink;
        }
        span {
    
    
            position: absolute;
            top: 50%;
            left: 50%;
            margin-left: -50px;
            margin-top: -50px;
            display: block;
            width: 100px;
            height: 100px;
            background-color: purple;
        }
</style>
2. 不依赖通过计算子盒子的宽高进行定位,可以用transform: translate 移动自身的一半就行了。
<style>
        div {
    
    
            position: relative;
            height: 400px;
            width: 400px;
            background-color: pink;
        }

        span {
    
    
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            display: block;
            width: 100px;
            height: 100px;
            background-color: purple;
        }
</style>
3. 通过flex布局,设置垂直水平都居中。
<style>
        div {
    
    
            display: flex;
            justify-content: center;
            align-items: center;
            height: 400px;
            width: 400px;
            background-color: pink;
        }

        span {
    
    
            display: block;
            width: 100px;
            height: 100px;
            background-color: purple;
        }
</style>

11. Mobile terminal adaptation

  • Before doing front-end adaptation, either by using css media media query, or by obtaining the visual width to set the document root font size according to the desired ratio. I accidentally saw a new adapter plug-in on the Internet, postcss-px-to-viewport, which uses the viewport (vw) unit, and the viewport unit is more and more supported by many browsers, postcss-px-to-viewport, The px unit is automatically converted to the required viewport unit according to the corresponding configuration.
  • Use the plugin: postcss-px-to-viewport. You can use npm and yarn to install: npm install -D postcss-px-to-viewport or yarn add -D postcss-px-to-viewport.
  1. Create a new .postcssrc.js file at the outermost layer of the project (that is, under the same directory as the configuration file), and add configuration statements in the .postcssrc.js file. The update of .postcssrc.js will take effect only after restarting. The following is an example:
module.exports = {
    
    
    plugins: {
    
    
        autoprefixer: {
    
    }, // 自动添加相应浏览器前缀,样式兼容,如-webkit-,-moz-等
        "postcss-px-to-viewport": {
    
    
            unitToConvert: "px", // (String)需要转换的单位,默认为"px"
            viewportWidth: 750, // (Number)设计稿的视口宽度:可为设计稿的宽度,也可按需自行配置(PC)
            unitPrecision: 6, // (Number)单位转换后保留的精度,即小数点位数
            propList: ["*"], // (Array)指定转换的css属性的单位,*代表全部css属性的单位都进行转换
            viewportUnit: "vw", // (String)指定需要转换成的视窗单位,默认vw
            fontViewportUnit: "vw", // (String)指定字体需要转换成的视窗单位,默认vw
            selectorBlackList: ["demo"], // (Array)需要忽略的CSS选择器,不转为视窗单位,使用原有单位,
            minPixelValue: 1, // (Number)设置最小的转换数值,默认为1,只有大于1的值会被转换
            mediaQuery: true, // (Boolean)媒体查询里的单位是否需要转换单位,默认false
            replace: true, // (Boolean)是否直接更换属性值,而不添加备用属性
            exclude: [/node_modules/], // (Array or Regexp)忽略某些文件夹下的文件或特定文件,用正则做目录名匹配
            include: /Ignore.vue/,    //(Array or Regexp)只有匹配到的文件才会被转换,那将只有匹配到的文件才会被转换
            landscape: false, // (Boolean)是否添加根据 landscapeWidth 生成的媒体查询条件
            landscapeUnit: 'vw',    //(String)横屏时使用的单位
            landscapeWidth: 700     //(Number)横屏时使用的视口宽度
        }
    }
};
  1. It can also be configured in the configuration file vue.config.js.
const pxtoviewport = require("postcss-px-to-viewport");
module.exports = {
    
    
  css: {
    
    
    // 忽略 CSS order 顺序警告
    extract: {
    
     ignoreOrder: true },
    // 适配插件
    loaderOptions: {
    
    
      postcss: {
    
    
        plugins: [
          pxtoviewport({
    
    
            // 配置视窗口尺寸
            viewportWidth: 1700,
            unitPrecision: 5,
            viewportUnit: "vw",
            fontViewportUnit: "vw",
            selectorBlackList: [],
            minPixelValue: 1,
            mediaQuery: true,
          }),
        ],
      },
    },
  },
}
  1. Use lib-flexible to dynamically set REM base value (font size of html tags)
  • Install: yarn add amfe-flexible or npm i amfe-flexible
  • Then load and execute the module in main.js: import 'amfe-flexible'
  • Final test: switch between different mobile phone device sizes in the browser, and observe the changes in the font-size of the html tag.
  1. Use postcss-pxtorem to convert px to rem
  • Installation: yarn add -D postcss-pxtorem, npm install postcss-pxtorem -D. ( -D is shorthand for --save-dev.)
  • Then create a .postcssrc.js file in the project root directory.
  • After the configuration is complete, restart the service.
	module.exports = {
    
    
	  plugins: {
    
    
	    'postcss-pxtorem': {
    
    
	      rootValue: 37.5,
	      propList: ['*']
	    }
	  }
	}

12. What is BFC? What are its rules? How to trigger BFC? What problems can BFC solve?

[What is BFC?] The full name of BFC is block-formatting-context, corresponding to its Chinese translation is block-level formatting context, which is an independent rendering area, we can understand BFC as a closed container, the internal elements no matter No matter how you change it, it will not affect the outside, and the style layout inside the container will naturally not be affected by the outside world.
[BFC internal rules] 1BFC is a block-level element, and block-level elements will be arranged one after another in the vertical direction. 2BFC is an isolated and independent container in the page. The labels in the container will not affect the external labels. , 3 The BFC area will not overlap with the floating container, 4 the outer margins of two adjacent elements belonging to the same BFC will overlap, and the vertical distance is determined by the larger value of the margin in the two elements, 5 Calculate the BFC When the height of , floating elements will also participate in the calculation.
[How to trigger BFC?] It can be triggered by adding CSS properties, overflow:hidden; values ​​other than visible, position:absolute/fixed; display:inline-block/flex;

【What problem does BFC solve】?

  1. It can prevent elements from being covered by floating elements. For example, in a two-column layout, the width of the left div is fixed, and the left floating is set, and the right div is adaptive. At this time, because the floating element is out of the document flow and does not occupy space, it will cause The div on the right reaches the far left, and the div floating on the left will cover it. At this time, we can set the div element on the right as a BFC, for example, add display:flex; attribute to it to trigger, It can solve the problem that the right side is covered by the left side.
  2. It can solve the problem that the parent element has no height, and when the child element is set as a floating element, the height of the parent element collapses. For example, two divs in a container are floating elements. At this time, we add a red background color to the parent element, and we will find There is no effect, because the height of the parent element is collapsed, and the height is 0. At this time, we can add an attribute that triggers the BFC function, because BFC has a rule that when calculating the height of BFC, floating elements will also participate in the calculation, so after triggering BFC, The height of the parent element will be stretched, that is, it will have the effect of clearing the float.
  3. Third, it can solve the problem of overlapping margin margins. For example, there are two divs in a container, and the margin of the bottom margin of one div is set to 10px, and the top margin of one div is set to 20px. Then the space between the two boxes The distance is 20px instead of 30px. This is the problem of margin collapse. At this time, the margin should be the larger margin value between the two divs, not the sum of the two. If you want the distance between them to be 30px, It is necessary to trigger the BFC of a div, and its interior will follow the BFC rules. The solution is to wrap a box for the element to form a completely independent space, so that the elements inside will not be affected by the elements outside.

13. What is the difference between pseudo-classes and pseudo-elements?

  • In CSS3, it is stipulated that pseudo-classes are (:)represented (::), and pseudo-elements are represented by double colons. The pseudo-elements that existed before CSS3 also support single colons, but we still need to standardize the writing as much as possible during the development process.

[Difference]
Pseudo-class: When we want the style to be rendered to the specified element in a certain state, in other words, when the state of an element changes, we expect to add some special effects to this element, then we You can add the corresponding pseudo-class after the selector of the element. For example: hover can specify the style that we expect the element to display when we hover over it.

Pseudo-element: It creates some elements that are not in the document tree and adds styles to them. It should be noted that a content attribute must be given to it in the pseudo-element style. For example, you can use the ::before pseudo-element to add some text before an element and add styles to the text. These texts are not actually in the document tree, so they are called pseudo-elements.

In summary, pseudo-classes operate on existing elements in the document tree, while pseudo-elements create and style elements outside the document tree. So the core difference between the two lies in whether a "new element" has been created.

<template>
	<div>
		<div class="div1">第一个字符是红色。</div>
		<div class="div2">选择部分背景是黑色哟。</div>
		<div class="div3">该内容前面插入内容123</div>链接被访问后是红色,悬浮是绿色。<div>
		<p>第一个p元素会是黄色</p>
		<p>第一个p元素会是黄色</p>
		</div>
	</div>
</template>
<style scoped>
/*单冒号(是伪类,双冒号《::》是伪元素*/
.div1::first-letter{
    
    
		color: red;
}
.div2::selection{
    
    
	background-color: black;
}
.div3::before{
    
    
	content:'123';
}
a:visited {
    
    
	color: red;
}
a:hover{
    
    
	color: limegreen;
}
p:first-child {
    
    
	color:yellow;
}
<style>

14. What is the role of scoped?

  • When the style tag has the scoped attribute, its CSS style is only applied to the current component. In other words, scoped can make the styles between components isolated from each other without affecting each other. If all style tags in a project are scoped, it is equivalent to realizing the modularization of styles.
  • [Principle] After compiling with scoped, a unique identifier will be added to all label elements in the component. This unique identifier is the custom attribute
    data-v-xxxxxx (8 random numbers). At the same time, the corresponding style selector is also This unique attribute selector will be added. Since the identifier of each component is unique, it means that there will be no duplicate attribute selectors, so the style isolation between components can be achieved.
  • For the unique identifier of data-v-xxxxxx, you can run a vue project, and after f12 element retrieval, you can see that each element has such an identifier.

15. Pure css draw a triangle?

  1. The principle of css drawing triangles is to use the border of the box. The implementation steps can be divided into the following four steps: 1. Set a box; 2. Set borders of different colors around; After selecting one of the triangles, set the border color of the other triangles to transparent.

But in this way, although the triangle is realized visually, in fact, the hidden part still occupies part of the height, and the upper width needs to be removed.

 .triangle {
    
    
      width: 0px;
      height: 0px;
      border-top: 100px solid transparent;
      border-bottom: 100px solid red;
      border-left: 100px solid transparent;
      border-right: 100px solid transparent;
  }
  
<div class="triangle"></div>

  1. Draw a triangle using pseudo-elements
   #triangle {
    
    
        margin: 100px;
        /* width: 100px;
        height: 100px; */
        background-color: pink;
        position: relative;
    }

    #triangle::before {
    
    
        position: absolute;
        content: "";
        width: 0;
        height: 0;
        top: 0px;
        left: 100px;
        border-top: solid 50px transparent;
        border-left: solid 50px pink;
        border-bottom: solid 50px transparent;
    }
<div id='triangle'></div>

Two, js interview questions

1. Throttle and anti-shake?

  • Anti-shake means that in continuous operation, no matter how long it takes, only after a certain operation, no further operation within the specified time, this time will be judged as valid. (The callback is executed after n seconds after the event is triggered. If it is triggered again within these n seconds, the timer will be restarted.)
  • Anti-shake application scenario: During the process of entering keywords in the search box, the server is requested to match the search results in real time. If no processing is performed, the content of the input box keeps changing, resulting in sending requests all the time. If anti-shake processing is performed, the result is that after we input the content, there is no further input within a certain period of time (such as 500ms), and then the request is triggered again.
// 1. 利用计时器,实现防抖。
// 2. 通过 setTimeout 的方式,在一定的时间间隔内,将多次触发变成一次触发。

function debounce(fn, delay) {
    
    
    let timer;
    return function () {
    
    
        let args = arguments;
        if (timer) {
    
    
            clearTimeout(timer);
        }
        timer = setTimeout(()=> {
    
    
            fn.apply(this, args); 
        }, delay);
    };
}
  • Throttling means that in frequent operations, it is only triggered once within a specified time. For example, if we set 500ms, within this time, no matter how many times the button is clicked, it will only be triggered once.
  • Throttling application scenarios: 1. When rushing to buy, countless people quickly click the button. If each click sends a request, it will cause huge pressure on the server, but after we throttle, the number of requests will be greatly reduced. . 2. To prevent the form submit button from being triggered multiple times, we should choose to use throttling instead of anti-shake. 3. Scroll to load, load more or scroll to the bottom to listen.
function throttle(fn, delay) {
    
    
    let timer;
    return function () {
    
    
        let _this = this;
        let args = arguments;
        if (timer) {
    
    
            return;
        }
        timer = setTimeout(function () {
    
    
            fn.apply(_this, args);
            // 在delay后执行完fn之后清空timer,此时timer为假,throttle触发可以进入计时器
            timer = null;
        }, delay)
    }
}

2. How to deal with memory leaks?

  1. A memory leak refers to the failure to release memory that is no longer used due to negligence or some errors in the program. To put it simply, it is assumed that a variable occupies 100M of memory, and you do not use this variable, but this variable is not manually or automatically recycled, and still occupies 100M of memory space. This is a waste of memory, that is memory leak. (Memory leak means that when the program is running, the requested memory space is not released in time, resulting in the continuous increase of the memory occupied by the program, which may eventually cause the system to crash or become very slow.)
  2. In front-end development, memory leaks may occur in js code. For example, when using a closure, if the variable of the external function is referenced in the closure, and the external function has been executed, but the closure still exists, then the memory occupied by the external function cannot be released, which may cause a memory leak.
  3. In order to avoid memory leaks, developers should release unused variables and resources in time, avoid circular references, etc., and use some tools and techniques to detect and solve memory leaks.
    (1) Events bound to EventBus are not unbound
    (2) Memory leaks caused by global variables, the declared global variables are not cleared when switching pages.
    (3) Forgotten timer
    (4) Console printing
    (5) Memory leak caused by improper use of closure
    (6) Memory leak caused by v-if instruction

3. Tell me about your understanding of shallow copy and deep copy?

  1. Shallow copy is to copy by assignment. Only the reference of the object is copied, which is a copy of the pointer. After copying, the two pointers point to the same memory and the same data, which means that when the original object changes, the copied object also follows Variety.
When to use deep copy? : Backstage returns data, we need to operate on the data, maybe other places also need to use this data, direct modification will cause many other hidden problems, using deep copy can make us safer and more secure to operate these data Yes, because we made a copy anyway.
  1. Deep copy: not only copy the pointer, but also copy the content pointed to by the pointer, that is, apply for another space memory, the content is the same as the original object, but it is two independent data, changing the original object, the copy object will not change.
  2. Plain language: Assuming that B copied A, when A is modified, if B also changes, it means that only the pointer is copied, and A and B actually share one data, which is a shallow copy; if A changes but B remains unchanged, then It is a deep copy, and the copied object is not affected by the original object. Because not only the pointer is copied, but also the content is copied, they have their own memory and are independent of each other.

Implementation of deep copy

(1) Serialization and de-objectification methods of JSON objects of js built-in objects: JSON.parse + JSON.stringify

// 但是这个方法是有局限的,无法实现对对象中方法的深拷贝,取不到值为undefined的key等等之类的。
function cloneDeepJson(obj){
    
    
  return JSON.parse(JSON.stringify(obj))
}

(2) Use recursion to implement deep copy. a. Traverse the attributes of the original object passed in. Each attribute needs to judge whether its value is an object class. If not, it means that it is a basic data type and can be directly assigned; b. If it is an object class, then it needs to be judged in detail Whether the data is an object or an array, if it is an array, create an empty array [], if it is an object, create an empty object {}, and continue recursion.


//递归实现深拷贝

function deepClone(origin, target){
    
    
  var target = target || {
    
    };  //防止不传target
  for(let key in origin){
    
       //遍历origin中的属性
    if(origin.hasOwnProperty(key)){
    
      //判断自身是否有该属性而非原型链上的
      if( origin[key] && typeof(origin[key]) == "object"){
    
        //如果当前value是一个object类型,需要往下递归
        target[key] = Array.isArray(origin[key]) ? [] : {
    
    };   //判断这个object类型,具体是数组还是对象
        deepClone(origin[key], target[key]);   //递归
      }else{
    
    
        target[key] = origin[key];  //如果当前value不是一个object类型,直接赋值即可
      }
    }
  }
  return target;  //返回最终的拷贝对象
}

(3) loadash is a very popular function library. After we import this library, we can use this method directly. However, if the project itself does not import this library, it is not worth importing the entire library just to use deep copy. This is not worth the candle.
(2) Object.assign(target,...sources) ES6's new method can realize deep copy, target: who to copy to. sources: The objects to copy.

// 注意:只有当对象中没有嵌套对象时,才可以实现深拷贝
const foo = {
    
    
    name: '张三',
    age: 24
}
const newFoo = Object.assign({
    
    }, foo)
foo.age = 25
console.log(foo, newFoo) // {name: '张三', age: 25} {name: '张三', age: 24}

// 对象中有内嵌的对象时
const foo = {
    
    
    name: '张三',
    info: {
    
    
        age: 24
    }
}
const newFoo = Object.assign({
    
    }, foo)
foo.info.age = 25
console.log(foo, newFoo) // { name: '张三', info: { age: 25 } } { name: '张三', info: { age: 25 } }

(3) for ··· in, it is too troublesome to use for ··· in to traverse the assignment, and it is not recommended. As long as you encounter a certain complex data type (array, object), you will enter this complex data type again for a second traversal, and if there is any, you will enter and continue the traversal.
(4) Realize deep copy through json deserialization. No matter how complex the data type is, it is the basic data type after conversion to json string, and the assignment of the string is the assignment of the basic data type, and then converted back after the assignment.
(6) ...Spread operator. Copying a layer is a deep copy, but modifying an item in the array in the object will be affected, indicating that it is a shallow copy.

  let obj11 = {
    
    
       name: "张三",
       age: 18,
       hobbies: ['sleep', 'eat', 'play']
   }
   let obj12 = {
    
     ...obj11 }
   obj12.name = "胡歌"
   obj12.hobbies[0] = 'sleep + doDream'
   console.log('--------------------', obj11, obj12);

(7) arr. concat() method. Only the outermost layer is deeply copied, and objects in the array will be affected if modified, which is a shallow copy.

 // 该方法用于数组合并,合并的数组.concat(被合并的数组元素…)
 // 参数可有多个,用逗号分隔,返回合并后的数组。
 // 原理:用原数组去合并一个空数组,返回合并后的新数组。
 let arr11 = [1, 3, {
    
    
      username: 'coco'
  }];
  let arr22 = arr11.concat();
  arr22[2].username = 'xxxxx';
  arr22[0] = 555;

  // console.log(arr, 'arr');1
  console.log('arr11---------------', arr11);
  console.log('arr22--------------', arr22);

(8) arr. slice() method. Only the outermost layer is deep copied.

 const arr1 = [1, 3, {
    
     username: 'aaaaaa' }]
 const arr2 = arr1.slice()  //返回截取后的数组,这里没有截取掉任何项,相当于返回原数组。
 
 // 修改堆内存中的值
 arr2[0] = 5
 arr2[2].username = 'bbbbbb'

 console.log('arr1---', arr1)
 console.log('arr2---', arr2)

https://zhuanlan.zhihu.com/p/556923120 Learn more about deep and shallow copy

4. What is bubbling and how to solve it? What is event proxy (event delegation)?

  1. It means that the parent element and the child element have the same event. When the child element event is triggered, it will bubble up, and the parent element event will also be triggered at the same time.

Prevent bubbling: Prevent the event from bubbling to the parent element through the event.stopPropagation() method, preventing any parent event handler from being executed.

  1. It is not necessary to bind events to each child node, but to bind the events of the child nodes to their common structural parent nodes, so that when each child node is clicked, the parent node will be executed using event propagation and bubbling. Events bound to the node.

5. What is axios? How is axios packaged?

  • Axios is a packaged independent ajax request library based on Promise. Supports use in browsers and Node.

The steps of axios package:

  1. Create a utils folder in the root directory
  2. Create the request.js file
  3. Introduce axios in request.js
  4. Configure the base path and timeout
  5. Configure request interception and response interception
  6. Loading and token can be placed in request interception
  7. In response interception, loading can be cleared and error encoding dictionary can be processed
  8. Finally, export our encapsulated axios instance

6. What new features of es6 are used?

  1. Keywords for declaring variables: let; const for declaring constants.
  2. destructuring assignment
  3. template string
  4. arrow function
  5. spread operator
  6. Promises are used to encapsulate asynchronous operations and can get success or failure results.

7. What is a closure? What are the pros and cons?

  1. A closure is a function that has access to variables in the scope of another function.
  • Advantages: 1. One is that variables inside the outer function can be read. 2. Let these variables always be stored in memory, that is, the closure can keep its birth environment alive (extending the scope of variables.)
  • Disadvantages: It is easy to cause memory leaks.
  1. The following conditions are met to be a closure: 1. There is function nesting 2. The inner function refers to the variable of the outer scope 3. The return value is a function 4. Create an object function and let it reside for a long time
  2. Why do you need to use closures? Because global variables are easy to pollute the environment, and local variables cannot reside in memory for a long time, we need a mechanism that can save variables for a long time without polluting the global environment. This is closure.
  3. When to use closures? : When we need to reuse an object and want to protect the object from being polluted by other codes, we can use closures.
  4. How to destroy the memory space of the closure? Just reassign the variable of the external receiving function to null.
        // 写一个函数,每次调用,数字都要减1 --------- 全局变量,占用内存,任意函数(地方)都可以随便调用,会污染环境。
        var a = 100;
        function fn() {
    
    
            a--;
            console.log(a);
        }
        fn()  // 99
        fn()  // 98
        fn()  // 97

        //  -----------每次调用,结果都是99。每次函数一调用完就会销毁。每次调用,b都是100开始,存不住。
        function fn2() {
    
    
            var b = 100;
            b--;
            console.log(b);
        }
        fn2()  // 99
        fn2()  // 99
        fn2()  // 99

        // ------------闭包的写法
        function fn3() {
    
    
            let c = 100;
            function fn4() {
    
      
                c--;
                console.log(c);
            }
            return fn4;
        }

        var fn5 = fn3();
        fn5()   // 99
        fn5()   // 98 
        fn5()   // 97

        fn5 = null;

8. Have you learned about the browser's same-origin policy (cross-domain issues)?

  • If any of the protocol, domain name, and port of a request url is different from the current page url, a cross-domain phenomenon will occur.
  • The same-origin policy is a security protocol for web pages. Same origin: same protocol, same domain name, same port.
  1. Vue-cli proxy cross-domain: configure in the proxy of the devServer object in the vue.config.js file.
module.exports={
    
    
	pages:{
    
    
		index:{
    
    
			//入口
			entry:'src/main.js',
		},
	},
	lintOnSave:false,//关闭语法检查
	//开启代理服务器 方法一
	// devServer:{
    
    
		//paroxy:'http://localhost:5000',//5000服务器端口号,
	// },
	//方法二:
	devServer:{
    
    
		proxy:{
    
    
			// 请求前缀/api,只有加了/api前缀的请求才会走代理(前端自定义)
			'/api':{
    
    
				target:'http://localhost:5000',
				pathReweite:{
    
    '^/api':''},//重写
				//ws:true,//用于支持websocket
				changeOrigin:true,//用于控制请求头中的host值,默认true,react中默认false
			}
		}
	}
}

When using webpack or vite to build tools, configure a reverse proxy to change the address of all local axios requests (domain name: port) to: /api/, and the address /api/ of the local request will be automatically replaced with the actual one. In this way, the address of the current request is realized, and it will be recognized by the backend as the same domain name as the frontend; it ensures that the frontend and backend domain names are consistent, and solves cross-domain issues; 2. The same method can also be used in
nginx , to solve cross-domain problems through reverse proxy forwarding.
3. JSONP solves cross domain. The cooperation between the front and back end is required, and the script tag is not restricted by using the same-origin policy, but only get requests are supported.
4. CORS cross-domain resource sharing. Cors cross-domain, only need back-end configuration, server set header("Access-Control-Allow-Origin:*"); allow any origin, header("Access-Control-Allow-Origin:http://me.com ”); Only requests from the domain name http://me.com are allowed.

9. Front-end login process

  1. When you click Login on the login page, the front end will call the login interface on the back end with the username and password.
  2. The backend receives the request and verifies the user name and password. If the verification fails, an error message will be returned, and the front end will prompt the corresponding error message. If the verification is successful, a token will be returned to the front end.
  3. The front end gets the token, stores the token in Vuex and localStorage, and jumps to the page, that is, the login is successful.
  4. Every time the front end jumps to a page that needs to have a login status, it needs to judge whether the current token exists. If it does not exist, it will jump to the login page. If it exists, it will jump normally (usually encapsulated in the routing guard).
  5. In addition, when sending other requests to the backend, it is necessary to bring a token in the request header (usually encapsulated in a request interceptor in the project), and the backend judges whether there is a token in the request header, and verifies the token if the verification is successful. The data is returned normally, and the corresponding error code is returned if the verification fails (if it has expired). The front end gets the error message, clears the token and returns to the login page.

11. What does the New operator do?

  1. The first step creates an empty object.
  2. The second step sets this to point to the empty object.
  3. The third step is to dynamically add member attributes to the newly created object.
  4. The fourth step implicitly returns this.

12. What is the difference between an arrow function and a normal function? Can an arrow function be used as a constructor?

1. 箭头函数比普通函数在写法上更加简洁。
    (1)如果没有参数,就直接写一个空括号即可
    (2) 如果只有一个参数,可以省去参数的括号
    (3)如果有多个参数,用逗号分割
    (4)如果函数体的返回值只有一句,可以省略大括号

2. 箭头函数没有自己的this
	箭头函数不会创建自己的this, 所以它没有自己的this,它只会在自己作用域的上一层继承this。所以箭头函数中this的指向在它在定义时已经确定了,之后不会改变。
	
3. 箭头函数继承来的this指向永远不会改变,call()、apply()、bind()等方法不能改变箭头函数中this的指向 。
	var id = 'GLOBAL';
	
	var obj = {
	  id: 'OBJ',
	  a: function(){
	    console.log(this.id);
	  },
	  
	  b: () => {
	    console.log(this.id);
	  }
	};
	
	obj.a();    // 'OBJ'
	obj.b();    // 'GLOBAL'
	new obj.a()  // undefined
	new obj.b()  // Uncaught TypeError: obj.b is not a constructor
	
对象obj的方法b是使用箭头函数定义的,这个函数中的this就永远指向它定义时所处的全局执行环境中的this,即便这个函数是作为对象obj的方法调用,this依旧指向Window对象。需要注意,定义对象的大括号{ }是无法形成一个单独的执行环境的,它依旧是处于全局执行环境中。

4. 箭头函数不能作为构造函数使用 
由于箭头函数时没有自己的this,且this指向外层的执行环境,且不能改变指向,所以不能当做构造函数使用。

5. 箭头函数没有自己的arguments
	箭头函数没有自己的arguments对象。在箭头函数中访问arguments实际上获得的是它外层函数的arguments值。
	
6. 箭头函数没有prototype

7. 箭头函数的this指向哪⾥?
	箭头函数不同于传统JavaScript中的函数,箭头函数并没有属于⾃⼰的this,它所谓的this是捕获其所在上下⽂的 this 值,作为⾃⼰的 this 值,并且由于没有属于⾃⼰的this,所以是不会被new调⽤的,这个所谓的this也不会被改变。

13. What is a pseudo-array (also called an object array)? How is it different from an array?

  1. The pseudo-array data type is object object, while the real array data type is array.
  2. Pseudo-arrays have a length attribute and an index, and the length can be obtained through .length, and an element can be obtained through the index, but there is no method such as forEach, while the array has all the methods of the array.
  3. The length of the pseudo-array cannot be changed, but the length of the array can be changed.
  4. Because the pseudo-array is an object array, it is traversed with for...in, and it is recommended to use for...of for the array.
  5. Pseudo-array-to-array is expanded into a new array using array.from or the direct spread operator.
  6. The common pseudo-array in JavaScript is arguments, the parameter arguments of the function; in addition, native JS obtains dom elements, and the list obtained by document.querySelector("div") is also a pseudo-array.

14. How to convert class array to array?

  1. Through the Array.from method to achieve conversion
    Array.from(arrayLike)
  2. Call the slice method of the array by call to realize the conversion
    Array.prototype.slice.call(arrayLike)
  3. Call the splice method of the array by call to realize the conversion
    Array.prototype.splice.call(arrayLike,0)
  4. The concat method of the array is called by apply to realize the conversion
    Array.prototype.concat.apply([],arrayLike)

15. Tell me about the common ways to detect data types?

  1. In typeof, arrays, objects, and null will be judged as Object, and other judgments are correct.
  2. instanceof can only judge the reference data type, not the basic data type.
  3. constructor It has two functions, one is to judge the type of data, and the other is for an object instance to access its constructor through the constructor object. The thing to note is that if you create an object to change its prototype, the constructor will not be able to determine the data type.
  4. Object.prototype.toString.call() uses the prototype method tostring of the object object to determine the data type.

The difference between instanceof and typeof:
instanceof: The return value is a Boolean value. instanceof is used to determine whether a variable belongs to an instance of an object.
typeof: The return value is a string, which is used to describe the data type of the variable. typeof generally can only return the following results: number, boolean, string, function, object, undefined

16. How many ways to deduplicate an array?

1.最简单的set去重

	var aa=[23,45,23,23,34,2,34,66,78];
	
	var aa=new set(aa);
	
	console.log(aa);

2.用indexOf()来去重
	var sum=[ ]; //给它一个空的数组

	for(var i=o;i<aa.length;i++){
    
    
	
		//如果没有找到字符串,则返回-1,检索是否存在。
	
		if(sum.indexOf(aa[i]>=0){
    
    
	
			continue;//结束本次循环
	
		}else{
    
    
	
			sum.push(aa[i]);
	
		}
	}
	
	console.log(sum);

3.用sort排序后去重

	function fn(arr){
    
    
	 let newArr = []
	 arr.sort((a,b)=>{
    
    
	       return a-b
	 })
	 arr.forEach((val,index)=>{
    
    
	     if(val != arr[index+1]){
    
    
	          newArr.push(val)
	     }
	   })
	 return newArr;
	}

4.数组去重,根据里面相同的ID去重,键值

var str=[
        {
    
    name:"张三",id:1},
        {
    
    name:"李四",id:2},
        {
    
    name:"王五",id:2},
        {
    
    name:"小明",id:3},
        {
    
    name:"小兰",id:1},
    ];

//声明一个数组
var result=[];

//声明一个对象
var obj={
    
    };

for(var i=0;i<str.length;i++){
    
    

	if(!obj[str[i].id]){
    
    

		result.push(str[i]);

		obj[str[i].id]=true;
	}
}

console.log(result);

5.普通去重的方式
function removeRepeat(arr) {
    
    
	for(var i=0;i<arr.length;i++){
    
    
	        for(var j=i+1;j<arr.length;j++){
    
    
	            if(arr[i]==arr[j]){
    
    
	                arr.splice(j,1);  //索引,删除长度
	                j--; 
	            }
	        }
	    }
	console.log(arr); 
	return arr;
}
removeRepeat([23, 45, 23, 23, 34, 2, 34, 66, 78])

17. How to tell if an object is an empty object?

// 1.使用JSON自带的.stringify 方法来判断
 if(Json.stringify(obj)=='{}'){
    
    
	console.log('是空对象')
 }
// 2.使用ES6新增的方法Object.keys()来判断
 if(Object.keys(Obj).length<0){
    
    
	console.log('是空对象')
 }

18. What is the difference between for...in and for...of?

  1. for...in traverses the object to obtain the key name of the object, and for...in traverses the array to obtain the index value of the array. for...of traversing the object reports an error: obj is not iterable, and for...of traversing the array gets the value of each item in the array.
  2. for...in will traverse the entire prototype chain of the object, the performance is very poor and it is not recommended to use it. And for...of only traverses the current object and does not traverse the prototype chain.
  3. For array traversal, for...in will return all enumerable properties in the array (including enumerable properties on the prototype chain), and for...of will only return the value of the property corresponding to the subscript of the array.

Summary: The for...in loop is mainly for traversing objects, not for traversing arrays. The for...of loop can be used to iterate over arrays, array-like objects, strings, Sets, Maps, and Generator objects.

19. What are the disadvantages of JSON.stringify?

1. If there is a time object in obj, then the result of JSON.parse after JSON.stringify, the time will be in the form of a string instead of an object.
2. If there are RegExp (abbreviation for regular expression) and Error objects in obj, the result of serialization will only get empty objects.
3. If there is a function, undefined in obj, the result of serialization will lose the function or undefined.
4. If there are NaN, Infinity and -Infinity in obj, the result of serialization will become null.
5. JSON.stringify() can only serialize the enumerable own properties of the object. For example, if the object in obj is generated by a constructor, use JSON.parse(JSON.stringify(obj)) after deep copy , will discard the object's constructor.
6. If there is a circular reference in the object, the deep copy cannot be implemented correctly.

20. How to use Set?

1. What are the characteristics of the Set data structure?
  1. ES6 provides a new data structure Set, which is similar to an array, but the values ​​of its members are unique and there are no duplicate values.
  2. Set is different from Map, it does not have the concept of key-value pairs, it has only one dimension, which is value.
2. Where is the Set data structure applied?
  • Application: storage of search history keywords
  1. The search function of the website, after the user searches, the website needs to record the keywords the user searches, so that the user can click directly next time and search for historical keywords.
  2. When users search for historical keywords, there cannot be duplicate values. When users enter the same keyword multiple times and use set to store the value, it will automatically judge whether the value is repeated. If it is repeated, it will not be stored again.
3. Usage of Set
  • Set itself is a constructor used to generate the Set data structure.
  • Attribute size, how many elements there are in the Set, similar to the length of the array.
const set = new Set();

const s1 = new Set();  // 空的Set数据结构
console.log(s1.size)  // 0 

const s2 = new Set(["a", "b"]);
console.log(s2.size)  // 2
  • The Set function can accept an array as a parameter for initialization.
1. 
const set = new Set([1,2,3,4,5,4,5]);
console.log(set)  // {1, 2, 3, 4, 5}

2. 
const s3 = new Set(["a","a","b","b"]);
console.log(s3.size)  // 2

const ary = [...s3]; 
console.log(ary)  // ["a","b"]
4. Set properties and methods (instance methods)
1. add(value): 添加某个值,返回Set结构本身。

const s4 = new Set();
// 向set结构中添加值 使用add方法
s4.add('a').add('b');  // 链式调用
console.log(s4.size)  // 2

 2. delete(value): 删除某个值,返回一个布尔值,表示删除是否成功。

const s4 = new Set(['1','2','c']);
const r1 = s4.delete('c');
console.log(s4.size)  // 2
console.log(r1);    // true

3. has(value): 返回一个布尔值,表示该值是否为Set的成员。

const s4 = new Set(['1','2','c']);
const r2 = s4.has('d');
console.log(r2)  // false

4. clear(): 清除所有成员,没有返回值。

const s4 = new Set(['1','2','c']);
s4.clear();
console.log(s4.size);  // 0 

5. 遍历 (方法)
- Set结构的实例与数组一样,也拥有forEach方法,用于对每个成员执行某种操作,没有返回值。

// 遍历set数据结构,从中取值
const s5 = new Set(['a', 'b', 'c']);
s5.forEach(value => {
    
    
	console.log(value)  
})

// a
   b
   c

21. Usage of Map

1. What is the Map data structure used for?
  1. Map objects are used to store key-value pairs.
  2. Map itself is a constructor used to generate a Map data structure.
// 创建一个Map
 const map = new Map();
2. Map properties and methods (instance methods)
1.  size属性
- 返回Map对象中所包含的键值对的个数。

const map = new Map()
const a = map.set(1,'one')
console.log(a.size)  // 1

2.  set方法
- 向Map中添加新元素。
- 第一次set是添加数据,第二次添加相同的key时,会将第一次添加的值给覆盖掉。

set(key,value)
const map = new Map()
const a = map.set(1,'one')
console.log(a)    // {1 => 'one'}


3.  get方法
- 通过键,查找特定的值。

get(key)

4.  delete方法
- 通过键,从Map中移除对应的数据。

delete(key)

5.  has方法
- 判断Map对象中是否存在key,若有则返回true,否则返回falsehas(key)

6.  clear方法
- 将这个Map中的所有元素删除。

clear(key)
3. How to traverse the Map
1. keys(): 返回键名的遍历器

const map = new Map()
map.set(1,'one')
map.set(2,'two')
map.set(3,'three')

for(const item of map.keys()) {
    
    
	console.log(item);  // 1 2 3
}

2. values(): 返回键值的遍历器

const map = new Map()
map.set(1,'one')
map.set(2,'two')
map.set(3,'three')

for(const item of map.values()) {
    
    
	console.log(item);  // 'one' 'two' 'three'
}

3. entries(): 返回键值对的遍历器
- entry条目的意思,entries复数,意思指键值对。
- entries方法中的键值对是以数组的形式存在的。

const map = new Map()
map.set(1,'one')
map.set(2,'two')
map.set(3,'three')

for(const item of map.entries()) {
    
    
	console.log(item);  // 返回三个数组[1,'one'] , [2,'two'], [3,'three']
}

4. forEach(): 使用回调函数遍历每个成员
	第一个参数:item,是Map的value值
	第二个参数:index 是Map的key值
	第三个参数: Map本身

22. js data type

  1. The data types in is are divided into basic data types and reference data types.
  2. The basic data types include Number, String, Boolean, Null, Undefined, Symbol added by es6 and Biglnt (arbitrary precision integer) added by es10.
  3. Reference data types are obiect classes, such as object arrays, and functions.
  • Storage location: the basic type is stored in the stack memory and the reference data type is stored in the stack memory as an object pointer, which points to the value in the heap memory, that is to say, the actual value is stored in the heap memory, and the object is stored in the stack The reference address in the heap memory, through which the object stored in the heap memory can be found. If two variables store the same address value, it means that they point to the same piece of data. When one variable modifies the attribute, the other will inevitably be affected.

3. Network

1. What is the difference between a get request and a post request?

  1. The parameters of the get request are spliced ​​in the address bar, which has poor privacy and security. The length of the requested data is limited. Different
    browsers and servers are different. Generally, the limit is between 2~8K, and the more common one is Within 1k; the post request has no length limit, and the request data is placed in the body.
  2. The get request is generally to get the data (it can also be submitted, but the common one is to get the data); the post request is generally to submit the data.
  3. The get request refreshes the server or rollback has no effect, and the data request will be resubmitted when the post request rolls back.
  4. Get requests can be cached, post requests will not be cached.
  5. Get requests will be saved in the browser history, post will not. GET requests can be bookmarked because the parameters are in the url, but POSTs cannot. The parameters of the post request are not in the url.
  6. Get requests can only be url-encoded (application-x-www-form-urlencoded), and post requests support multiple types (multipart/form-data, etc.).

2. Do get and post use cache?

  1. Get and post are two request methods with the same purpose in the http protocol. The http protocol is an application layer protocol based on TCP/IP, so both get and post use the same transport layer protocol, so it can be considered basically useless in terms of transmission. Difference.
  • The get request is similar to the search process. It is usually used when obtaining data from the server, such as query. If the get request has parameters, the parameters will be concatenated and exposed in the url in the address bar. HTTP caching is usually only applicable to data that does not change the server. request, so get complies with http caching, which applies to the principle of not changing the data requested by the server, so get requests can be cached.
  • Post is different. Post is generally used when submitting data to the server. What it does is modify and delete work, such as adding and modifying forms. Post parameters will be placed in the request body, so it must interact with the database, so caching cannot be used.

3. How to configure Apache and Nginx?

阿帕奇(Apache)和 Nginx 都是常用的 Web 服务器软件,它们可以用来处理 HTTP 请求并向客户端发送响应。下面是它们的配置方法简述:
阿帕奇配置:
1. 修改 Apache 的配置文件 httpd.conf(或 .htaccess 文件),配置虚拟主机和监听端口等参数。
2. 配置 Apache 的模块,如 PHP 模块,通过修改 httpd.conf 文件或添加 .conf 文件。
3. 重启 Apache 服务器,使配置生效。
Nginx 配置:
1. 修改 Nginx 的配置文件 nginx.conf,配置虚拟主机、监听端口、反向代理等参数。
2. 配置 Nginx 的模块,如 Lua 模块、gzip 模块等,通过在 nginx.conf 文件中添加配置项。
3. 重启 Nginx 服务器,使配置生效。
需要注意的是,在配置阿帕奇和 Nginx 的过程中,需要根据实际情况选择不同的配置选项,并确保配置文件的正确性和安全性。另外,由于 Nginx 的性能优于阿帕奇,因此在高并发的情况下,可以考虑使用 Nginx 作为 Web 服务器。

4. Front-end and back-end interaction?

前后端交互是指前端页面和后端服务器之间的数据传输和通信。前端通常使用 JavaScript 发送 HTTP 请求(如 GETPOST 请求等),后端服务器接收请求并处理请求,返回相应的数据给前端。

下面是前后端交互的基本流程:
1. 前端页面通过 JavaScript 构造 HTTP 请求,包括请求方法(GETPOST 等)、请求 URL、请求头、请求体等。
发送 HTTP 请求到后端服务器。可以使用浏览器的 XMLHttpRequest 对象、Fetch API,或者第三方库(如 axios)发送请求。
2. 后端服务器接收请求,根据请求 URL 和请求方法进行处理,并从数据库或其他资源中获取数据,对数据进行处理和计算。
后端服务器将处理后的数据封装成 HTTP 响应,包括响应状态码、响应头、响应体等。
3. 前端页面接收到 HTTP 响应,解析响应数据,并根据数据更新页面内容。
4. 需要注意的是,前后端交互需要遵循一定的协议和规范,例如 HTTP 协议、JSON 数据格式等。此外,为了提高交互效率和用户体验,可以使用一些技术和工具,如 Ajax、WebSocket、RESTful API 等。

5. How to connect the front and back ends?

  • The front-end and the back-end are separated, and when different people are responsible for the development, it is often encountered in the development process that the front-end and back-end are jointly debugged for data docking and debugging. When we usually practice front-end development, we directly provide interface documents and server addresses, and then we can directly configure in webpack to request data. But in the actual development, the server address is available, but the back-end interface has not been written, and it has not been deployed to the shared server.
  1. Before development, agree on the interface protocol and data format with the backend. (The data content and format that need to be displayed on the front end are generally more json)
  2. During development, the front end completes local development and ui rendering through mock data
  3. Joint debugging: the backend provides interface documents to the frontend, and the frontend can be debugged through postman, or the interface can be debugged in the frontend project. If there is any doubt about the interface data returned by the request, just let the backend adjust.

In layman's terms, the front end adjusts the interface of the back end, transmits data to the back end or fetches data from the back end. As the front-end, our main concern is what is the address of the interface, what parameters should be passed to the back-end when the front-end adjusts the interface, what data will the back-end return to us, and so on. We will find the answer to this information from the interface document. The interface document is generally written by the backend according to the specification and provided to us. For communication, the front-end cannot modify it without authorization. If there is a data format that is not what we want, there are only two situations. Either communicate with the back-end teacher and let the back-end teacher change it, or the front-end processes the data into an ideal state.

6. What is the browser's caching mechanism?

为什么需要浏览器缓存?
1. 浏览器的缓存,主要针对的是前端的静态资源。最好的效果是,我们在发起请求后,拉去相应的静态资源,并且保存在本地。如果服务器的静态资源没有更新,那么在下次请求的时候,就直接从本地读取;如果服务器的静态资源已经更新,那么我们再次请求的时候,就到服务器拉取新的资源,并保存在本地。这样能减少请求的次数,提高网站的性能。
2. 所谓的浏览器缓存:指的是浏览器将用户请求过的静态资源,存储到电脑本地磁盘中,当浏览器再次访问的时候,就可以直接从本地加载,不需要再去服务端请求了。
3. 使用浏览器缓存,有以下优点:
     (1)减少服务器的负担,提高了网站的性能。
     (2)加快客户端请求网页的加载速度。
     (3)减少了多余网络数据传输。

7. What happens when you enter an address in the address bar and press Enter?

(1) URL parsing
(2) Cache judgment
(3) DNS resolution
(4) Obtaining MAC address
(5) TCP three-way handshake
(6) HTTPS handshake
(7) Return data
(8) Page rendering
(9) TCP four-way handshake

8. What is the difference between HTTP and HTTPS protocols?

  1. Http, also known as Hypertext Transfer Protocol, is the most widely used transfer protocol on the Internet. It sends information in plain text, so if criminals intercept the transfer message between the Web browser and the server, Information can be obtained directly, so it is conceivable that this is not safe.
  2. https can be considered as a secure version of http, which adds the SSL protocol on the basis of HTTP. The s in https refers to the SSL protocol. This layer of protocol is added between the transport layer and the application layer. It can communicate Data is encrypted and identities can be verified, making communication more secure. Of course, it is not absolutely safe, but it will only increase the destruction cost of criminals.
  3. The difference between https and http:
    (1) The connection methods of the two are different. The port of https is 443, while the port of http is 80.
    (2) HTTP transmission is in plain text, and the HTTP protocol is not suitable for transmitting some sensitive information, such as payment information such as credit card numbers and passwords. And https is encrypted with ssl, which is more secure.
    (3) HTTPS needs to apply for a CA certificate. Generally, there are fewer free certificates, so a certain fee is required, while HTTP does not.
    (4) The http protocol is faster than https, because it does not require complex ssl handshakes compared to https. The https protocol needs to go through some complicated security procedures, and the page response speed will be slow.

9. The difference and application scenarios of tcp and udp

Both tcp and udp are communication protocols and transport layer protocols, but their communication mechanisms and application scenarios are different.

  1. udp is connectionless (no need to establish a connection before sending data) tcp is connection-oriented (need to establish a connection to transmit data, here is the three WeChat official account [programming 10:30] handshake of tcp);
  2. udp is unreliable transmission, tcp is reliable transmission (because tcp has mechanisms such as congestion control, which can ensure data transmission without errors, while udp has no relevant mechanism, and does not guarantee reliable delivery of data)
  3. UDP is oriented to message transmission, while tcp regards data as a series of unstructured byte streams, which is oriented to byte stream transmission.
  4. UDP supports one-to-one, one-to-many, and many-to-many interactive communication; TCP is a one-to-one two-point service, that is, a connection has only two endpoints. In summary, it can be seen that tcp is a reliable transmission protocol, but the efficiency is slow; while udp is an unreliable transmission protocol, but the efficiency is fast.

Therefore, the applicable scenario of tcp is used in situations where the integrity and accuracy of communication data are required to be high. Such as: important file transfer, email sending, etc.
Applicable scenarios of udp: It is used in situations where the requirements for communication speed are high and the requirements for data information security and integrity are relatively low. Such as: Internet telephony, video conference live broadcast and other real-time communication.

10. TCP's three-way handshake and four-way handshake?

  • First of all, we need to know what the purpose of establishing a connection is, we are for reliable data transmission. Since it is a reliable transmission of data, we must ensure that both the client and the server can send and receive data normally. If one party cannot send or receive data normally, the entire data transmission will not be successful and unreliable.
three handshake
  1. The first handshake: the first handshake is when the client sends a synchronous message to the server. At this time, the client knows that it has the ability to send data, but it does not know whether the server has the ability to receive and send data;
  2. The second handshake: When the server receives the synchronization message, it replies to confirm the synchronization message. At this time, the server knows that the client has the ability to send messages, and knows that it has the ability to receive and send data, but it does not Know whether the client has the ability to receive data;
  3. The third handshake: When the client receives the confirmation message from the server, it knows that the server has the ability to receive and send data, but at this time the server does not know that it has the ability to receive, so it needs to send a confirmation message , to inform the server that it is capable of receiving.

Finally, when the entire three-way handshake is over, both the client and the server know that they and the other party have the ability to send and receive data, and then the entire connection establishment is completed, and subsequent data transmission can be performed.

waved four times
  1. For the first time, the client initiates a request to close the connection to the server by waving;
  2. The second wave: When the server receives the close request, the data may not have been sent at this time, so the server will first reply with a confirmation message, indicating that it knows that the client wants to close the connection, but because the data has not been transmitted finished, so still need to wait;
  3. The third wave: When the data transmission is completed, the server will actively send a FIN message to tell the client that the data has been sent, and the server is ready to close the connection.
  4. The fourth wave: When the client receives the FIN message from the server, it will reply with an ACK message, telling the server that it knows, and then close the connection after waiting for a while.
Why do you have to shake hands three times, but wave four times?
  1. Because there is no data transmission during the handshake, the SYN and ACK messages of the server can be sent together, but when the hand is waved, there is data transmission, so the ACK and FIN messages cannot be sent at the same time, it needs to be divided into two steps, so it will be more than the handshake step.
Why does the client wait for 2MSL after the fourth wave?
  1. Waiting for 2MSL is to ensure that the server receives the ACK message, because the network is complicated, it is very likely that the ACK message is lost, if the server does not receive the ACK message, it will resend the FIN message, only when the client After waiting for 2MSL and not receiving the resent FIN message, it means that the server has received the ACK message normally, then the client can be closed at this time.

11. Horizontal and vertical overreach?

  • First explain what is an unauthorized access vulnerability: an unauthorized access vulnerability is a very common logical security vulnerability. There is an error in checking the authorization of an application. It is because the server side has too much trust in the data operation request made by the client, ignoring the judgment of the user's operation authority, which leads to the addition and deletion of other accounts by modifying the relevant parameters. , Check, and change functions, resulting in unauthorized loopholes.
  1. Horizontal overreach means that different users under the same authority can access each other. The attacker tries to access the resources of a user with the same authority as him. How to understand it? For example, there is a function of personal data in a certain system, and both account A and account B can access this function, but the personal information of account A and the personal information of account B The information is different, which can be understood as the division of the personal data of account A and account B with horizontal permissions. At this time, account A accessed the personal data of account B through attack means, which is a horizontal unauthorized access vulnerability.

Common scenarios of horizontal overreach
1. ID based on user identity
When using a certain function, access or operate the corresponding data through the identity ID submitted by the user (user ID, account number, mobile phone number, certificate number, etc.).
2. Based on the object ID,
access or operate the corresponding data through the object ID (such as order number, record number) submitted by the user when using a certain function.
3. Based on the file name
When using a certain function, directly access the file through the file name, which is most common in the scene where the user uploads the file.

  1. Vertical overreach, users with low privileges can access users with high privileges.
    Vertical overreach refers to overreach between different levels or between different roles. Vertical overreach can also be divided into upward overreach and downward overreach. Upward privilege refers to a low-level user trying to access the resources of a high-level user. For example, a system is divided into ordinary users and administrator users. Administrators have system management functions, but ordinary users do not. Then we can understand it as management Functions have vertical authority division. If ordinary users can use some attack method to access management functions, then we call it the upper authority (that is, the following commits the above). Downward override is a high-level user accessing low-level user information (then this is not acceptable, each of us must have a private life and small secrets).

Common scenarios for vertical unauthorized access
1. Unauthenticated account access can access the function without authentication
2. Accounts that do not have a certain function authority can successfully access the function after authentication

12. Common front-end security issues?

In the field of web security, XXS and CSRF are the two most common attack methods.

The full English name of XXS is Cross Site Script, and the Chinese translation is cross-site scripting attack. XSS (cross-site scripting attack) means that the attacker embeds javascript scripts in the returned HTML. In order to defend against XXS attacks, it is necessary to match the HTTP header with set-cookie: http-only; this attribute makes the script unavailable, it will Disable javascript scripts to access cookies. You can also use the verification code to log in, so as to prevent the script from pretending to be the user to perform some operations.

  1. Malicious scripts injected by attackers into client webpages generally include JavaScript, and sometimes HTML and Flash. There are many ways to carry out XSS attacks, but what they all have in common is: sending some private data such as cookies and sessions to the attacker, redirecting the victim to a website controlled by the attacker, and performing some Malicious operation.
  2. XSS attacks can be divided into three categories: storage (persistent), reflection (non-persistent), and DOM-based.

The full English name of CSRF is Cross-site request forgery, so it is also called "cross-site request forgery". To put it simply, a CSRF attack is a hacker who takes advantage of the user's login status and does some bad things through a third-party site.

Detailed understanding transfer: https://juejin.cn/post/6945277278347591688

13. localStorage、sessionStorage、cookie?

common ground
  1. SessionStorage, LocalStorage, and Cookie can all be used to store data on the browser side, and they are all string-type key-value pairs. The difference is that the former two belong to WebStorage, and they are created to facilitate the client to store data. Cookies have been supported as early as in Netscape's browsers, and the original purpose was to maintain the status of HTTP.
the difference
  1. The difference in storage size
    cookie: generally no more than 4K (because every http request will carry cookie, so cookie is only suitable for saving small data, such as session ID)
    localStorage and sessionStorage: 5M or larger
  2. The valid time of the data is different.
    cookie: The set cookie is valid until the expiration time, stored in the hard disk, and expires even if the window or browser is closed;
    localStorage: permanent storage, the data will not be lost after the browser is closed, unless manually permanently cleared, so Used as persistent data;
    sessionStorage: The life cycle is that the data is automatically deleted after the current browser window is closed.
  3. The interaction between the data and the server is different.
    The cookie data will be automatically transmitted to the server, and the server can also write the cookie to the client;
    sessionStorage and localStorage will not automatically send the data to the server, but only save it locally;
  4. The difference in usability
    cookie: The original cookie interface is not friendly, and needs to be packaged by the programmer.
    The native interfaces of sessionStorage and localStorage can be accepted or encapsulated again to have better support for Object and Array.
  5. Application Scenario cookie: determine whether the user has logged in to the website, so as to realize the next automatic login
    or remember the password; save event information, etc.

14. Browser caching policy? Strong cache (local cache) and negotiated cache (weak cache)?

  • According to whether it is necessary to re-initiate an HTTP request to the server, the caching process is divided into two parts: strong caching and negotiation caching.
  1. Strong cache, local cache stage: Before the browser sends a request, it will go to the cache to check whether it hits the strong cache. If it hits, it will directly read the resource from the cache without sending the request to the server. Otherwise, go to the next step. Two HTTP Headers can be set to achieve: Expires, Cache-Control.
  2. Negotiate caching. When the strong cache misses, the browser will definitely initiate a request to the server. The server will judge whether it hits the negotiation cache according to some fields in the Request Header. If it hits, the server will return a 304 response, but it will not carry any response entity, it just tells the browser that the resource can be obtained directly from the browser cache. If neither the local cache nor the negotiated cache is hit, the resource is loaded directly from the server. Negotiation caching can be implemented by setting two HTTP Headers: Last-Modified and ETag.

15. What is the token used for in the project? Why does the request carry token?

  1. Token means token. When the client logs in for the first time, the server will generate an encrypted string and then return it to the client. Later, every time the client requests resources from the server, it only needs to bring the token, and does not need to bring the user name and password to request.
  2. Why do you need to bring a token? It is because after the user logs in successfully, he will log in to the server to obtain data later. For each front-end request, the server has to verify which user sent it and whether the user is legal. Repeatedly querying the database in this way will put pressure on the server. When subsequent requests carry tokens, the server directly decrypts the tokens. Knowing the relevant information of the user saves the operation of querying the database and reduces the pressure on the database. This is what the token does. And because all basic requests must carry tokens, it cannot be manually configured every time, so we can uniformly encapsulate them in the request interceptor so that every request can carry tokens.

16. When you usually work on projects, what security vulnerabilities have you encountered?

(1) Add verification before submitting the form to prevent xss attacks. In order to prevent xss attacks, each field submission of the form needs to be verified or coded and filtered. For verification, you can use regular rules, such as verifying mobile phone numbers or email addresses. For encoding filtering, the submitted content needs to be encoded and filtered before submission to prevent special tags from being submitted to the background. For example, the user enters scripts such as '' or html tags. To filter out and prevent submission to the background.
(2) Restrict URL access and unauthorized access. 1 Add a verification method in the public module to check whether you have the corresponding permissions. For example, each customer can only view and modify their own information. In the parameters of the url address bar, there are parameters such as serial numbers. The attacker may think that the serial numbers of customers are arranged in order. If Is it possible to access other people's accounts by adding one and subtracting one in sequence (horizontal unauthorized access). Another is that different levels of logins have different functional permissions. A low-privileged user may access the account of a high-privileged user to use functions that it does not have. This is also an unauthorized access vulnerability, which belongs to vertical unauthorized access. 2 Monitor route jumps, add verification (route navigation guard) before route jumps. 3 Jointly debug with the background, store the corresponding information in the cookie, and compare it when accessing the data.
(3) File upload vulnerability. For example, a user uploading any type of file may allow an attacker to inject dangerous content or malicious code and run it on the server. Solution: 1 Strictly limit the file suffix and file type uploaded by users. 2 Define the white list of uploaded file types, and only allow the upload of files of the type in the white list. 3 The file upload directory prohibits execution of script parsing to avoid secondary attacks by attackers.

17. What is nodejs technology?

  • nodejs is a js runtime environment (a software that can run js code) based on the chrome V8 engine.
  • Nodejs is actually a platform for running js in a server environment, because it encapsulates Google's v8 engine to enable it to run js.
    (js: run on the browser, develop front-end programs. Nodejs: run on the server, develop back-end programs.)

4. Vue interview questions

1. What is the principle of vue2 two-way data binding?

  1. To give an example of two-way data binding, when you enter text in the input box, Vue will detect the change of the data, and then update the corresponding view. The reverse is also the same, if you modify the data through code, vue will also automatically update the view.
  2. The principle of two-way data binding is realized through data hijacking and publish-subscribe mode. First, vue hijacks the data through the Object.defineProperty() method, intercepts when the data changes, and calls the getter and setter methods. Secondly, when data changes are monitored, Vue will trigger the publish-subscribe mode, and Vue will notify all subscribers to update. Therefore, when the user makes changes on the page, vue will update the corresponding data and notify all subscribers to update the view; at the same time, when the data changes, vue will also update the corresponding view. Through such a mechanism, Vue implements two-way data binding, so that changes in data and views can affect each other.
  3. Supplement: Subscriber is a concept in Vue. It is an object used to manage and update views. When data changes, Vue will notify all subscribers to update. The publisher is the changed data, and the subscriber is the place where the variable is used in the page to update the data. [One publisher with multiple subscribers].
  4. In vue3, Object.defineProperty() is replaced with ES6 proxy object, because Object.defineProperty() can only hijack one property, and proxy can hijack all properties of the object

2. What is the difference between vue2 and vue3?

  1. The principle of two-way data binding of vue2 and vue3 has changed.
    The two-way data binding of vue2 is realized by using an API Object.definePropert() of ES5 to hijack the data and combine it with the publish-subscribe mode. ProxyAPI of es6 is used in vue3 to proxy data.
  2. Vue3 supports fragments (Fragments), which means that there can be multiple root nodes in a component.
  3. The biggest difference between Vue2 and Vue3 - Vue2 uses the option type API, and Vue3 synthetic type API. The old options API separated different attributes in the code: data, computed attributes, methods, etc. The new synthetic API allows us to use the method (function) stup(){} to divide, compared to the old API using attributes to group, so the code will be simpler and cleaner.
  4. Create data data. Vue2 puts data in data. In Vue3, we need to use a new setup() method, which is triggered when the component is initialized and constructed.
  5. Reactivity data is built using the following three steps:
    1. Import reactive from vue
    2. Use the reactive() method to declare our data as reactive
    3. Use the setup() method to return our responsive data so that our template can get it

3. What is virtual DOM?

  1. In Vue, virtual DOM (Virtual DOM) is a lightweight JavaScript object used to describe the hierarchy and properties of the real DOM. Whenever the data of a Vue component changes, Vue will first operate on the virtual DOM, and then synchronize the changed part to the real DOM, thus avoiding performance problems when directly manipulating the real DOM.
  2. The emergence of virtual DOM is to solve the problem of frequent operation of real DOM in traditional front-end development. Since the operation of the real DOM is often very performance-consuming, frequent operations will cause performance problems on the page. The virtual DOM can operate on the DOM in memory, and only when necessary, the changes are synchronized to the real DOM, thereby avoiding the performance problem of frequently operating the real DOM.
  3. Specifically, when the data of the Vue component changes, Vue will determine the parts that need to be updated by comparing the differences between the old and new virtual DOM trees, and synchronize these parts to the real DOM. This avoids unnecessary DOM manipulation, thereby improving the performance and responsiveness of the page.
  4. In addition, virtual DOM can also easily implement some advanced features, such as component reuse and animation effects. The virtual DOM enables Vue to implement these functions without manipulating the real DOM, thereby improving development efficiency.

4. Communication between vue components

1. Passing from parent to child: the parent component passes custom attributes to the child component, and the child component receives the bound properties in the parent component through props 2. Passing from child to parent
: the child component sends a custom event by broadcasting emit, and the The value is passed to the parent component, the parent component listens to the event, and triggers a function to receive the value passed from the child component. 3. Transfer value between brothers: ( 1 ) Transfer value through parent component, that is, A and B are sibling components, A can be passed to the parent component, and then passed to B by the parent component ( 2 ) New a Bus instance, in The custom method in the component that needs to send data sends a custom event through emit, passes the value to the parent component, the parent component listens to the event, and triggers a function to receive the value passed from the child component. 3. Passing values ​​between brothers: (1) Passing values ​​through parent components, that is, A and B are sibling components, A can be passed to the parent component, and then passed to B by the parent component. (2) A new Bus instance, when needed The custom method in the component that sends data, throughemit发送自定义事件,将值传递给父组件,父组件监听事件,触发一个函数去接收子组件中传递过来的值。3、兄弟间传值:(1)通过父组件中转来传值,即AB是兄弟组件,可以A传给父组件,由父组件再传给B(2)new一个Bus实例,在需要发送数据的组件中自定义方法,通过emit传递数据,在需要接收数据的组件生命周期created中,通过$on监听获取数据。
(3) 使用vuex状态管理,可以实现数据的随意存储和获取。

5. vuex状态管理工具的五个核心属性?

  • state: 用来存储公共数据的(变量),类似于组件中的data。
  • mutations:数据修改的逻辑,也是唯一修改state数据的地方。(提交更新数据的方法),它必须是同步操作,如果有异步操作的话,那么就需要actions。
  • actions:它也是用来改变数据的,但是它无法直接修改数据,actions提交的是mutations,在mutations里面更改数据,actions支持异步操作。
  • getters:从基本数据,派生过来的数据,相当于组件里的计算属性computed。
  • modules: It is used to modularize vuex, allowing each module to have its own state, mutation, actions, and getters to make the structure clearer and easier to manage.

6. The order in which vue child components and parent components are executed?

加载渲染过程:
父 beforeCreate -> 父 created -> 父 beforeMount -> 子 beforeCreate -> 子 created -> 子 beforeMount -> 子 mounted -> 父 mounted
子组件更新过程:
父 beforeUpdate -> 子 beforeUpdate -> 子 updated -> 父 updated
父组件更新过程:
父 beforeUpdate -> 父 updated
销毁过程:
父 beforeDestroy -> 子 beforeDestroy -> 子 destroyed -> 父 destroyed

7. What is the MVVM framework?

  1. MVVM is an abbreviation of Model-view-ViewModel, Model is a model, View view, and ViewModel is a view model, a bridge connecting view and model.
  2. To implement an observer, when the data changes, the ViewModel can detect the change of the data, and then notify the corresponding view to automatically update; when the user operates the view, the ViewModel can also monitor the change of the view, and then notify the data to make changes , which actually realizes the two-way binding of data.

8. Why is vue a progressive framework, and how do you understand it?

  1. When we start using a progressive framework, we can only use a certain part or part of the functions of this framework, instead of adopting the entire framework immediately and comprehensively. In other words, we can gradually apply the functions of the framework according to our own needs and the characteristics of the project.
  2. this way. It can make the way of adopting the new framework smoother, reduce the cost of learning, and at the same time better control the development progress of the project.
  3. In the project, we can gradually use different features such as template syntax, component system, vuex state management, routing, etc. If we don’t need certain features, we don’t use them, which makes it very flexible to use.
  4. For example. Vue is a state management tool vux, if our project is relatively simple, we can not use it, this is the concept of Vue progressive framework development. It means that you can use whatever you want in vue, and don’t use it if you don’t want to.

9. How to implement lazy loading of images?

  • Lazy loading is a technique that delays loading some non-critical resources when the page loads, in other words, loading on demand. When we encounter a long web page with many pictures, we first load a few pictures that appear in the viewport, and then load other pictures when the scroll bar scrolls to the position of the corresponding picture. This lazy loading method is lazy loading. (Rolled out height + screen height = document height)
  • How does image lazy loading work? That is, we first set the data-set attribute of the picture (of course, it can be any other, as long as it does not send http requests, the function is to access the value) as its picture path, because it is not src, so it will not send http ask. Then we calculate the sum of the height of the page scrolITop and the height of the browser. If the coordinate Y of the picture from the top of the page (relative to the entire page, not the browser window) is less than the sum of the first two, it means that the picture will be displayed (the right time, of course, it can also be other situations), at this time we can replace the data-set attribute with the src attribute.
  1. Vue uses vue asynchronous components and import in ES to implement lazy loading.

Asynchronous components use routing lazy loading, the method is as follows: component: resolve=>(require(['the address of the route that needs to be loaded']), resolve)

// 代码如下:
import Vue from 'vue'
import Router from 'vue-router'
  /* 此处省去之前导入的HelloWorld模块 */
Vue.use(Router)
export default new Router({
    
    
  routes: [
    {
    
    
      path: '/',
      name: 'HelloWorld',
      component: resolve=>(require(["@/components/HelloWorld"],resolve))
    }
  ]
})
  1. The import method proposed by ES, (----the most commonly used----)
方法如下:const HelloWorld = ()=>import('需要加载的模块地址')(不加 {
    
     } ,表示直接returnimport Vue from 'vue'
import Router from 'vue-router'

Vue.use(Router)

const HelloWorld = ()=>import("@/components/HelloWorld")
export default new Router({
    
    
  routes: [
    {
    
    
      path: '/',
      name: 'HelloWorld',
      component:HelloWorld
    }
  ]
})

10. Why does the token exist in both vuex and localStorage?

  1. The characteristics of vuex storage data: unified global management of data, once the data is updated in a certain component, all other component data will be updated, that is to say, it is responsive, but if the data only exists in vuex, the data in vuex will be refreshed when the page is refreshed Initialization, resulting in data loss, restores to its original state.
  2. The characteristics of localStorage (local storage) store data: permanent storage, but not responsive, when a component data is modified, other components cannot be updated synchronously.
  3. In addition, vuex is stored in memory, localStorage local storage is stored in disk, and the speed of reading data from memory is much higher than that of disk, so storing data in vuex can increase the speed of token acquisition and improve performance.
  4. Conclusion: So we usually use the two together in the project. After getting the token, store the token in localStorage and vuex. Vuex ensures that the data is updated synchronously between components. If the refresh page data is lost, we can get it from localStorage , realize data persistence by combining vuex and localStorage local storage.

11. In vue, should the request be written in created or mounted?

  1. created: The Chinese meaning is created. At this time, some attribute values ​​have been initialized, and the data and methods in the Vue instance are ready to use. However, it is not mounted on the page yet.
  2. mounted: Chinese means that the mount is completed. At this time, the initialization page is completed. At this time, the page has been rendered and DOM operations can be performed.

In actual development, whether the request is placed in created or mounted is mostly the same, because created and mounted are synchronous, and the request is asynchronous, which will not block the main thread of page rendering, and we cannot control the time when the request comes back . It mainly depends on personal habits.
But if it is necessary to operate dom-related requests, it must be executed in mounted, because at this time the page is mounted and the dom operation can be performed.
In addition, one thing to add is that the official document reminds everyone that the mounted phase does not guarantee that all subcomponents are also mounted. At this time, if we want to wait until the entire view is rendered before doing operations, we need to use to the this.$nextTick method.

12. The backend returns 100,000 pieces of data, how should the frontend handle it?

1. Bottom loading
  1. As long as you scroll once, you need to judge the loading time. When the height of the scroll + the height of the screen >= the height of the page, you need to load the next page of data.

We need to get the height of the scroll, the height of the window, and the height of the document.
Get the height that the page scrolls up: document.documentElement.scrollTop/document.body.scrollTop

Get the width and height of the current element: ele.offsetHeight/ele.offsetWidth
Get the width and height of the window: window.innerHeight
Get the width and height of the document: document.documentElement.scrollHeight

2. Virtual list
  1. Since the final effect needs to be in the form of a long list, conventional page-by-page rendering obviously does not meet the requirements. At this time, we can consider using a virtual list to meet the requirements.
  2. What is a virtual list?
    The virtual list is a technology that only renders the visible area, and does not render or partially renders the data in the non-visible area, so as to reduce consumption and improve user experience. It is an optimization for long lists and performs well.
  3. Implementation ideas:
  • (1) Write a div representing the visible area, fix its height, and allow vertical Y-axis scrolling through overflow.
  • (2) The second step is to calculate the number of data items that can be displayed in the area. This can be obtained by dividing the height of the visible area by the height of a single piece of data.
  • (3) Monitor scrolling, and calculate the height of the rolled-up data when the scroll bar changes.
  • (4) Calculate the starting index of the data in the area, that is, the first piece of data in the area: this can be obtained by dividing the rolled-up height by the height of a single piece of data.
  • (5) Calculate the end index of the data in the area. It can be obtained through the starting index + the number of data that can be displayed.
  • (6) Take the data between the start index and the end index and render it to the visible area.
  • (7) Calculate the offset position of the data corresponding to the start index in the entire list and set it to the list.
  • After the whole steps, the final effect is: no matter how we scroll, what we change is only the height of the scroll bar and the content of the elements in the visible area. Only a fixed number of bars will be rendered each time, and no redundant elements will be added.
<template>
    <div :style="{height: `${contentHeight}px`}" class="content_box" @scroll="scroll">
        <!--这层div是为了把高度撑开,让滚动条出现,height值为所有数据总高-->
        <div :style="{'height': `${itemHeight*(listAll.length)}px`, 'position': 'relative'}">
            <!--可视区域里所有数据的渲染区域-->
            <div :style="{'position': 'absolute', 'top': `${top}px`}">
                <!--单条数据渲染区域-->
                <div v-for="(item,index) in showList" :key="index" class="item">
                    {
    
    {
    
    item}}
                </div>
            </div>
        </div>
    </div>
</template>

<script>
export default {
    
    
    name: "list",
    data(){
    
    
        return{
    
    
            listAll: [],  //所有数据
            showList: [],  //可视区域显示的数据
            contentHeight: 500,  //可视区域高度
            itemHeight: 30,      //每条数据所占高度
            showNum: 0,  //可是区域显示的最大条数
            top: 0, //偏移量
            scrollTop: 0,  //卷起的高度
            startIndex: 0,  //可视区域第一条数据的索引
            endIndex: 0,  //可视区域最后一条数据后面那条数据的的索引,因为后面要用slice(start,end)方法取需要的数据,但是slice规定end对应数据不包含在里面
        }
    },
    methods:{
    
    
        //构造10万条数据
        getList(){
    
    
            for(let i=0;i<100000;i++){
    
    
                this.listAll.push(`我是第${
      
      i}条数据呀`)
            }
        },
        //计算可视区域数据
        getShowList(){
    
    
            this.showNum = Math.ceil(this.contentHeight/this.itemHeight);  //可视区域最多出现的数据条数,值是小数的话往上取整,因为极端情况是第一条和最后一条都只显示一部分
            this.startIndex = Math.floor(this.scrollTop/this.itemHeight);   //可视区域第一条数据的索引
            this.endIndex = this.startIndex + this.showNum;   //可视区域最后一条数据的后面那条数据的索引
            this.showList = this.listAll.slice(this.startIndex, this.endIndex)  //可视区域显示的数据,即最后要渲染的数据。实际的数据索引是从this.startIndex到this.endIndex-1
            const offsetY = this.scrollTop - (this.scrollTop % this.itemHeight);  //在这需要获得一个可以被itemHeight整除的数来作为item的偏移量,这样随机滑动时第一条数据都是完整显示的
            this.top = offsetY;
        },
        //监听滚动事件,实时计算scrollTop
        scroll(){
    
    
            this.scrollTop = document.querySelector('.content_box').scrollTop;  //element.scrollTop方法可以获取到卷起的高度
            this.getShowList();
        }
    },
    mounted() {
    
    
        this.getList();
        this.scroll();
    }
}
</script>

<style scoped>
.content_box{
    
    
    overflow: auto;  /*只有这行代码写了,内容超出高度才会出现滚动条*/
    width: 700px;
    border: 1px solid red;
}
/*每条数据的样式*/
.item{
    
    
    height:30px;
    padding: 5px;
    color: #666;
    box-sizing: border-box;
}
</style>

13. What is a slot? How are slots used?

  • Vue implements a set of APIs for content distribution, using elements as the outlet for carrying and distributing content.
  • Slots can be used to dynamically specify the rendering of a certain component template part. When we call the component, what kind of label structure is passed in the middle of the component's call label, then the component will put the label structure we passed in its The template part is rendered.
  • To give an example, if you add a piece of HTML to a custom component tag, the DOM elements in it will not be rendered by default, but if you write a slot in the subcomponent template, the tag The content will automatically be placed where you wrote the slot label.
  • Vue's slots are mainly divided into three types: default slots, named slots, and scoped slots.
  • Named slot: A slot with a name. If there are multiple slots in a component, it can be written as a named slot, and the content provided for the slot is placed in the position corresponding to the name.
<div id="app">
    // 子组件 
	<Child>
		// 给插槽提供的内容
		<template v-slot:default>
			<button>按钮</button>
			<a href="https://huawei.com">跳转华为</a>
		</template>
		
		<template v-slot:header>
			<h1>标题</h1>
			<p>内容,21231215456454</p>
		</template>
	</Child>
</div>

<Child>子组件的模板中:
<div>
	<h1>这是子组件的内容</h1>
  	<slot></slot>   	// 给插槽提供的内容将会被放在这个位置,这是默认插槽
</div>
  1. The use of slots is a component with a parent-child relationship. The position of the slot can be determined in the sub-component, and the sub-component can also give the default information of these slots. When there is no need to insert information for the slot of the sub-component in the parent component, Shown is the default information for subcomponent slot definitions.

14. What is a SPA?

  • SPA (Single Page Application), single-page application, using vue, react, angular, the projects created belong to SPA.
  1. Single-page applications only load the corresponding HTML, js, and css when the web page is initialized. Once the page is loaded, the page will not be reloaded or redirected due to user operations. Simply put, SPA has only one web page, for example: the vue project only has one index.html, but why can we see different pages? This is because of vue's routing mechanism, which realizes HTML content by monitoring changes in routing. Transformation, so as to dynamically realize the interaction between the UI and the user, just like we switch from one menu item to another in the Vue project. Although the content of the page has changed, it does not request a new html action, but It is to find the page corresponding to the current route through the changed route.
  2. Advantages of SPA: 1. Since the resources that the project depends on are loaded uniformly when the page is initialized, there is no need to request the server after switching pages. Therefore, the switching speed is fast and smooth, and the user experience will be better. To a certain extent It will also reduce the pressure on the server. 2. The front-end and back-end responsibilities are clearer. The front-end is responsible for page-related work and adjusting the back-end interface to get data; the back-end is responsible for data-related processing.
  • Disadvantages of SPA: The loading of the first screen is slow, because it is a single-page application, and all resources will be loaded uniformly when loading for the first time. Of course, as a solution during optimization, some pages can also be loaded on demand. In addition, since all content is dynamically replaced and displayed on one page, it has a natural weakness in SEO, which is not conducive to search engine optimization.

15. How do you understand the one-way data flow of vue?

  • Single-item data flow is top-down, but it cannot be bottom-up.
  • One-way data flow in Vue means that the parent component can pass values ​​to the child components, and the child components cannot directly modify the value passed by the parent component.
  • Prop is the data passed from the parent component. If we try to change the prop through the v-model of the child component, that is, we try to directly change the data of the parent component through the child component instead of sending events. Allowed.

16. At what stage can the DOM be accessed and manipulated?

  • Before calling mounted.
  • Before the hook function mounted is called, Vue has mounted the compiled template to the page, so the DOM can be accessed and manipulated in mounted.

17. What is a micro frontend?

Micro-frontend is an architecture similar to microservices. It applies the concept of microservices to the browser side, that is, transforms a web application from a single single application to an application that aggregates multiple small front-end applications into one. Each front-end application can run independently, develop independently, and deploy independently. (It is recommended to understand microservice first)
(1) Microservice is an architectural style
(2) Microservice is to split a project into multiple independent services, and multiple services can run independently, and each service will Occupy threads.

18. How to solve the Jquery version leakage problem?

The correct solution: upgrade the version.

19. What are the life cycles of vue?

创建阶段: 只执行一次。
    beforeCreate(开始进行一些数据和方法的初始化的操作, data 中的数据和 methods 中的方法还不能用)。
    created(已经完成数据和方法的初始化, data 中的数据和 methods 中的方法可以使用了)。
挂载阶段:
    beforeMount(开始渲染虚拟 DOM)。
    mounted(已经完成了虚拟 DOM 的渲染, 可以操作 DOM 了, 只执行一次)。
更新阶段: 执行多次
    beforeUpdate(data 中的数据即将被更新, 会执行多次)。
    updated(data 中的数据已经更新完毕, 会执行多次)。
销毁阶段: 只执行一次
    beforeDestroy(vue 实例即将销毁, 此时 data 中的数据和 methods 中的方法依然处于可用状态)。
    destroyed(vue 实例已经销毁, 此时 data 中的数据和 methods 中的方法已经不可用)。

20. What is the difference between computed and watch?

  1. Computed is a computed attribute, and if the dependent data changes, the result will be recalculated, so computed is needed.
  • The most typical example is the total amount when the shopping cart is settled, which is calculated depending on the quantity and unit price; in addition, computed supports caching, and will only be recalculated when the dependent data changes, otherwise, it will be directly from the cache read. The use method is basically the same as the data in data, and the calculated attribute does not support asynchronous operation. When there are asynchronous operations in computed, it is invalid and cannot monitor data changes. (The function of the calculated property must have a return value)
  1. Watch is a monitor. When a change in data will affect one or more other data, you need to monitor this data. Watch does not support caching, and changes in monitored data will trigger corresponding operations. Pay attention to the process. No need to return a value, both synchronous and asynchronous.
  • In addition, watch supports asynchrony, and the data we monitor must be the data declared in data, or the data in props passed from the parent component. In addition, each monitoring data has two optional attributes, which are immediate and deep. immediate is whether the component loading triggers the execution of the callback function immediately. If its value is true, the component loading will be triggered immediately; if it is false, the monitoring logic will not be executed for the first time, and it will only be monitored when the data changes. deep is a deep monitoring, in order to monitor the change of the internal value of the object, it is suitable for use in complex types of data. (floor navigation, when switching floors, monitor the changes of the floor index and adjust the position of the scroll bar)

26. Why is Data a function?

Because the object is a reference data type, there is only one copy in memory. If the value of data is directly an object, then when the later components are called multiple times in different places, they will affect each other, because each call operation The data object is the same. Using a function to return an object can ensure that each call of the component will create a new object, so that each call of the component will not affect each other.

27. The difference between v-if and v-show

  • The common point is that both v-if and v-show can display and hide elements.
  • Difference: 1. v-show simply controls the display attribute of the element, while v-if is conditional rendering (if the condition is true, the element will be rendered, and if the condition is false, the element will be destroyed); 2. v-show has Higher initial rendering overhead, while the first rendering overhead of v-if is much smaller; 3. v-if has higher switching overhead, while v-show switching overhead is small; 4. v-if has supporting v-else -if and v-else, while v-show does not. 5. v-if can be used with template, but v-show cannot.

28. The usage scenarios of v-show and v-if

  • Both v-if and v-show can control the display of dom elements on the page.
  • Compared with v-show, v-if has more overhead (directly operate dom node addition and deletion). If you need to switch very frequently, it is better to use v-show. If the condition rarely changes at runtime, it is better to use v-if.

29. Why do you try not to use the index value as the key value for dynamic binding when looping in vue?

  1. In Vue, looping is usually implemented using the v-for directive. The v-for directive usually needs to bind a key value to help Vue track the identity of each list item so that it can be efficiently updated when the list changes.
  2. Using index values ​​as keys may cause some problems. For example, this can be problematic if your list items are reordered or filtered during the loop. Since index values ​​are assigned sequentially, if you insert or remove an item in the middle of the list, all subsequent items' index values ​​will change, causing Vue to do unnecessary re-renders.
  3. 此外,使用索引值作为key值还可能导致性能问题。在处理大型列表时,Vue可能需要在每次更新时对整个列表进行重新渲染,这可能会导致性能瓶颈。
  4. 为了避免这些问题,建议使用列表项中具有唯一标识符的属性作为key值。这可以确保每个项具有唯一的身份,并且在列表中进行排序或过滤时仍然能够正确更新。如果您的列表项没有唯一标识符,则可以考虑创建一个。

30. nextTick

  1. 在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。
// 修改数据
vm.msg ='Hello'// DOM 还没有更新
Vue.nextTick(function(){
    
    
// DOM 更新了})

this.$nextTick()

31. 说一下keep-alive 标签的作用,以及它的使用场景?

  1. 在Vue中,keep-alive标签可以用来缓存组件,当一个组件被包裹在keep-alive标签中时,离开当前页面时,这个组件不会被销毁,而是被缓存起来,当这个组件再次被使用时,Vue会从缓存中提取组件实例,并重新挂载,而不是重新渲染。
  2. 这个功能可以提高应用的性能,特别是在需要频繁切换组件的场景下,就比如Tab切换或者路由切换,因为不需要每一次切换时都重新创建和销毁组件,而是直接从缓存中获取,这样可以避免重复的初始化和渲染,从而提高应用的响应速度和性能。
  3. 举个应用场景,有个员工列表,现在我们点击某条数据,查看员工详情后,再返回到员工列表,这个时候我们就希望这个列表能够保持刚才的状态,这时候就可以使用keep-alive把这个列表所在的组件包裹起来。

32. 组件化和模块化一样吗?

  1. 模块化是从代码逻辑角度进行划分的,保证每个模块的职能单一,比如登录页的登录功能,就是一个模块,注册功能又算是一个模块。
  2. 组件化,是从UI界面的角度划分的;页面上每个独立的区域,都可以视为一个组件,前端组件化开发,便于UI组件的复用,减少代码量。
  3. 区别是:划分角度不同,组件化是从UI界面角度来划分的,模块化是从代码逻辑角度来划分的。

33. data和props的区别?

  • 在实际vue项目中,我们经常会在子组件里看到data和props属性,这两者里面的数据使用方式基本是一致的。但是还是有一定的区别。
  1. data does not need to pass values ​​from the parent component, and maintains itself; while props needs to pass values ​​from the parent component.
  2. The data on data is readable and writable; and the data of props is passed from the parent component, and because it is a one-way data flow, the data is only readable and cannot be re-modified.
  • If the passed props value is a basic type (like Number, Boolean, String) and the subcomponent is directly modified, the console will definitely report an error, but if the passed props value is a reference type, like Object, array structure, the subcomponent modifies the property value or For a certain array element, the console will not report an error. Because only the value is changed for the reference type, not the reference address.
  • However, no matter what form of data is passed, we do not recommend directly modifying the value of Props in subcomponents, because this will destroy the single data flow and may cause data changes to be untracked.
Q: What is the correct operation to modify props in subcomponents?
  • Answer: If the child component just wants to use it after modification and does not want to affect the data of the parent component, then we can define a variable in the data in the child component, so that the initial value of this variable is equal to the props value passed from the parent component, which is quite Make a copy of this props value, and if you need to modify it later, change this value in your own data. This will not affect the parent component. If you want to modify the value of the parent component synchronously after processing, you can trigger the parent component to modify it through the this.$emit event.

34. What is the difference between white screen time and first screen time?

  1. White screen time (First Paint): refers to the time when the user enters the content and press Enter until the first character appears in the browser, that is, the time when the content starts to be displayed. Therefore, the white screen time = the time when the page starts to display - the time when the request starts.
  2. First Contentful Paint: It refers to the time from when the browser responds to the user inputting the network address to when the first content is rendered. Therefore, the first screen time = the end time of the first screen content rendering - the time when the request is started.
  • Through the two concepts just now, we know that the first screen time must be longer than the white screen time, because another calculation of the first screen time is: first screen time = white screen time + time from the first screen rendering to the end of rendering.

35. Say three ways to refresh the page?

  1. Native js method: location.reload(), we only need to add such a line of code in the place that needs to be refreshed to achieve refresh.
  2. With the help of the routing jump method in Vue: if you need to refresh, write this.$router.go(0). This method explains that we want to jump to the route, and the page that needs to be jumped is this page, so it is go(0), so that the page can be reloaded.
  3. provide / inject combination. The first two methods are forced to refresh, and the page will be blank for a short time, while provide/iniect is a normal refresh, which will not make the page blank. This method allows an ancestor component to provide data to all its descendants through provide. No matter how deep the component hierarchy is, subcomponents can be injected through inject to receive this data.

Specific implementation: define a boolean type of data in the app.vue file of the project, use v-if to control whether router-view is displayed, and define a refresh function at the same time, the internal logic of the function is mainly to set the display to false, and wait for nextTick to execute Then set the display to true to reload the page; after writing the refresh function, inject the dependency provided by provide in app.vue just now through inject in the component that needs to be refreshed, that is, the refresh function, and then call this function directly Refresh can be achieved.
To sum up, what the refresh function does is, when we want to refresh, we call the refresh function, combined with the function of v-if, first set whether the component is displayed to false to let the component be destroyed first, and then set whether to display to true to let the component create . In addition to the above methods, there are also refresh methods such as this.$forceUpdate().

36. How to change the background color of a page separately in vue?

[Requirement] The background color of the global page is white, and now it is necessary to change the background color of a certain page to gray.
[Invalid] Try to directly change the style of the body tag, but after setting, it is found that the background color of all pages has become gray.
[Reason] Vue is a single-page application with only one index.html, which can affect the whole body.
[Correct method] Before this page is created, that is, in the beforeCreate life cycle function, change the body background color to the color we want, and before the page is destroyed, that is, in the beforeDestroy life cycle hook, remove the one we just added The background color style. In this way, when jumping to other pages, the body background color just added on that page will be removed, and the global background style will continue to be used.
The specific code is:

beforeCreate(){
    
    
	document.querySelector('body').setAttribute('style','background-color:#fff')
},
beforeDestroy() {
    
    
    document.querySelector('body').removeAttribute('style')
 },

In addition to changing the background style of the body on the page that needs to be modified, we can also seal this logic in the route guard, and when entering the page route that needs to be changed, do the style operation just now. Removed when leaving this route.

37. What is the function and usage scenario of ref?

  1. ref can be used to get dom elements. If we bind ref="test" to an element, then we can this.$refs.tesget dom through t, and then do some operations we need.
  2. ref can also get methods or data in subcomponents. If you bind a ref to the child component, the value is still assumed to be test, then pass it in the parent component this.$refs.test, you can get a VueComponent object, which contains various properties of the child component, and you will find that there is a $elproperty in it when you print it out , this is the dom object of this subcomponent. If there is a msg attribute in the data of the child component, then we can get this.$refs.test.msgthe msg value of the child component in the parent component; and assuming that the child component has a getData method, then the this.$refs.test.getDgta()getData of the child component can also be called in the parent component method.

38. Where should static resources be placed? The difference between assets and static?

  • The directory structure of the vue project usually has an assets folder under the src directory, and a static folder at the same level as src.

[Same point] Both folders can be used to store static resources required in the project, such as pictures, style files, etc.

[Difference] When the static resource files stored under assets are packaged in the project, that is, when the npm run build command is executed, the packaging process of webpack will be followed to compress the code size and format the code; put the resource files stored in static It will not go through the packaging process, but will be directly copied into the final dist directory. So if you put all the resources in static, since the resources in this folder will not go through the packaging process, it will improve the efficiency when packaging the project, but there is also a problem, that is, it will not be compressed, etc. Operation, so the volume of the packaged project will be larger than putting all resources into assets.

[Summary] After we package the project through npm run build, a dist folder will be generated. The resources in assets will be packaged by webpack and put into the dist folder, while the resources in static will be directly copied into dist. Third-party library resources have generally been processed, so we can put some external third-party resource files in static, and assets put resources such as pictures in our own project, let these resources go through the packaging process, and reduce the volume of the final package . However, the situation in actual development is definitely changeable, and it is still more appropriate to place static resource files according to the actual situation.

39. What is the difference between route and router in vue?

  1. this.$routerIt is an instance of VueRouter, and it is a global routing object. It can be used to operate routing. It is more commonly used in projects to make routing jumps. For example, when we often need to jump to another page, we will write it. It is this.$router.push( )the this.$routecurrent The activated routing object, through which we can get some information about the current routing such as path, query, meta and other attributes.
  2. For example, we want to view the details of a piece of data. When we click on the details, we need to jump to the details page. Here we can do the jump this.$router.push, and we can pass this item to the query object of the detail routing object that we will jump to. The id of the data is to get the details of the data through this id and display it after the route jumps. How to get the id after the jump, we can get all the information of the current route first, and then go to the query this.$routeobject Take the id attribute that was just put in before the previous page jump, so that you can check the detailed data after getting the id. Complete is this$route.query.id.

In a nutshell, route is used to obtain current routing information, that is, to read routing information, while router is used to operate routing and write routing.

40. How to judge that it has entered the visible area?

41. How do you jump in normal projects?

  1. The first method is the label. We can add the to attribute in the label to configure the path that needs to be redirected. When the browser parses it, it will parse it into something similar to the a label.
  2. The second solution is this.$router.push()the method. We can use this method of routing in a certain function to realize the jump.
  3. The third method is that this.$router.replace()when this.$router.push()jumping to the specified url path, a record will be added to the history stack at the same time. Click Back to return to the previous page. this.$router.replace()The method jumps to the specified URL path and clicks to return. He is jumping to you The last page you see means that the target page is directly replaced instead of adding a record.
  4. The fourth method this.$router.go(n), we can use this method to jump forward or backward n pages, for example, if n is 1, we can jump to the next page, if it is -1, we can go back to the previous page, and 0 is the current page page.

43. How to make the echarts chart self-adaptive in the project?

[Requirement] When the size of the browser window changes, the echarts chart should change with the browser window.
[Solution] The window.addEventListener method monitors the change of the window. When the window changes, let the echarts instance that needs to be self-adaptive call the self-adaptive resize method provided by echarts official. You can write the following code in the mounted hook function, so that you can realize self-adaptation adapted.

window.addEventListener('resize',  () => {
    
    
    myEchart.resize();
});

44. How many ways to implement lazy loading of images?

  1. Background and principle
  • In the front-end project, when there are many pictures on the page, it takes a certain amount of time to load the pictures, which consumes a lot of server performance, not only affects the rendering speed but also wastes bandwidth. In order to solve this problem and improve the user experience, it appears Lazy loading is used to reduce the pressure on the server, that is, the content of the visible area is loaded first, and the content of other parts enters the visible area before loading, thereby improving performance.
  1. Implementation ideas
  • Pictures are loaded according to the src attribute, so we can not assign a value to src before the picture enters the visible area (or give a small address of the loading picture first), and wait until the picture enters the visible area before giving src assigns the real value. The real address of the picture can be stored in data-src first. After understanding the implementation idea, let’s continue to the most critical step, which is how to calculate whether the picture has entered the visible area?
  1. Specific implementation
<div>
    <h6>图片懒加载</h6>
    <img data-src="/static/images/login-bg-3.jpg" src="/static/images/login-bg-4.jpg"><br>
    <img data-src="/static/images/login-bg-1.jpg" src="/static/images/login-bg-4.jpg"><br>
    <img data-src="/static/images/login-bg.jpg" src="/static/images/login-bg-4.jpg"><br>
    <img data-src="/static/images/login-bg-3.jpg" src="/static/images/login-bg-4.jpg"><br>
    <img data-src="/static/images/login-bg-old.jpg" src="/static/images/login-bg-4.jpg"<br>
    <img data-src="/static/images/login-bg-1.jpg" src="/static/images/login-bg-4.jpg"><br>
    <img data-src="/static/images/login-bg.jpg" src="/static/images/login-bg-4.jpg"><br>
</div>

The first type: vue-lazyload plug-in implementation
(1) Install the plug-
in npm install vue-lazyload --save-dev (2) Introduce and use import VueLazy from 'vue-lazyload' Vue.use(VueLazyload)
in the main.js file (3) Modify the image display method to lazy loading. Change the :src="xxx" attribute directly to v-lazy="xxx"


The second type: IntersectionObserver API implementation.
This api can automatically "observe" whether an element is visible, Chrome 51+ already supports it. Since the essence of visibility is that the target element and the viewport create an intersection area, this API is also called an intersecting viewer.


created() {
    
    
    this.intersectionObserver();
},
methods:{
    
    
    intersectionObserver(){
    
    
        let images = document.getElementsByTagName('img');
        const observer = new IntersectionObserver((imgs) => {
    
    
          console.log('imgs===', imgs)
          // imgs: 目标元素集合
          imgs.forEach((img) => {
    
    
            // img.isIntersecting代表目标元素可见,可见的时候给src赋值
            if (img.isIntersecting) {
    
    
              const item = img.target
              item.src = item.dataset.src
              observer.unobserve(item);
            }
          })
        })
      //定时器和Array.from的目的是让images可遍历
      setTimeout(()=>{
    
    
        Array.from(images).forEach(item => {
    
    
          observer.observe(item);
        })
      },300)
    }
}
// isIntersecting 为true 代表该目标元素可见,可以加载;target 即对应页面中的真实img。

The element's offsetTop API implementation.
The conditions for judging entering the visible area have changed. From the figure below, we can see that the judging condition for entering the visible area here is that e.offsetTop < document.body.clientHeight + document.body.scrollTop of an element e is
relative to the obtained object The calculated top position of the layout or the parent coordinates specified by the offsetTop property < the height of the visible area of ​​the web page + the height of the web page being rolled away

Guess you like

Origin blog.csdn.net/m0_56232007/article/details/129427825