preface
This paper will sort out and summarize some common important knowledge points and framework principles in Vue, aiming to help the author and readers to self-test Vue proficiency and facilitate inquiry and review. With the arrival of Gold, silver, and Silver, VUE will be a key assessment content for many interviewers. I hope that after reading this article, you can improve yourself to a certain extent. I also hope that this article can escort your interview
If this article helps you, ❤️ follow + like ❤️ to encourage the author, the article public account first, followThe front nine south
The first time to get the latest articles ~
Github star❤️❤️
1. The difference between MVC and MVVM
MVC
MVC full name is Model View Controller, is the abbreviation of Model – View – Controller, a Model of software design
- Model: Is the part of the application that handles the application’s data logic. Typically, model objects are responsible for accessing data in a database
- View: Is the part of the application that handles the display of data. Views are usually created from model data
- Controller: Is the part of the application that handles user interaction. Typically the controller is responsible for reading data from the view, controlling user input, and sending data to the model
Let’s look at this picture from the Stanford Open class to illustrate, which is arguably the most classic and canonical MVC standard
Almost all apps do one thing: show the data to the user and handle what the user does to the interface. The idea of MVC is that the Controller is responsible for displaying the Model’s data in the View. In other words, the Controller assigns the Model’s data to the View.
MVVM
MVVM: Model, View, ViewModel.
You’ll subconsciously compare it to MVC, and you’ll see that MVVM has one more ViewModel and one less Controller.
Let’s start with the extra ViewModel (VM, not video memory). The point of VM, like Model, is data. The Model is responsible for fetching and storing data, but in addition to fetching and storing data, there is another very important operation: parsing
M: corresponds to M for MVC
V: corresponds to THE V of MVC
VM: ViewModel is to separate the data loading and processing functions of the CONTROLLER in MVC
The difference between
The biggest difference between MVVM and MVC is: It realizes automatic synchronization between View and Model, that is, when the Model property changes, we no longer need to manually manipulate Dom elements to change the display of View, but after changing the property, the corresponding View layer display will automatically change (corresponding to the Vue data-driven idea).
Vue does not follow MVVM’s ideas exactly
This point Vue official website has its own explanation
This is because, strictly speaking, MVVM requires that the View and Model cannot communicate directly, and Vue violates this rule by providing the $refs attribute that allows the Model to manipulate the View directly, so Vue is not fully compliant with MVVM.
2. Why does data need to be a function?
This expression is mainly used in components, because components can be reused, js objects are reference relationships, if the component data is an object, then the data property values in the sub-components will pollute each other, causing side effects. If the data option in the component is a function, then each instance can maintain a separate copy of the returned object, and the data property values between component instances do not affect each other. The instance of new Vue is not reused, so there is no object reference problem.
3. V – if with v – show
Difference between V-if and V-show
V-if is true conditional rendering because it ensures that event listeners and subcomponents within the conditional block are properly destroyed and rebuilt during the switch; Also lazy: if the condition is false during the initial render, nothing is done — the conditional block does not start rendering until the condition is true for the first time.
V-show is much simpler — elements are always rendered regardless of initial conditions, and simply switch based on the “display” property of CSS.
Therefore, V-IF is suitable for scenarios where conditions are rarely changed at runtime and do not need to be switched frequently; V-show is suitable for scenarios that require very frequent switching of conditions.
Is the V-show command a rearrangement?
The essence of V-show is to control the display of elements through the display attribute of CSS. In DOM rendering, elements will still be rendered first before judging whether to display (through the display attribute). The definition of rearrangement is that the information of nodes in the rendering tree changes in size and margin, etc. Recalculate the exact size and location of each node and CSS. When using display to control the display and hiding of elements, it changes the size of nodes and the layout of the rendered tree, causing rearrangement, so the V-show command is a rearrangement.
4.v-for
Why not use v-if and V-for together?
First, about the v – the if and the v – for priority, can be in the source code compiler/codegen/index found in js genElement method, inside the if else, you can clearly see the for judgment on the if judgment, therefore, to prove that the v – for the priority of higher v – the if
If v-if and V-for occur at the same time, there are two cases:
-
Vue.$options.render (” for “, “if”); render (” for “, “if”)
-
$options. Render vue.$options.render vue.$options. Render vue.
To optimize and improve performance, v-IF needs to be executed first. You can add a template layer to the outer layer of v-FOR to match v-IF. If v-if and V-for must appear in the same layer or v-if is a sub-level of V-for, the optimized way can advance the array of the for loop through the calculation attribute processing to minimize the performance consumption caused by excessive rendering.
What does the key in V-for do? Why is it not recommended to use a random number or index for key in V-for?
Key enables vUE diff operations to be more accurate and faster
If keys are not used, Vue uses an algorithm that minimizes dynamic elements and tries to modify/reuse the same type of elements in place whenever possible. The key is a unique token for a Vnode in a Vue. With this key, our diff operation can be more accurate and faster
The sameNode function a. keey === B. Keey can be compared with the sameNode function a. keey === B. So it’s more accurate.
Faster: Using the uniqueness of keys to generate map objects to obtain corresponding nodes, faster than traversal
Why is it not recommended to use a random number or index for key in V-for?
Because when inserting or deleting data, the index of the key binding of the following data will change, leading to re-rendering, which will reduce efficiency and also lead to rendering errors. When the data changes, the key is used to determine whether the virtual DOM tree has changed. If the same DOM-key is found, it can be reused directly. Reduced performance cost of rendering. So using a random number or index as the key can lead to wasted performance, and using index as the key can lead to rendering errors.
In what order does v-for traverse objects? How to ensure the order?
First check if there is an iterator interface, and if there is a loop execute next()
2. In the absence of iterator, the object.keys () method is called. The JS engine cannot guarantee the same order of output in different browsers
3, ensure the order of the output of objects can be placed in an array, as array elements
5. Common Vue built-in instructions
6. Several ways of Vue component communication
props/$emit
This is used for communication between parent and child components. The parent component passes data to the child component via props, and the child component can communicate to the parent component via $emit.
<! Class ="section"> <childItem :list="list" @update="update"></childItem> </div> </template> <script> import childItem from './childItem' export default { name: 'parent', components: { childItem }, data() { return { currentIndex: 0, list: [{id:1,title: 'nanjiu'}, {id:2, title:'FE'}, {id:3, title:'boy'}] } }, methods: { update(index) { this.currentIndex = index } } } </script>Copy the code
<! --> <template> <div> <span v-for="(item, index) in list" :key="item.id" @click="update(index)">{{item}}</span> </div> </template> <script> export default { props: { list: Array }, methods: { update(index) { this.$emit('update', index) } } } </script>Copy the code
Conclusion:
props
It can only be passed from one level of component to the next level (parent and child components), known as one-way data flow. And it isprops
Read-only, cannot be modified, all changes will be invalidated and warned.$emit
Bind a custom event that passes arguments to the parent component when the statement is executed, and the parent component passesv-on
Listen for and receive parameters.
$parent/$Children
Let’s take a look at the official explanation of these two apis:
$parent = $children; $child = $child; $parent = $child; $child = $child;
<! -- Parent component --> <template> <div class="section"> <childItem></childItem> </div> </template> <script> import childItem from "./components/item"; Export default {name: "parent", components: {childItem}, data() {return {currentIndex: 0, MSG: "parent",}; {}, mounted () the console. The log (` components, I am father I'm access ${this. $children [0]. MSG}... `); }}; </script>Copy the code
<! <div class="item"> </div> </template> <script> export default {name: "Item ", data() {return {MSG:" subcomponent "}; }, mounted() {console.log(' console.log ') {${this.$parent. `); }}; </script>Copy the code
ref
If used on a normal DOM element, the reference refers to the DOM element. If used on a child component, the reference refers to the component instance
<! Export default {data () {return {name: 'nanjiu'}}, methods: { sayHello () { console.log('hello, I am nanjiu') } } }Copy the code
<! -- parent component --> <child ref="child"></child> </template> <script> import child from "./child" export default { components: {child}, mounted () { const child = this.$refs.child; console.log(child.name); // nanjiu child.sayHello(); // hello, I am nanjiu } } </script>Copy the code
provide/inject
Provide/Inject is a new API in Vue2.2.0. Simply put, provide variables in the parent component and inject variables in the child component. And inject data in provide can be injected as long as inject is invoked, no matter how deep the subcomponents are nested
<! -- Root component --> <template> <div class="section"> <childItem></childItem> </div> </template> <script> import childItem from "./components/item"; Export default {name: "parent", components: {childItem}, data() {return {currentIndex: 0, MSG: "root component"}; }, provide() { return { rootMsg: this.msg }; {}, mounted () the console. The log (` components, I am father I'm access ${this. $children [0]. MSG}... `); }}; </script>Copy the code
<! <div class="item"> <subItem /> </div> </template> <script> import subItem from "./ subitem.vue "; Export default {name: "item", Components: {subItem}, inject: ["rootMsg"], data() {return {MSG: "subcomponent"}; export default {name: "item", Components: {subItem}, inject: ["rootMsg"], data() {return {MSG: "subcomponent"}; }, mounted() {console.log(' I am a child component, I am calling ${this.rootmsg}... `); // I am a child component, I am accessing the root component... }}; </script>Copy the code
<! <div ></div> </template> <script> export default {name: "subItem", inject: ["rootMsg"], mounted() {console.log(${this.rootmsg} '); // I am the grandchild component, I am accessing the root component}}; </script>Copy the code
eventBus
EventBus, also known as the eventBus, can be used in vue as a bridge concept, as all components share the same event center to which they can register to send and receive events, so that components can notify other components. Use $ON to subscribe to events and $emit to publish events
Prototype.$bus = new Vue() // Use a Vue instance to hold the central event // subscribe event <template> <div class="section"> <childItem :list="list" @update="update"></childItem> </div> </template> <script> import childItem from "./components/item"; export default { name: "parent", components: {childLoad}, mounted() {this.$bus.$on("childLoad", () => {console.log(' I am the parent of the child '); // I am the parent component and I have detected that the child component is loading}); }}; </script> // Release event <template> <div class="item"> Child </div> </template> <script> export default {name: "item", mounted() { window.addEventListener("load", e => { this.$bus.$emit("childLoad"); }); }}; </script>Copy the code
$attrs/$listeners
If a cross-level component uses props to communicate with emit, it would be too cumbersome to pass data and events down layer by layer. So vue2.4 introduces $attrs and $Listeners to address this requirement, and adds the inheritAttrs option. Prior to version 2.4, feature bindings (except class and style) that were not recognized (and retrieved) as props in the parent scope by default were “rolled back” and applied to the root element of the child component as normal HTML features.
// Root component <template> <div class="section"> <childItem :list="list" : MSG =" MSG "@update="update" @rootFun="rootFun" ></childItem> </div> </template> <script> import childItem from "./components/item"; Export default {name: "parent", components: {childItem}, data() {return {currentIndex: 0, MSG: "Root component ", list: [ { id: 1, title: "nanjiu" }, { id: 2, title: "FE" }, { id: 3, title: "boy" } ] }; }, methods: {rootFun() {console.log(" I am the root component's method "); }, update(index) { this.currentIndex = index; }}}; </script> <template> <div class="item"> <subItem V-bind ="$attrs" V-on ="$listeners" /> </div> </template> <script> import subItem from "./subItem.vue"; export default { name: "item", components: { subItem } }; </script> // grandchild component <template> <div class="sub_item"></div> </template> <script> export default {name: "subItem", mounted() { console.log(this.$attrs); // {list: Array(3), MSG: 'root '} console.log(this.$listeners); //{update: ƒ, rootFun: ƒ}}}; </script>Copy the code
Vuex
1. Vuex is introduced
Vuex is a state management mode developed specifically for vue.js applications. It uses centralized storage to manage the state of all components of an application and rules to ensure that the state changes in a predictable way.
Vuex solves the problem of multiple views relying on the same state and behavior from different views needing to change the same state, focusing developers’ efforts on updating data rather than transferring data between components
2. Vuex modules
- State: Used to store data and is the only data source in the store
- Getters: Secondary wrapping based on state data, like computed properties in VUE, often used for filtering data and correlation calculation of multiple data
- Mutations: similar to a function, the only way to change state data and cannot be used to handle asynchronous events
- Actions: Similar to mutation, used to submit mutations to change state rather than directly change state, and can include arbitrary asynchronous operations
- Modules: Similar to a namespace, used in a project to define and manipulate the state of modules separately for easy maintenance
localStorage/sessionStorage
Able to communicate, its drawbacks as well as using localStorage/sessionStorage is not easy to maintain
conclusion
- Parent-child component communication: props;
$parent / $children
; provide / inject ; ref ;$attrs / $listeners
- Sibling communication: eventBus; vuex
- Cross-level communication: eventBus; Vuex; Dojo.provide/inject,
$attrs / $listeners
7. How to understand the one-way data flow of Vue?
In Vue, all prop creates a one-way data flow between their parent prop: updates from the parent prop flow down to the child component, but not vice versa. This prevents accidental changes in the state of the parent component from the child, which can make the data flow of your application difficult to understand.
Additionally, every time the parent component is updated, all prop in the child component will be refreshed to the latest value. This means that you should not change a prop inside a child component. If you do, Vue will issue a warning in the browser console. If a child component wants to modify it, it can only send a custom event through $emit. If the parent component receives the custom event, the parent component can modify it.
8.Com Puted and Watch differences and application scenarios?
The difference between:
Computed: Computed attributes depend on other attribute values, and computed values are cached. Only when the dependent attribute values change, computed values will be recalculated the next time it obtains computed values.
-
Support caching, only the dependent data changes, will be recalculated
-
Asynchronism is not supported. It does not work when there is asynchronous operation in computed, and data changes cannot be monitored
-
Computed attribute values are cached by default, and computed attributes are cached based on their reactive dependencies, that is, values computed from the data declared in data or passed by the parent component
-
If a property is computed by something else, that property depends on something else, it’s a many-to-one or one-to-one, usually computed
-
If the computed attribute value is a function, the default is to use the GET method; The return value of the function is the property value of the property; In computed, attributes have a GET and a set method, which are called when data changes.
Watch: It is more of a function of “observation”, similar to the listening callback of some data. Whenever the monitored data changes, the callback will be executed for subsequent operations.
-
Does not support cache, data change, will directly trigger the corresponding operation;
-
Watch supports asynchrony;
-
The listening function takes two arguments, the first of which is the latest value; The second argument is the value before input;
-
When an attribute changes, you need to perform the corresponding operation. A couple more;
-
The listening data must be the data declared in data or passed by the parent component in props. When the data changes, other operations are triggered.
Different data relation scenarios are processed by Watch and computed respectively:
-
Watch is good at dealing with scenarios where one piece of data affects multiple pieces of data
-
Computed is good at handling scenarios in which multiple data are affected by one data
9. What is the minimum compatibility of Vue2 to IE?
Vue2 is compatible with IE8 and above. IE8 and below do not support the Object.defineProperty method, but it is necessary for vUE to be responsive.
10. Tell me about the lifecycle of Vue. Which hook is used to make requests?
BeforeCreate is called after instance initialization and before data Observer and Event/Watcher event configuration. In the current phase, data and methods on Data, methods, computed, and Watch cannot be accessed
Called after the created instance has been created. In this step, the instance completes the configuration of data Observer, property and method operations, and Watch/Event event callbacks. There is no $EL, so if you really want to interact with the Dom, you can access the Dom via $nextTick
BeforeMount is called before the mount begins: the associated render function is called for the first time.
Mounted Occurs after the Dom is mounted. In this stage, the REAL Dom is mounted, data is bound, and Dom nodes can be accessed
BeforeUpdate is called when data is updated and occurs before the virtual DOM is re-rendered and patched. You can further change the state in this hook without triggering additional rerendering
Updated occurs after the update is complete, and the component Dom is updated in the current phase. Care should be taken to avoid changing the data during this time, as this may result in an infinite loop of updates, and the hook is not called during server-side rendering.
BeforeDestroy Called before instance destruction. At this step, the instance is still fully available. This is where we can clean up the mess, like clearing timers.
Called after the Destroyed Vue instance is destroyed. When called, everything indicated by the Vue instance is unbound, all event listeners are removed, and all subinstances are destroyed. This hook is not called during server-side rendering.
Activated keep-alive Is used when the component is activated
Deactivated keep-alive Is exclusive and is invoked when a component is destroyed
At what stage is the asynchronous request initiated?
Asynchronous requests can be made in hook functions created, beforeMount, and Mounted because data is already created in these hook functions and can be assigned to the data returned by the server.
If an asynchronous request does not need to rely on Dom, it is recommended to call an asynchronous request in a Created hook function, because calling an asynchronous request in a Created hook function has the following advantages:
- The server data can be obtained faster, reducing page loading time.
- SSR does not support beforeMount and Mounted hook functions, so creating helps consistency.
11. Talk about the data response principle of Vue2
Recommended reading
【Vue source code learning 】 responsive principle exploration
【Vue source code learning 】 rely on collection
What is the difference between the data response principle of Vue2 and Vue3
-
The change detection implementation in Vue2 treats Object and Array differently. Objcet uses the Object.defineProperty API, and Array uses an interceptor to intercept methods on the Array prototype that can change data. Although the data change detection is also implemented, there are many limitations, such as new object attributes cannot be detected, and the contents of the array can be modified through the bottom of the array. Therefore, in Vue2, the $set method is often used to modify the data to ensure the dependency on update.
-
Vue3 uses es6 Proxy API for data Proxy, and does not modify the original data like Vue2 does, but adds Proxy wrapper, so performance will be improved at first. Secondly, the limitation of change detection in Vue2 is solved. It can be detected without using the new object attribute of $set and by modifying the array by subscript.
12.Vue parent and child component lifecycle hook function execution sequence?
-
Loading the rendering process
Parent beforeCreate -> Parent created -> parent beforeMount -> child beforeCreate -> child created -> child beforeMount -> Child Mounted -> parent Mounted
-
Child component update process
Parent beforeUpdate -> Child beforeUpdate -> Child updated -> Parent updated
-
Parent component update process
Parent beforeUpdate -> Parent updated
-
Destruction of the process
Parent beforeDestroy -> Child beforeDestroy -> Child destroyed -> Parent destroyed
13. Principle of Vue event binding
Native event bindings are bound to real elements via addEventListener, and component event bindings are implemented via Vue’s custom $on. If you want to use native events on a component, you need to add a. Native modifier, which is equivalent to adding native events to the parent component by treating the child component as a normal HTML tag.
1. Binding of native DOM events, using addEventListener implementation
Vue
In creating the realdom
Called whencreateElm
Is called by defaultinvokeCreateHooks
- Will traverse the current platform relative property handling code, which has
updateDOMListeners
Method is passed in internallyadd
methods
function updateDOMListeners (oldVnode: VNodeWithData, vnode: VNodeWithData) {
if (isUndef(oldVnode.data.on) && isUndef(vnode.data.on)) {
return
}
const on = vnode.data.on || {}
const oldOn = oldVnode.data.on || {}
target = vnode.elm
normalizeEvents(on)
updateListeners(on, oldOn, add, remove, createOnceHandler, vnode.context)
target = undefined
}
function add (
name: string,
handler: Function,
capture: boolean,
passive: boolean
) {
target.addEventListener( // Add events to the current DOM
name,
handler,
supportsPassive
? { capture, passive }
: capture
)
}
Copy the code
2. Component binding events use the $on method
export function updateComponentListeners (
vm: Component,
listeners: Object,
oldListeners: ?Object
) {
target = vm
updateListeners(listeners, oldListeners || {}, add, remove, createOnceHandler, vm)
target = undefined
}
function add (event, fn) {
target.$on(event, fn)
}
Copy the code
14. Can Vue detect changes when assigning an array item directly?
This is not possible because Vue2 essentially hijacks the seven methods on the array prototype, so only by calling one of these seven methods can Vue detect the change.
But we can trigger view updates by calling set or $set
Mounted () {this.list, this.list[0], {id: 1, id: 1}); mounted() {this.list, this.list[0], {id: 1, id: 1}); },Copy the code
The implementation principle of vm.$set is:
- If the target is an array, use the array splice method directly to trigger the corresponding expression.
- If the target is an object, the presence of the attribute and whether the object is reactive are first read. Finally, if the attribute is to be processed responsively, it is processed responsively by calling the defineReactive method (the defineReactive method is when Vue initializes the object, Method called to dynamically add getters and setters to Object properties using Object.defineProperty)
15. Can a data attribute in Vue have the same name as a method in Methods? Why is that?
During the initialization process, vue initializes props(initProps) and then methods(initMethods). If there is a key with the same name as the props, an alarm is generated. Initialize data(initData), and check whether there are properties with the same name as props and methods.
16. Can a parent component listen to the life cycle of a child component?
The answer is yes.
The first one can be used$emit
To implement the
// Parent.vue
<Child @mounted="doSomething"/>
// Child.vue
mounted() {
this.$emit("mounted");
}
Copy the code
The second one can be used@hook
To implement the
// Parent.vue <template> <div class="section"> <childItem @hook:mounted="childMounted" ></childItem> </div> </template> <script> export default {name: "parent", components: {childItem}, mounted() {console.log(" parent component mounted"); }, methods: {childMounted() {console.log(" parent component listen to child component mounted"); }}}; </script> // child.vue mounted() {console.log(" Child component mounted"); }Copy the code
The print sequence is as follows: child component mounted > Parent component Monitors child component mounted > parent component mounted
17. The virtual DOM
What is the virtual DOM?
The virtual DOM is one of many solutions for mapping state into attempts. The nature of page interaction is still changing state (variables) to change the attempt to render, and frameworks (like vue, React, Angular) allow us to focus more on state and leave out DOM manipulation (which the framework already does for us). The way the virtual DOM map view works is to generate a virtual node tree from the state and then render it through the virtual node tree. The virtual DOM is essentially a plain JS object that contains the attributes needed to create a DOM element.
Pros and cons of the virtual DOM
Advantages:
- Lower performance: The framework’s virtual DOM needs to accommodate any operations that the upper-level API may produce, and some of its DOM operations must be implemented in a universal way, so its performance is not optimal; But performance is much better than rough DOM manipulation, so the framework’s virtual DOM can at least guarantee decent performance without having to manually optimize it.
- No need to manually manipulate the DOM: We no longer need to manually manipulate the DOM, just need to write the code logic of the View-Model, the framework will help us update the View in a predictable way according to the virtual DOM and data two-way binding, greatly improving our development efficiency;
- Cross-platform advantages: Because the virtual DOM is based on JavaScript objects and does not depend on the real platform environment, it has cross-platform capabilities, such as browser platform, Weex, Node, etc.
Disadvantages:
- When rendering a large number of DOM for the first time, it is slower than innerHTML insertion due to the extra layer of virtual DOM computation.
18. What is the route hook function of vue-router, and what is the execution sequence?
Vue-router provides navigation guard mainly for navigation guard by jump or cancel. Vue route hook is divided into global guard, route guard and component guard
Execution order
- Navigation is triggered.
- Call the beforeRouteLeave guard in the deactivated component.
- Call the global beforeEach guard.
- Call the beforeRouteUpdate guard (2.2+) in the reused component.
- Call beforeEnter in routing configuration.
- Parse the asynchronous routing component.
- Call beforeRouteEnter in the activated component.
- Call the global beforeResolve guard (2.5+).
- Navigation confirmed.
- Call the global afterEach hook.
- Trigger a DOM update.
- Call the callback passed to Next in the beforeRouteEnter guard, and the created component instance is passed in as an argument to the callback.
19. Say what you understand about slot
Solt occupies a Slot in the component template. When the component label is used, the content in the component label is automatically filled in (replacing the Slot position in the component template) and serves as an outlet for distribution content
Slot can be divided into three categories
The default slot
The child component uses the
tag to determine the location of the render. The DOM structure inside the tag is displayed on the page when the parent component uses it without passing content into the slot
When the parent component is in use, it writes content directly into the child component’s tag
<! -- Parent component --> <Child> <div> Default slot </div> </Child> <! - child components - > < template > < slot > < p > slot backup the content of the < / p > < / slot > < / template >Copy the code
A named slot
The child component uses the name attribute to represent the name of the slot, not the default slot
The slot attribute is added to the default slot attribute in the parent component when used. The value is the slot name attribute value of the child component
<! Parent component --> <child> <template v-slot:default> Named slot </template> <! --> <template v-slot:content> the name of the slot... </template> </child> <! <slot name="nanjiu"> </slot> </template>Copy the code
Scope slot
The child binds properties on the scope to pass information from the child to the parent, and these properties are hung on objects that the parent v-slot accepts
The parent component uses v-slot: (- #) to get information about the child component when used in the content
<! -- Parent component --> <child> <! <template V-slot :default="slotProps"> Data from child components: {{slotProps. TestProps}} /template> <template #default="slotProps"> {{slotProps.testProps}} </template> </child> <! -- Subcomponent --> <template> <slot name="footer" testProps=" value of subcomponent "> <h3>Copy the code
Summary:
-
The V-slot attribute can only be used on
, but can be used on component labels if there is only a default slot
-
The default slot name is default. You can write v-slot directly without default
-
You can’t abbreviate # without writing an argument. Write #default
-
You can get v-slot={MSG} by deconstructing it. You can also rename v-slot=”{MSG: newMsg}” and define default v-slot=”{MSG = ‘default ‘}”.
The principle of slot:
Slot is essentially a function that returns a VNode. Normally, components in a Vue need to go through the Template >> Render Function >> VNode >> DOM process to render onto a page. The essence of component mounting is to perform render functions to get vNodes, and data/props/computed are all data sources for vNodes.
Prior to 2.5, a normal slot would be in the form of a VNode, whereas a scoped slot would require the child to access the child’s data from the parent. So under the parent component is an unexecuted function (slotScope) => return h(‘div’, slotScope.msg), which accepts the slotProps parameter of the child component and is called to pass in data when the child component renders the instance.
After 2.6, the two were merged and the normal slot became a function, but it took no arguments.
20. Talk about how Vue $nextTick works
Vue is executed asynchronously when updating the DOM. As long as it listens for data changes, Vue opens a queue and buffers all data changes that occur in the same event loop. If the same watcher is triggered more than once, it will only be pushed into the queue once. This removal of duplicate data while buffering is important to avoid unnecessary computation and DOM manipulation. Then, in the next event loop, “TICK,” Vue refreshes the queue and performs the actual (de-duplicated) work. Vue internally attempts to use native Promise.then, MutationObserver, and setImmediate for asynchronous queues, and setTimeout(fn, 0) instead if the execution environment does not support it. (I’ll write an article about the source code for nextTick later)
21. Tell me what you understand about functional components
1. You need to specify functional:true in the declaration component
2. No instantiation is required, so there is no this, which is replaced by the second context argument to the render function
3. No lifecycle hook function, can’t use calculated property, watch
4. Events cannot be exposed through $emit. Events can only be called through context.listeners
5. Because functional components are not instantiated, when a component is referenced externally via ref, HTMLElement 6 is actually referenced. Functions components do not need to be declared, so properties that are not declared in props are automatically resolved to prop, while all undeclared properties in normal components are resolved to $attrs and automatically mounted to the component root element.
advantages
-
1. Because functional components do not need to be instantiated, are stateless and have no life cycle, rendering performance is better than normal components
-
2. The functional component structure is relatively simple, and the code structure is clearer
22. What are common Vue performance optimizations?
-
The hierarchy of reactive data objects should not be too deep, and non-reactive data should not be placed in data or frozen using Object.freeze()
-
Use v-if and v-show properly. V-if applies to scenarios with infrequent switching, and v-show applies to scenarios with frequent switching
-
Use scenarios with computed and watch. If you can use computed, you don’t need watch (computed has caching effect)
-
V-for traversals must include a key, preferably an ID value, and avoid v-if
-
Big data list and table performance optimization – virtual list/virtual table
-
To prevent internal leaks, global variables and events should also be destroyed after component destruction
-
Lazy loading of images
-
Route lazy loading
-
The introduction of third-party plug-ins on demand
-
Use the keep-alive cache component as appropriate
-
Anti – shake, throttling application
-
Server render SSR or prerender
23. Application scenarios and principles of Vue.mixin
Mixins provide a very flexible way to distribute reusable functionality in Vue components. Mixin objects can contain any component option. When a component uses a mixin object, all mixin options are mixed with the component’s own options. Mixin can also be registered globally. Use with extreme care! Once global mixin is used, it affects every subsequent Vue instance created.
// mixin.js
export default {
data() {
return {
title: 'I'm the title in the mixin'}}},Copy the code
<template> <div class="section"> </div> </template> <script> import mixin from "./mixin"; Export default {name: "parent", mixins: [mixin], data() {return {currentIndex: 0, MSG: "root component ",}; }, created() { console.log(this.$data); Console. log(" I am created in the root component "); }, </script>Copy the code
First print out that I am created in the mixin, then print out the merged data (including the data in the root component and the data in the mixin), then print out that I am created in the root component
Usage Scenarios:
In daily development, we often encounter the need to use some same or similar codes in different components. At this time, the functions of these codes are relatively independent. The same or similar codes can be put forward through the mixin function of Vue.
Principle:
The main principle is the merOptions method
export function mergeOptions (
parent: Object,
child: Object, vm? : Component) :Object {
if (child.mixins) { // Check if there are mixins and then recursively merge
for (let i = 0, l = child.mixins.length; i < l; i++) {
parent = mergeOptions(parent, child.mixins[i], vm)
}
}
const options = {}
let key
for (key in parent) {
mergeField(key) // Iterate over the parent's key
}
for (key in child) {
if(! hasOwn(parent, key)) {// If the parent has already handled a key, it does not
mergeField(key) // Handle child keys that are not handled by parent keys}}function mergeField (key) {
const strat = strats[key] || defaultStrat
options[key] = strat(parent[key], child[key], vm, key) // Call different strats methods based on different types of options to merge
}
return options
}
Copy the code
The mixins are first recursively processed, first traversing the merged parent key, then calling mergeField method to merge, and then saving it in the variable options, then traversing the child, merging and adding the keys not found in the parent, and calling mergeField method to merge. Save in the variable options.
24. The function and principle of vue.extend
Using the base Vue constructor, create a “subclass.” The parameter is an object that contains component options.
The data option is a special case, note – it must be a function in vue.extend (), which returns a constructor with the same functionality as Vue (actually creating a component) – the property options is an object that combines the arguments of the base Vue constructor with extend,
Principle:
Extend is to create a VueComponent constructor named Sub, and inherit all attributes and methods of the Vue constructor prototype by pointing VueComponent’s prototype to the Vue constructor prototype. Then check if the passed extendOptions has props and computed properties, and initialize them if so. If the name attribute is detected in the passed extendOptions, it is automatically put into VueComponent’s global component. Then the Vue. Save the options to VueComponent. SuperOptions attributes, to save incoming extendOptions to VueComponent. The extendOptions properties, And storing incoming extendOptions a save to VueComponent. SealedOptions. Finally, VueComponent is returned, which is the constructor of the Vue component that inherits the Vue constructor. (More on this later)
Differences from mixins:
-
A mixin is a mixin of Vue class options. All Vue instance objects will have the configuration behavior blended in.
-
Extend extends a subclass that extends from the Vue class and affects only the instance objects of that subclass, not the Vue class itself or the instance objects of the Vue class.
25. Since VUE can accurately detect data changes through data hijacking, why do we need diff to detect differences?
Currently, the front-end framework has two methods of data change detection, one is pull, the other is push.
-
React is represented by Pull, which displays updated data after setState operation. React will use diff algorithm to find differences layer by layer, and then patch to the DOM tree. React didn’t know that there was a change at the beginning, but only knew that there was a change. Then violence looks for that change, and another proxy is Angular’s dirty check.
-
Vue’s responsive system is the representative of Push. When Vue initializations, it will collect the data of data by dependency, so Vue can know in real time that there is a change. Generally, the fine granularity of binding is too high, which will generate a large number of Watcher instances, resulting in excessive memory and dependency tracking overhead. The granularity is too low to detect change. Therefore, Vue adopts a medium fine-grained scheme, only for component-level responsive listening, also known as push, so that you can know which component has changed, and then perform diff algorithm on the component to find the specific location of the change. This is a pull operation, and Vue is a combination of pull and push for change detection.
Recommended reading
- Common front-end sorting algorithms
- Common front-end security problems and preventive measures
- Why are big factories using GIF as a burying point?
- Don’t just know about KFC, you should know about BFC, IFC, GFC and FFC
- What is the difference between Promise, Generator, and Async?
- In 2022, don’t you know the difference between an arrow function and a normal function?
- From how to use to how to implement a Promise
- Explains the page loading process in great detail
The original address point here, welcome everyone to pay attention to the public number “front-end South Jiu”, if you want to enter the front-end exchange group to learn together, please click here
I’m Nan Jiu, and we’ll see you next time!!