面试官 : “ Vue 中 el: '#app'` 是什么意思 ? “

25 阅读5分钟

什么是 Vue 实例

在 Vue.js 中,Vue 实例是整个应用的核心。它是使用 new Vue({...}) 创建出来的对象,负责将数据(data)、方法(methods)、模板(template)等连接起来,并进行数据驱动的视图渲染。

简单来说:

  • Vue 实例 是一个 Vue 应用的 “入口” 和 “控制器”。
  • 它会把你定义的数据和方法挂载到页面的某个 DOM 元素上。
  • 当数据变化时,Vue 实例会自动更新视图。

基本用法示例:

<div id="app">
  {{ message }}
</div>

<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
<script>
  // 创建一个 Vue 实例
  var vm = new Vue({
    el: '#app',      // 挂载点
    data: {          // 数据
      message: 'Hello Vue!'
    }
  });
</script>

1. Vue 2 中的 el

在 Vue 2 中,el 用来指定 Vue 实例要挂载到哪个 DOM 元素上,例如:

new Vue({
  el: '#app', // 挂载到 id="app" 的元素
  data: { message: 'Hello Vue!' }
});

el 的值可以是:

  • CSS 选择器字符串(如 '#app'
  • DOM 元素对象(如 document.getElementById('app')

2. Vue 3 中的变化

在 Vue 3 中,el 选项已经被移除,不再通过 new Vue({ el: ... }) 的方式来挂载应用。取而代之的是使用 createApp()  创建应用实例,然后调用 mount()  方法来挂载。


Vue 3 写法

import { createApp } from 'vue';

const app = createApp({
  data() {
    return {
      message: 'Hello Vue!'
    };
  }
});

// 挂载到 #app
app.mount('#app');

手动挂载

你也可以直接传 DOM 元素:

app.mount(document.getElementById('app'));

3. 为什么移除 el

  • Vue 3 引入了 应用实例(app instance)  的概念,所有配置都通过 createApp() 来设置,然后统一用 mount() 挂载。
  • 这种方式更清晰,也更符合现代前端的模块化思想。
  • 可以在 mount() 之前进行其他配置,比如注册全局组件、指令、插件等。

4. 注意事项

  • 在 Vue 3 中,mount() 会返回应用实例,而不是组件实例(Vue 2 中返回的是组件实例)。
  • 如果需要访问组件实例,可以在组件的 setup() 或生命周期钩子中获取。

✅ 总结

  • Vue 2:new Vue({ el: '#app' })
  • Vue 3:createApp(...).mount('#app')

还有什么变化

Vue 3 引入了 Composition API(组合式 API),相比 Vue 2 的 Options API,写法有较大变化,主要是通过 setup() 函数来组织逻辑。

我会帮你把Vue2的选项一一对应到 Vue 3 的写法。


1. 数据相关选项

data

Vue 2

new Vue({
  data: {
    message: 'Hello Vue!'
  }
});

Vue 3(Composition API)

import { reactive, ref } from 'vue';

export default {
  setup() {
    const message = ref('Hello Vue!'); // 基本类型
    const user = reactive({ name: 'Tom' }); // 对象类型
    return { message, user };
  }
};

props

Vue 2

new Vue({
  props: {
    title: String,
    count: {
      type: Number,
      default: 0
    }
  }
});

Vue 3

export default {
  props: {
    title: String,
    count: {
      type: Number,
      default: 0
    }
  },
  setup(props) {
    console.log(props.title);
  }
};

computed

Vue 2

new Vue({
  data: { a: 1 },
  computed: {
    double() { return this.a * 2; }
  }
});

Vue 3

import { ref, computed } from 'vue';

export default {
  setup() {
    const a = ref(1);
    const double = computed(() => a.value * 2);
    return { a, double };
  }
};

watch

Vue 2

new Vue({
  data: { a: 1 },
  watch: {
    a(newVal, oldVal) {
      console.log(newVal, oldVal);
    }
  }
});

Vue 3

import { ref, watch } from 'vue';

export default {
  setup() {
    const a = ref(1);
    watch(a, (newVal, oldVal) => {
      console.log(newVal, oldVal);
    });
    return { a };
  }
};

2. 方法相关选项

methods

Vue 2

new Vue({
  methods: {
    greet() {
      alert('Hello!');
    }
  }
});

Vue 3

export default {
  setup() {
    const greet = () => {
      alert('Hello!');
    };
    return { greet };
  }
};

3. 生命周期钩子

Vue 3 的生命周期钩子改为在 setup() 中调用,并且名称有所变化:

Vue 2Vue 3 (setup() 中)
beforeCreate- (直接写在 setup 最前面)
created- (直接写在 setup 最前面)
beforeMountonBeforeMount
mountedonMounted
beforeUpdateonBeforeUpdate
updatedonUpdated
beforeDestroyonBeforeUnmount
destroyedonUnmounted

Vue2示例

new Vue({
  mounted() {
    console.log('DOM 已挂载');
  }
});

Vue 3 示例

import { onMounted } from 'vue';

export default {
  setup() {
    onMounted(() => {
      console.log('DOM 已挂载');
    });
  }
};

4. 模板相关选项

template

Vue 2

new Vue({
  el: '#app',
  template: '<div>{{ message }}</div>',
  data: { message: 'Hello Vue!' }
});

Vue 3

import { createApp } from 'vue';

const app = createApp({
  template: '<div>{{ message }}</div>',
  data() {
    return { message: 'Hello Vue!' };
  }
});

app.mount('#app');

render

Vue 2

new Vue({
  el: '#app',
  render(h) {
    return h('div', 'Hello Vue!');
  }
});

Vue 3

import { createApp, h } from 'vue';

const app = createApp({
  render() {
    return h('div', 'Hello Vue!');
  }
});

app.mount('#app');

5. 资源选项

components

Vue 2

new Vue({
  components: {
    'my-component': {
      template: '<div>自定义组件</div>'
    }
  }
});

Vue 3

import { createApp } from 'vue';
import MyComponent from './MyComponent.vue';

const app = createApp({
  components: {
    MyComponent
  }
});

app.mount('#app');

6. 其他常用选项

mixins

Vue 2

const myMixin = {
  created() { console.log('mixin 钩子'); }
};
new Vue({
  mixins: [myMixin]
});

Vue 3

  • Vue 3 中 Mixins 依然可用,但官方推荐使用 组合式函数(Composables)替代。

import { onMounted } from 'vue';

export default function useLogger() {
  onMounted(() => {
    console.log('组件已挂载');
  });
}

// 使用
export default {
  setup() {
    useLogger();
  }
};

extends

Vue 2

const Parent = Vue.extend({
  data() { return { a: 1 }; }
});
new Parent({
  data() { return { b: 2 }; }
});

Vue 3

  • Vue 3 不再支持 extends 选项,推荐使用 组合式 API 或 组合式函数 复用逻辑。

✅ 总结

  • Vue 3 推荐使用 Composition API,逻辑写在 setup() 中。
  • 生命周期钩子改为函数形式(如 onMounted)。
  • 数据用 ref / reactive,方法直接定义在 setup 中。
  • 模板和渲染函数的写法略有调整。

✅ 总结:Vue 实例的选项覆盖了数据管理、模板渲染、生命周期、组件复用等核心功能,合理使用这些选项可以灵活构建复杂应用。

总结

  • Vue 实例:是一个通过 new Vue({...}) 创建的对象,管理数据、方法和模板。

  • el: '#app' :告诉 Vue 实例要把自己挂载到页面中 id="app" 的 DOM 元素上。

Vue 3 中的变化

在 Vue 3 中,el 选项已经被移除,不再通过 new Vue({ el: ... }) 的方式来挂载应用。取而代之的是使用 createApp()   创建应用实例,然后调用 mount()   方法来挂载。


Vue 3 写法

import { createApp } from 'vue';

const app = createApp({
  data() {
    return {
      message: 'Hello Vue!'
    };
  }
});

// 挂载到 #app
app.mount('#app');

手动挂载

你也可以直接传 DOM 元素:

app.mount(document.getElementById('app'));

为什么移除 el

  • Vue 3 引入了 应用实例(app instance)   的概念,所有配置都通过 createApp() 来设置,然后统一用 mount() 挂载。
  • 这种方式更清晰,也更符合现代前端的模块化思想。
  • 可以在 mount() 之前进行其他配置,比如注册全局组件、指令、插件等。

注意事项

  • 在 Vue 3 中,mount() 会返回应用实例,而不是组件实例(Vue 2 中返回的是组件实例)。
  • 如果需要访问组件实例,可以在组件的 setup() 或生命周期钩子中获取。