面试题:Vue 中 mixin 和 extends 的覆盖逻辑是什么?

在 Vue 中,mixinextends 是两种用于复用组件选项的机制。它们的覆盖逻辑有一定的规则,以下是详细的说明:


1. mixin 的覆盖逻辑

mixin 是一种将组件选项混入到目标组件中的方式。当多个 mixin 或组件本身定义了相同的选项时,Vue 会按照以下规则进行合并:

(1)数据对象(data

  • 如果 mixin 和组件都定义了 data,Vue 会递归合并 data 对象。
  • 如果 data 中的属性冲突,组件中的属性优先级高于 mixin

示例

const mixin = {
  data() {
    return {
      message: 'Hello from mixin',
      count: 1,
    };
  },
};

export default {
  mixins: [mixin],
  data() {
    return {
      message: 'Hello from component',
      name: 'Vue',
    };
  },
};
  • 合并后的 data
  {
    message: 'Hello from component', // 组件优先级高
    count: 1, // 来自 mixin
    name: 'Vue', // 来自组件
  }

(2)生命周期钩子

  • 如果 mixin 和组件都定义了相同的生命周期钩子(如 mounted),这些钩子会被合并成一个数组,并按以下顺序执行:
  1. mixin 的钩子。
  2. 组件的钩子。

示例

const mixin = {
  mounted() {
    console.log('mixin mounted');
  },
};

export default {
  mixins: [mixin],
  mounted() {
    console.log('component mounted');
  },
};
  • 输出:
  mixin mounted
  component mounted

(3)方法、计算属性和侦听器

  • 如果 mixin 和组件定义了同名的方法、计算属性或侦听器,组件的选项会覆盖 mixin 的选项

示例

const mixin = {
  methods: {
    greet() {
      console.log('Hello from mixin');
    },
  },
};

export default {
  mixins: [mixin],
  methods: {
    greet() {
      console.log('Hello from component');
    },
  },
};
  • 调用 greet 方法时,输出:
  Hello from component

2. extends 的覆盖逻辑

extends 是一种基于另一个组件扩展新组件的方式。它的覆盖逻辑与 mixin 类似,但优先级不同:

(1)数据对象(data

  • 如果 extends 的组件和目标组件都定义了 data,Vue 会递归合并 data 对象。
  • 如果 data 中的属性冲突,目标组件中的属性优先级高于 extends 的组件

示例

const baseComponent = {
  data() {
    return {
      message: 'Hello from base',
      count: 1,
    };
  },
};

export default {
  extends: baseComponent,
  data() {
    return {
      message: 'Hello from child',
      name: 'Vue',
    };
  },
};
  • 合并后的 data
  {
    message: 'Hello from child', // 目标组件优先级高
    count: 1, // 来自 baseComponent
    name: 'Vue', // 来自目标组件
  }

(2)生命周期钩子

  • 如果 extends 的组件和目标组件都定义了相同的生命周期钩子,这些钩子会被合并成一个数组,并按以下顺序执行:
  1. extends 的组件的钩子。
  2. 目标组件的钩子。

示例

const baseComponent = {
  mounted() {
    console.log('base mounted');
  },
};

export default {
  extends: baseComponent,
  mounted() {
    console.log('child mounted');
  },
};
  • 输出:
  base mounted
  child mounted

(3)方法、计算属性和侦听器

  • 如果 extends 的组件和目标组件定义了同名的方法、计算属性或侦听器,目标组件的选项会覆盖 extends 的组件的选项

示例

const baseComponent = {
  methods: {
    greet() {
      console.log('Hello from base');
    },
  },
};

export default {
  extends: baseComponent,
  methods: {
    greet() {
      console.log('Hello from child');
    },
  },
};
  • 调用 greet 方法时,输出:
  Hello from child

3. mixinextends 的优先级

mixinextends 同时存在时,Vue 会按照以下优先级进行合并:

  1. extends 的组件
  2. mixin
  3. 目标组件

示例

const baseComponent = {
  data() {
    return {
      message: 'Hello from base',
    };
  },
};

const mixin = {
  data() {
    return {
      message: 'Hello from mixin',
    };
  },
};

export default {
  extends: baseComponent,
  mixins: [mixin],
  data() {
    return {
      message: 'Hello from child',
    };
  },
};
  • 合并后的 data
  {
    message: 'Hello from child', // 目标组件优先级最高
  }

总结

选项mixin 覆盖逻辑extends 覆盖逻辑
数据对象(data组件优先级高于 mixin目标组件优先级高于 extends 的组件
生命周期钩子mixin 钩子先执行,组件钩子后执行extends 钩子先执行,目标组件钩子后执行
方法、计算属性、侦听器组件优先级高于 mixin目标组件优先级高于 extends 的组件
优先级extends > mixin > 目标组件extends > mixin > 目标组件

通过理解 mixinextends 的覆盖逻辑,可以更好地组织代码,避免冲突和意外行为。

THE END
点赞12 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容