作用
app.config.optionMergeStrategies
用来控制vue实例自身的API属性
在与mixin合并时的行为
首先API属性
指的是像created
,mounted
,setup
等属性, app.config.optionMergeStrategies
是用来控制与他们同级别的, 自定义的属性, 在与来自mixin
中的属性 如何合并的行为, 所有的API属性
在与mixin
合并时都有其自身的合并规则, 他们是由vue
定义的
看一个例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
import { createApp, h } from "vue";
const app = createApp({
render() {
return h("div", "title");
},
msg: "self",
mounted() {
console.log(this.$options.msg);
},
});
app.config.optionMergeStrategies.msg = function (o, n, vm) {
// o 表示msg的旧值
// n 表示msg的新值
console.log(o, n, vm);
return n;
};
app.mixin({
msg: "mixin",
});
app.mount("#app");
|
看一下这段代码的输出值:
1
2
3
4
5
|
[vite] connecting...
undefined 'mixin' undefined
mixin self undefined
self
connected.
|
在vue的源码中有这么一段:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
function resolveMergedOptions(instance) {
const base = instance.type;
const { mixins, extends: extendsOptions } = base;
const { mixins: globalMixins, optionsCache: cache, config: { optionMergeStrategies } } = instance.appContext;
const cached = cache.get(base);
let resolved;
if (cached) {
resolved = cached;
}
else if (!globalMixins.length && !mixins && !extendsOptions) {
{
resolved = base;
}
}
else {
resolved = {};
// 注意这一段
if (globalMixins.length) {
globalMixins.forEach(m => mergeOptions(resolved, m, optionMergeStrategies, true));
}
mergeOptions(resolved, base, optionMergeStrategies);
}
cache.set(base, resolved);
return resolved;
}
|
从我标记注释的地方可以看到, vue在合并api属性
的时候, 会优先读取mixin的内容, 再读取自身的内容,
所以我们前面的案例中, 通过app.config.optionMergeStrategies.msg
定义了: 每次msg的值发生变化时, 要采取它的新值作为最终值
- 解析mixin的内容时, msg 的旧值为 undefined, 新值为 mixin, 所以最终值为 mixin
- 解析组件本身时, msg的旧值为 mixin, 新值为 self, 所以最终值为 self
- 输出msg时, 它的最终值就是 self
现在我们来换一下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
import { createApp, h } from "vue";
const app = createApp({
render() {
return h("div", "title");
},
msg: "self",
mounted() {
console.log(this.$options.msg);
},
});
app.config.optionMergeStrategies.msg = function (o, n, vm) {
console.log(o, n, vm);
// 注意, 只要这一句不同了,
return o;
};
app.mixin({
msg: "mixin",
});
app.mount("#app");
|
输出结果:
1
2
3
4
5
|
[vite] connecting...
undefined 'mixin' undefined
undefined 'self' undefined
undefined
client.ts:53 [vite] connected.
|
这个案例中, 我们定义了在确定msg的最终值时, 都要采用老值作为最终值
- 解析mixin的内容时, msg 的旧值为 undefined, 新值为 mixin, 所以最终值为 undefined
- 解析组件本身时, msg的旧值为 undefined, 新值为 self, 所以最终值为 undefined
- 输出msg时, 它的最终值就是 undefined
再修改一次来验证一下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
import { createApp, h } from "vue";
const app = createApp({
render() {
return h("div", "title");
},
msg: "self",
mounted() {
console.log(this.$options.msg);
},
});
app.config.optionMergeStrategies.msg = function (o, n, vm) {
console.log(o, n, vm);
return o + "," + n;
};
app.mixin({
msg: "mixin",
});
app.mount("#app");
|
输出结果:
1
2
3
4
5
|
[vite] connecting...
undefined 'mixin' undefined
undefined,mixin self undefined
undefined,mixin,self
client.ts:53 [vite] connected.
|
看一下它的合并过程:
- 解析mixin的内容时, msg 的旧值为 undefined, 新值为 mixin, 所以最终值为 ‘undefined,mixin’
- 解析组件本身时, msg的旧值为 ‘undefined,mixin’, 新值为 ‘self’, 所以最终值为 ‘undefined,mixin,self’
- 输出msg时, 它的最终值就是 ‘undefined,mixin,self’