每个 Vue 应用都是通过创建 Vue 实例开始的。Vue 实例是 Vue 应用的核心,它连接了数据、模板和 DOM。
理解 Vue 实例是掌握 Vue 的基础。实例管理着数据、方法、生命周期钩子,以及与 DOM 的交互。
Vue 实例是 Vue 应用的入口点。它是一个对象,包含了应用的所有配置:
const vm = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
},
methods: {
greet() {
alert(this.message)
}
}
})
const vm = new Vue({
el: '#app',
template: '<div>{{ message }}</div>',
data: {
message: 'Hello'
}
})
可以不指定 el,稍后手动挂载:
const vm = new Vue({
template: '<div>{{ message }}</div>',
data: {
message: 'Hello'
}
})
vm.$mount('#app')
或者:
const vm = new Vue({
data: {
message: 'Hello'
}
}).$mount('#app')
const ComponentClass = Vue.extend({
template: '<div>{{ message }}</div>',
data() {
return {
message: 'Hello'
}
}
})
const instance = new ComponentClass()
instance.$mount('#app')
每个 Vue 组件也是一个 Vue 实例:
Vue.component('my-component', {
data() {
return {
count: 0
}
},
template: '<button @click="count++">{{ count }}</button>'
})
组件实例与根实例的区别:
| 特性 | 根实例 | 组件实例 |
|---|---|---|
| data | 对象 | 函数 |
| el | 可以有 | 不能有 |
| 父实例 | 无 | 有 |
Vue 实例接受多种选项:
new Vue({
data: {
message: 'Hello'
},
props: {
title: String
},
computed: {
reversedMessage() {
return this.message.split('').reverse().join('')
}
},
methods: {
greet() {
console.log(this.message)
}
},
watch: {
message(newVal, oldVal) {
console.log(`Message changed from ${oldVal} to ${newVal}`)
}
}
})
new Vue({
el: '#app',
template: '<div>{{ message }}</div>',
render(h) {
return h('div', this.message)
},
renderError(h, err) {
return h('pre', { style: { color: 'red' } }, err.stack)
}
})
new Vue({
beforeCreate() {},
created() {},
beforeMount() {},
mounted() {},
beforeUpdate() {},
updated() {},
beforeDestroy() {},
destroyed() {},
activated() {},
deactivated() {},
errorCaptured(err, vm, info) {}
})
new Vue({
directives: {
focus: {
inserted(el) {
el.focus()
}
}
},
filters: {
uppercase(value) {
return value.toUpperCase()
}
},
components: {
'my-component': {
template: '<div>Component</div>'
}
}
})
new Vue({
mixins: [mixin],
extends: baseComponent,
provide: {
theme: 'dark'
},
inject: ['userService']
})
Vue 实例提供了一些有用的属性:
| 属性 | 说明 |
|---|---|
| $data | 数据对象 |
| $props | props 对象 |
| $el | DOM 元素 |
| $options | 实例选项 |
| $parent | 父实例 |
| $root | 根实例 |
| $children | 子组件实例 |
| $refs | 引用元素 |
| $attrs | 非 prop 属性 |
| $listeners | 事件监听器 |
const vm = new Vue({
el: '#app',
data: {
message: 'Hello'
},
mounted() {
console.log(this.$data)
console.log(this.$el)
console.log(this.$options)
}
})
console.log(vm.$data.message)
console.log(vm.$el.outerHTML)
vm.$watch('message', (newVal, oldVal) => {
console.log(`Changed: ${oldVal} -> ${newVal}`)
})
vm.$set(this.obj, 'newProp', 'value')
vm.$delete(this.obj, 'oldProp')
vm.$on('event', handler)
vm.$once('event', handler)
vm.$off('event', handler)
vm.$emit('event', payload)
vm.$mount('#app')
vm.$forceUpdate()
vm.$nextTick(callback)
vm.$destroy()
Vue 实例的 data 是响应式的:
const vm = new Vue({
data: {
message: 'Hello'
}
})
vm.message = 'World'
当 message 改变时,视图会自动更新。
对象:Vue 无法检测属性添加
vm.obj.newProp = 'value'
需要使用 $set:
vm.$set(vm.obj, 'newProp', 'value')
数组:Vue 无法检测某些变更
vm.items[0] = 'new value'
vm.items.length = 0
需要使用变异方法或 $set:
vm.items.splice(0, 1, 'new value')
vm.items.splice(0)
Vue 实例代理了 data 和 props 的属性:
const vm = new Vue({
data: {
message: 'Hello'
}
})
console.log(vm.message)
vm.message = 'World'
实际上访问的是 vm.$data.message。
在 Vue 实例的方法中,this 指向实例本身:
new Vue({
data: {
message: 'Hello'
},
methods: {
greet() {
console.log(this.message)
}
},
created() {
this.greet()
}
})