Vue bidirectional binding principle
Vue. js adopts data hijacking combined with publiser-subscriber mode. It hijacks the setter and getter of each attribute through Object.defineProperty() to publish messages to subscribers when data changes and trigger corresponding listening callback.
The data was hijacked
Traversing the data property hijacks the setter and getter via Object.defineProprety
Vue relies on the collection process
- When new wacther, pushTarget is used to change the dep. target to Wacther, and the getter is triggered during render Vnode
function pushTarget (_target: ? Watcher) {
if (Dep.target) targetStack.push(Dep.target)
Dep.target = _target
}
updateComponent = () = > {
vm._update(vm._render(), hydrating)
}
new Watcher(vm, updateComponent, noop, {
before () {
if (vm._isMounted) {
callHook(vm, 'beforeUpdate')}}},true /* isRenderWatcher */)
Copy the code
- The getter triggers dep.depend() which executes dep.target.adddep (this), which executes the addDep method in Wacther
/ / Dep
depend () {
if (Dep.target) { // dep. target = "watcher"
Dep.target.addDep(this) // this =》dep}}Copy the code
- Dep is used as a parameter in addDep. Map has is used to determine whether the ID of the DEP already exists. If not, it is pushed to the stack (filter duplicate DEPs).
- Wacther is collected by executing the addSub method of the DEP just passed in
/ / Watcher
addDep (dep: Dep) {
const id = dep.id
if (!this.newDepIds.has(id)) {
this.newDepIds.add(id)
this.newDeps.push(dep)
if (!this.depIds.has(id)) { // Prevent duplicate collection of DEPs
dep.addSub(this) // deP collects watcher}}}Copy the code
The difference between Watch and COMPUTD
- Computd is cached after the getter executes
- Computd is suitable for performance-intensive computing scenarios
- Watch is more of a listener, listening for a change and performing a callback
Function of Vue key
Key is the unique ID given to each Vnode. You can rely on the key to get the corresponding VNode in oldVnode more accurately and faster.
- A more accurate
Because there is no local reuse with key, local reuse can be avoided in sameNode function A. key === B. key comparison. So it’s more accurate.
- faster
The uniqueness of key is used to generate map objects to obtain corresponding nodes, which is faster than traversal
When there is no key or index as the key: for example, there may be no transition effect, or some nodes have bound data (form) state, and the state will be misaligned
Vue nextTick principle
-
It performs a callback after the DOM is updated, allowing us to manipulate the updated DOM
-
The ability to listen for DOM changes is a mutationObserver of the new H5 feature, but Vue is not implemented by listening for DOM changes
-
Instead, it uses the eventloop principle, because an eventloop task performs a DOM update after executing (completing an eventloop)
-
The cutoff point for completing a task is microtask completion, so Vue first uses promise. Then and then mutationObserver.
-
For compatibility then demote to the macro tasks setImmediate and setTimeout
// timerFunc collects asynchronous task events
function flushCallbacks () {
pending = false
const copies = callbacks.slice(0)
callbacks.length = 0
for (let i = 0; i < copies.length; i++) {
copies[i]()
}
}
let timerFunc
if (typeof Promise! = ='undefined' && isNative(Promise)) {
const p = Promise.resolve()
timerFunc = () = > {
p.then(flushCallbacks)
if (isIOS) setTimeout(noop)
}
isUsingMicroTask = true
} else if(! isIE &&typeofMutationObserver ! = ='undefined' && (
isNative(MutationObserver) ||
MutationObserver.toString() === '[object MutationObserverConstructor]'
)) {
let counter = 1
const observer = new MutationObserver(flushCallbacks)
const textNode = document.createTextNode(String(counter))
observer.observe(textNode, {
characterData: true
})
timerFunc = () = > {
counter = (counter + 1) % 2
textNode.data = String(counter)
}
isUsingMicroTask = true
} else if (typeofsetImmediate ! = ='undefined' && isNative(setImmediate)) {
timerFunc = () = > {
setImmediate(flushCallbacks)
}
} else {
timerFunc = () = > {
setTimeout(flushCallbacks, 0)}}// Collect callback functions with callbacks
export function nextTick (cb? :Function, ctx? :Object) {
let _resolve
callbacks.push(() = > {
if (cb) {
try {
cb.call(ctx)
} catch (e) {
handleError(e, ctx, 'nextTick')}}else if (_resolve) {
_resolve(ctx)
}
})
if(! pending) { pending =true
timerFunc()
}
// $flow-disable-line
if(! cb &&typeof Promise! = ='undefined') {
return new Promise(resolve= > {
_resolve = resolve
})
}
}
Copy the code
Diff Algorithm Flow (Patch)
CreateElm generates the real DOM for the first time. Then sameVnode is used to identify the same node and patchVNode child is used. If both the old node and the new node exist, updateChildren is used. If the old and new heads, tail and tail, and cross-samevNode pairs fail to be compared, key will be directly used to search the mapping table. If the same key node is found, sameVnode comparison will be performed. If the same key node is found, patchVNode of sub-node will be entered until the traversal is completed.
The new vue () process
What are the features of Vuex
First, Vuex is a state management mode developed specifically for Vue 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 core concepts focus on synchronous asynchronous implementation of Action mutation
Why can’t a Vue component data be an object
A Vue component can have multiple instances, and if you define data as an object, they share a single data object, and state changes affect all component instances.
The understanding of the MVVM
Realize model and View active data response and view update by way of instruction
What performance optimizations Vue has
-
Route lazy loading
-
Keep-alive cache page
-
Reuse dom with V-show
-
Long lists of pure data displays are frozen with Object.freeze
-
Long lists of big data with virtual scrolling
-
Timely event destruction
-
Server rendering SSR
Server side rendering principles
When the client requests the server, the server obtains the relevant data from the database, and renders the Vue components into HTML inside the server, and returns the data and HTML to the client. This process of converting data and components into HTML on the server is called the server side rendering SSR
Benefits of using SSR
- Is conducive to SEO
In fact, it is beneficial for crawlers to climb your page, because some page crawlers do not support JavaScript execution, and the non-SSR page captured by crawlers that do not support JavaScript execution will be an empty HTML page, and with SSR, these crawlers can obtain complete HTML structure data. Then included in the search engine.
- The white screen time is shorter
In contrast to client-side rendering, server-side rendering already gets an HTML text with data after the browser requests the URL. The browser simply parses the HTML and builds the DOM tree directly. The client rendering needs to get an empty HTML page first, at which time the page has entered a white screen. After that, it needs to load and execute JavaScript, request the back-end server to obtain data, and render the page with JavaScript before the final page can be seen. Especially in complex applications, JavaScript scripts need to be loaded. The more complex the application is, the more and larger the JavaScript scripts need to be loaded. As a result, the first screen of the application takes a long time to load, which reduces the experience.
What’s new with Vue3
- Data hijacking: Use a proxy as a proxy
- Virtual DOM reconstruction: V2 transforms static nodes into VDOM, and only constructs the VDOM of dynamic nodes
- Tree-shaking is friendlier by moving most global apis and internal components to the ES module export
- Support the ts
- Composition API: New setup functions for code reuse (instead of mixins, which are prone to naming conflicts)
Vue2 reactive malpractice
The reactive process requires recursive traversal, which consumes a lot of energy. Adding or deleting attributes cannot listen to arrays. The reactive process requires additional implementation, such as Map, Set, and Class
Life cycle 2. mapping between X and Composition
-
beforeCreate -> use setup()
-
created -> use setup()
-
beforeMount -> onBeforeMount
-
mounted -> onMounted
-
beforeUpdate -> onBeforeUpdate
-
updated -> onUpdated
-
beforeDestroy -> onBeforeUnmount
-
destroyed -> onUnmounted
-
errorCaptured -> onErrorCaptured
Vue component communication
-
Props ★★ (Father to son)
-
Emit /emit/emit/ ON ★★ Event Bus (cross level communication)
-
Vuex ★★★ (common status management) Advantages: All pages can be accessed by storing data at one time
-
Parent/parent/parent/children (parent = (not recommended) disadvantages: not across levels
-
Attrs/attrs/attrs/listeners (are available if you don’t understand it is not recommended, and the interviewer said this one)
-
Provide /inject★★★ (Advanced usage = Recommended) Advantages: Easy to use Disadvantages: Not responsive
v-model vs .sync
The difference between:
A component can have multiple properties with the.sync modifier, which can “bidirectionally bind multiple” prop “at the same time, unlike the V-Model, which has only one for each component
Usage Scenarios:
V-model is more about the final operation result, which is the result of bidirectional binding. It is value, which is a change operation
Sync is more about a variety of states. It’s about exchanging states, it’s about status, it’s about update
The V-model can be used in scenarios where only the child component updates the parent component as follows:
<CreativityGroup: plantemplatemodel. sync="planParams"/> true }) formModleChange(nVal) { this.$emit('input', nVal) }Copy the code
Examples of v-model vs. sync usage
<template>
<div>
my myParam {{ value }}<br />
paramsync {{ paramsync }}
<button type="button" @click="change">change my</button>
</div>
</template>
<script>
export default {
props: {
value: {
type: String,
default: ""
},
paramsync: {
type: Number,
default: 0
}
},
computed: {
value1: {
set(val) {
this.$emit("input", val);
},
get() {
return this.value;
}
}
},
methods: {
change() {
this.value1 = "rtrtr";
console.log("this.value", this.value);
// this.paramsync = 78;
// this.$emit('input','更新之后')
this.$emit("update:paramsync",5555);
}
}
};
</script>
Copy the code
Vue life cycle
-
BeforeCreate: after the instance is initialized, it is called before the Data Observe and Event/Watcher events are configured. In this case, data such as data and props cannot be accessed.
-
Created: Called immediately after the instance is created, when the instance has completed data observer, property and method operations, watch/ Event callback, mount phase has not started, and $EL is not available.
-
Beforemount: Called before the mount begins, the associated render function is called for the first time.
-
Mounted: When mounted is called, vm. El is replaced by the newly created vm. When Mounted is called, vm. El is also in the document. Note Mounted does not ensure that all child components are mounted together.
-
Beforeupdata: called when data is updated, occurs before the virtual DOM is patched. In this case, it is appropriate to access the existing DOM before the update, for example, manually remove the added event listener.
-
Updated: This hook is called after the virtual DOM is re-rendered and patched due to data changes. When this hook is called, the component DOM is updated to perform DOM-dependent operations. In most cases, the status should change during this time. If you need to change it, it is best to use Watcher or calculated properties instead. Note that the updated does not guarantee that all child components can be redrawn together.
-
Beforedestory: called before instance destruction. At this point, the instance is still available.
-
Destroyed: Called after the instance is destroyed. All instructions for the Vue instance are unbound, all event listeners are removed, and all subinstances are destroyed.
Vue the compile process
The compilation process as a whole is divided into parsing, optimization and generation
Resolution – the parse
Parsers parse templates into abstract syntax trees that can be optimized or code generated based on the AST
Optimization – optimize
The optimizer’s job is to find and label static subtrees in the AST. Static subtrees are nodes that never change in the AST, such as plain text nodes. The benefit of marking static subtrees: The static subtree can be skipped every time you re-render and do not need to create a patch in the virtual DOM for a new node for the static subtree
Code generation – generate
Convert the AST into the content of the rendering function, which is the code string.
Vue2 vs Vue3
Disadvantages of Vue2 responsiveness: The reactive process requires recursive traversal, which costs a lot. New or deleted attributes cannot listen to arrays. Responsiveness requires additional implementation of Map, Set, and Class
Vite principle
To be updated