先说下上一篇留下的问题
if (child.mixins) {
for (let i = 0, l = child.mixins.length; i < l; i++) {
let mixin = child.mixins[i]
if (mixin.prototype instanceof Vue) { // 这个if暂时不明白功能作用,一般的用法都不会走这里
mixin = mixin.options
}
parent = mergeOptions(parent, mixin, vm)
}
}
// 这段代码就是把传入的每一项mixins遍历,然后执行mergeOptions合并,mixin只能是数组的形式,所以,
// 这里就是对mixin的一个递归调用,知道后面没有mixin这一字段为止,比如下面这种情况
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id="app">
<p style="color: blue">{{msg}}</p>
</div>
</body>
<script type="text/javascript" src="vue.js"></script>
<script>
var mixinDataOne_child_child = {
data () {
return {
msg: 'hello world from mixin one child child',
name: 'name from mixin one child child'
}
},
created () {
console.log('created from mixin one child child')
}
}
var mixinDataOne_child = {
data () {
return {
msg: 'hello world from mixin one child',
name: 'name from mixin one child'
}
},
created () {
console.log('created from mixin one child')
},
mixins: [mixinDataOne_child_child]
}
var mixinDataOne = {
data () {
return {
msg: 'hello world from mixin one',
name: 'name from mixin one'
}
},
created () {
console.log('created from mixin one')
},
mixins: [mixinDataOne_child]
}
var options = {
el: '#app',
data () {
return {
msg: 'hello world'
}
},
created () {
console.log('created from root')
},
mixins: [mixinDataOne]
}
var myVue = new Vue(options)
console.log(myVue.msg)
console.log(myVue.name)
</script>
</html>
// 这里就是不断对有mixin的字段进行合并,关键在于对于data,created还有其他的属性等等的合并方法,
// 不同的字段属性用不同的方法,这个才是Vue合并策略的重点,也就是这一段
const options = {}
let key
for (key in parent) {
mergeField(key)
}
for (key in child) {
if (!hasOwn(parent, key)) {
mergeField(key)
}
}
function mergeField (key) {
const strat = strats[key] || defaultStrat
options[key] = strat(parent[key], child[key], vm, key)
}
// 而重点在于先前说过的strat对象,如下
strats = {
el: function (parent, child, vm, key) {
return defaultStrat(parent, child)
},
propsData: function (parent, child, vm, key) {
return defaultStrat(parent, child)
},
data: function (parentVal: any,childVal: any,vm?: Component) {
do something...
},
beforeCreate: function mergeHook () {
do something...
},
created: function mergeHook () {
do something...
},
beforeMount: function mergeHook () {
do something...
},
mounted: function mergeHook () {
do something...
},
beforeUpdate: function mergeHook () {
do something...
},
updated: function mergeHook () {
do something...
},
beforeDestroy: function mergeHook () {
do something...
},
destroyed: function mergeHook () {
do something...
},
activated: function mergeHook () {
do something...
},
deactivated: function mergeHook () {
do something...
},
components: function mergeAssets () { // 这里加上个s复数
do something...
},
directives: function mergeAssets () { // 这里加上个s复数
do something...
},
filters: function mergeAssets () { // 这里加上个s复数
do something...
},
watch: function (parentVal: ?Object, childVal: ?Object) {
do something...
},
props: function (parentVal: ?Object, childVal: ?Object) {
do something...
},
methods: function (parentVal: ?Object, childVal: ?Object) {
do something...
},
computed: function (parentVal: ?Object, childVal: ?Object) {
do something...
}
}
下一篇则重点学习这个,在这先把之前留下的一个问题解决
- initMixin(Vue)
src\core\global-api\mixin.js
export function initMixin (Vue: GlobalAPI) {
Vue.mixin = function (mixin: Object) {
this.options = mergeOptions(this.options, mixin)
}
}
// 这个this.options便是之前说过的Vue.options
Vue.options = {
components: {
KeepAlive,
Transition,
TransitionGroup
},
directives: {
model,
show
},
filters: {},
_base: Vue
}
// 比如下面这个例子
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id="app">
<p style="color: blue">{{msg}}</p>
</div>
</body>
<script type="text/javascript" src="vue.js"></script>
<script>
var mixinGlobal_child = {
data () {
return {
msg: 'hello world from mixin global child',
name: 'name from mixin global child'
}
},
created () {
console.log('created from mixin global child')
}
}
Vue.mixin({
created () {
console.log('created from global Vue mixin')
},
mixins: [mixinGlobal_child]
})
var options = {
el: '#app',
data () {
return {
msg: 'hello world'
}
},
created () {
console.log('created from root')
}
}
var myVue = new Vue(options)
</script>
</html>
// 这里和上面一样,还是合并所有的mixin字段,直到没有为止,但是这里有个疑问
// 全局混合的属性在所有的组件里面都有的,但是这里没有看到Vue用什么方法区分的!!!
<p style="font-weight: bold;margin-bottom: 10px;color: #FF0000">剩下的几个问题</p>
Vue.set = set // 涉及到Vue的数据响应式系统,先保留
Vue.delete = del // 涉及到Vue的数据响应式系统,先保留
Vue.nextTick = util.nextTick // 水平有限,看不懂 - -#
initExtend(Vue) // 水平有限,看不懂 - -#
extend(Vue.options.directives, platformDirectives) // 水平有限,看不懂 - -#
extend(Vue.options.components, platformComponents) // 水平有限,看不懂 - -#
Vue.prototype.__patch__ // 水平有限,看不懂 - -#
compileToFunctions // 水平有限,看不懂 - -#
const extendsFrom = child.extends // 水平有限,看不懂 - -#