(共566篇)
全部分类

vue3中app.config.optionMergeStrategies用法及作用
[ Vue(2+3) ] 

作用

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的值发生变化时, 要采取它的新值作为最终值

  1. 解析mixin的内容时, msg 的旧值为 undefined, 新值为 mixin, 所以最终值为 mixin
  2. 解析组件本身时, msg的旧值为 mixin, 新值为 self, 所以最终值为 self
  3. 输出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的最终值时, 都要采用老值作为最终值

  1. 解析mixin的内容时, msg 的旧值为 undefined, 新值为 mixin, 所以最终值为 undefined
  2. 解析组件本身时, msg的旧值为 undefined, 新值为 self, 所以最终值为 undefined
  3. 输出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.

看一下它的合并过程:

  1. 解析mixin的内容时, msg 的旧值为 undefined, 新值为 mixin, 所以最终值为 ‘undefined,mixin’
  2. 解析组件本身时, msg的旧值为 ‘undefined,mixin’, 新值为 ‘self’, 所以最终值为 ‘undefined,mixin,self’
  3. 输出msg时, 它的最终值就是 ‘undefined,mixin,self’