创建 Vue 实例是每个 Vue 应用的起点。本章详细介绍实例创建的各种方式和注意事项。
最常见的方式是使用 el 选项指定挂载点:
const vm = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
})
Vue 会自动查找匹配的 DOM 元素并挂载。
el 可以是 CSS 选择器字符串:
new Vue({
el: '#app',
data: { message: 'Hello' }
})
new Vue({
el: '.container',
data: { message: 'Hello' }
})
el 也可以是直接的 DOM 元素:
new Vue({
el: document.getElementById('app'),
data: { message: 'Hello' }
})
可以先创建实例,稍后再挂载:
const vm = new Vue({
data: {
message: 'Hello'
},
template: '<div>{{ message }}</div>'
})
vm.$mount('#app')
$mount 不传参数时,实例处于未挂载状态:
const vm = new Vue({
data: {
message: 'Hello'
},
template: '<div>{{ message }}</div>'
})
vm.$mount()
document.getElementById('app').appendChild(vm.$el)
可以链式调用:
new Vue({
data: {
message: 'Hello'
},
template: '<div>{{ message }}</div>'
}).$mount('#app')
new Vue({
el: '#app',
template: '<div>{{ message }}</div>',
data: {
message: 'Hello'
}
})
new Vue({
el: '#app',
template: `
<div class="container">
<h1>{{ title }}</h1>
<p>{{ content }}</p>
</div>
`,
data: {
title: 'Welcome',
content: 'Hello Vue!'
}
})
如果 el 元素有内容,会作为模板:
<div id="app">
<h1>{{ title }}</h1>
<p>{{ content }}</p>
</div>
<script>
new Vue({
el: '#app',
data: {
title: 'Welcome',
content: 'Hello Vue!'
}
})
</script>
new Vue({
el: '#app',
data: {
message: 'Hello'
},
render(h) {
return h('div', this.message)
}
})
new Vue({
el: '#app',
data: {
items: ['Apple', 'Banana', 'Orange']
},
render(h) {
return h('ul',
this.items.map(item =>
h('li', { key: item }, item)
)
)
}
})
new Vue({
el: '#app',
data: {
message: 'Hello'
},
render() {
return <div>{this.message}</div>
}
})
const MyComponent = Vue.extend({
template: '<div>{{ message }}</div>',
data() {
return {
message: 'Hello'
}
}
})
const instance = new MyComponent()
instance.$mount('#app')
const BaseComponent = Vue.extend({
methods: {
greet() {
console.log('Hello')
}
}
})
const ExtendedComponent = BaseComponent.extend({
methods: {
greet() {
console.log('Hello Extended')
}
}
})
new Vue({
data: {
message: 'Hello',
count: 0,
user: {
name: 'John',
age: 30
}
}
})
new Vue({
methods: {
handleClick() {
console.log('Clicked')
},
fetchData() {
return fetch('/api/data')
}
}
})
new Vue({
data: {
firstName: 'John',
lastName: 'Doe'
},
computed: {
fullName() {
return `${this.firstName} ${this.lastName}`
}
}
})
new Vue({
data: {
searchQuery: ''
},
watch: {
searchQuery(newVal, oldVal) {
this.search(newVal)
}
},
methods: {
search(query) {
console.log('Searching:', query)
}
}
})
new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
},
props: {
title: String
},
computed: {
reversedMessage() {
return this.message.split('').reverse().join('')
}
},
methods: {
greet() {
alert(this.message)
}
},
watch: {
message(newVal, oldVal) {
console.log(`Changed: ${oldVal} -> ${newVal}`)
}
},
beforeCreate() {
console.log('beforeCreate')
},
created() {
console.log('created')
},
beforeMount() {
console.log('beforeMount')
},
mounted() {
console.log('mounted')
},
components: {
'my-component': {
template: '<div>Component</div>'
}
},
directives: {
focus: {
inserted(el) {
el.focus()
}
}
},
filters: {
uppercase(value) {
return value.toUpperCase()
}
}
})
一个页面可以有多个 Vue 实例:
const header = new Vue({
el: '#header',
data: {
title: 'My App'
}
})
const main = new Vue({
el: '#main',
data: {
content: 'Main content'
}
})
const footer = new Vue({
el: '#footer',
data: {
copyright: '© 2024'
}
})
const bus = new Vue()
const vm1 = new Vue({
created() {
bus.$on('event', (data) => {
console.log('Received:', data)
})
}
})
const vm2 = new Vue({
methods: {
send() {
bus.$emit('event', { message: 'Hello' })
}
}
})
const vm1 = new Vue({
data: {
message: 'Hello'
}
})
const vm2 = new Vue({
created() {
console.log(vm1.message)
}
})
在单文件组件中,实例创建由 Vue 自动处理:
<template>
<div>{{ message }}</div>
</template>
<script>
export default {
data() {
return {
message: 'Hello'
}
}
}
</script>
生产环境建议使用 render 函数,避免模板编译:
new Vue({
render: h => h(App)
}).$mount('#app')
实例创建后,不应修改 $options:
const vm = new Vue({
data: { message: 'Hello' }
})
vm.$options.data = { message: 'World' }