Hello, here is Linkπ€©, from today, I intend to write a Vue source analysis of a series of articles, but please rest assured, absolutely not a simple dry source, we start from some interview questions, scenarios, each of our articles only to focus on the Vue implementation of some functions, and solve some interview often asked questions. Then understand the implementation. You don’t have to face the tedious source code directly.πͺπͺ
Later, we’ll talk about how Vue uses a Watcher to perform core functions such as component instantiation, calculation properties, and listening properties, and you’ll understand that many of the subtlety of Vue’s design, such as the most well-known responsive system, will be very fruitful π
Flow chart of Vue instantiation
This is a flow chart note about Vue written by myself, which can be very intuitive and convenient to understand the whole instantiation. And this map has been put in my Vue source project VUE-core-analyse, and the project source has my personal read source remarks, I believe you will also have some help π, welcome to starβ¨
This diagram covers the entire Vue instance data and component instantiation process
- This flowchart is a vscode plug-in
Draw.io Integration
Provided, you need to download this plug-in to enable
scenario
Why is it possible to access values in the data function directly in the form of this.message?
<script src=".. /.. /dist/vue.js"></script>
<script>
var vm = new Vue({
el: '#el',
data () {
return {
message: "Hello Vue"}},mounted() {
const message = this.message
}
})
</script>
Copy the code
It seems to us that mouted and data are two different scopes, and it only makes sense that we should first access the common scope and then access the data object π€, like this
mounted() {
const message = this.data.message
}
Copy the code
The principle of
In fact, the processing is fairly easy to understand, so let’s take a look at Vue’s processing of the data property from an entry point
The _init function is mounted by initMixin(Vue) when the entire Vue project is initialized. When we new Vue({}), we will execute the following function, options, which is the big object we passed to the Vue constructor in the demo above. Data, Mounted, and other configurations are configured
// src/core/instance/index.js
function Vue (options) {
if(process.env.NODE_ENV ! = ='production' &&
// request new execution! (this instanceof Vue)
) {
warn('Vue is a constructor and should be called with the `new` keyword')}this._init(options) / / π
}
Copy the code
- One is executed in the last line of Vue
this._init(options)
A function is a Vue that triggers a set of behaviors when instantiated
Here I’m cutting the source code, and we’re just going to focus on initialization of the data part. Such an _init function does several things
-
Define a VM equal to the current instance
-
Initially mount $options and merge configuration options
$options = vm.$options = options
-
Execute initState(VM) to initialize all states
Step 3 is the one we need to focus on most. This function initializes properties such as props, Methods and data in configuration items
// src/core/intance/init.js
Vue.prototype._init = function (options? :Object) {
const vm: Component = this
// a flag to avoid this being observed
vm._isVue = true
// merge options
vm.$options = mergeOptions(
resolveConstructorOptions(vm.constructor),
options || {},
vm
)
// expose real self
vm._self = vm
// Initialization state
initState(vm)
}
Copy the code
- This function right here is oursThe ultimate goal
initData(vm)
This is where we start our data
// src/core/intance/state.js
// Initialization state
export function initState (vm: Component) {
const opts = vm.$options
// Initialize based on the properties that exist in our options
if (opts.data) {
// Initialize the data
initData(vm)
}
}
Copy the code
InitData function
They will judge us firstdata
Is it a function? If so, execute it and return an object. If not, use it directly.- The while loop first applies to our
data
withpros
andmethod
Do a double name-check. The logic here is very simple. We don’t have to care - Assign a copy of this object to
data
εvm._data
- Then call proxy(VM, _data, key)
// src\core\instance\state.js
function initData (vm: Component) {
let data = vm.$options.data
data = vm._data = typeof data === 'function'
? getData(data, vm)
: data || {}
const keys = Object.keys(data)
const props = vm.$options.props
const methods = vm.$options.methods
let i = keys.length
while (i--) {
const key = keys[i]
/** * compare the key in data with the props and method */
if(process.env.NODE_ENV ! = ='production') {
/ /..
}
if (props && hasOwn(props, key)) {
/ /...
} else if(! isReserved(key)) {/ / agent
proxy(vm, `_data`, key) / / π}}}Copy the code
The focus is on proxy(VM,_data
, key)
- The proxy function starts with
sharedPropertyDefinition
The object defines oneget
andset
methods - Use defineProperty to intercept vm objects
This means that when we access data from the VM, which we usually use as this.message, this._data.message will be forwarded to us via a defineProperty interception (same with assignment).
// \src\core\instance\state.js
export function proxy (target: Object, sourceKey: string, key: string) {
sharedPropertyDefinition.get = function proxyGetter () {
return this[sourceKey][key]
}
sharedPropertyDefinition.set = function proxySetter (val) {
this[sourceKey][key] = val
}
/** * How can I get the value of data from other attributes by calling this.message? * The answer is right here, When vue initializes data, it uses this proxy function * to monitor the key value in data directly on the VM instance, and then monitors it based on the object above * /
Object.defineProperty(target, key, sharedPropertyDefinition)
}
Copy the code
Flow chart presentation
new Vue({
el: '#app'.data: {msg: 'parent-Vue'
},
mounted () {
console.log(this.msg);
console.log(this._data.msg); // This way of accessing data is certainly not recommended}})Copy the code
Thank π
If you find the content helpful:
- β€οΈ welcome to focus on praise oh! I will do my best to produce high-quality articles
Contact author: Linkcyd π Previous:
- Interview often test 6 big sorting algorithm principle, read that understand!
- That’s all you need to know about regular expressions
- React Get started with 6 brain maps
- Interviewer: Come on, hand write a promise
- Prototype and Prototype Chain: How to implement Call, Bind, New yourself?