创建阶段是 Vue 实例生命周期的第一个阶段。在这个阶段,Vue 完成实例的初始化工作,包括数据观测、事件配置等。
创建阶段包含两个钩子:beforeCreate 和 created。
beforeCreate 在实例初始化之后,数据观测和事件配置之前调用。
new Vue()
│
▼
beforeCreate ← 此时 data、methods 都不可用
│
▼
初始化 data、methods、computed、watch
│
▼
created
new Vue({
data: {
message: 'Hello'
},
methods: {
greet() {
console.log(this.message)
}
},
beforeCreate() {
console.log('beforeCreate')
console.log(this.message)
console.log(this.greet)
console.log(this.$el)
}
})
输出结果:
beforeCreate
undefined
undefined
undefined
beforeCreate 的使用场景较少,常见的有:
1. 加载动画开始
beforeCreate() {
NProgress.start()
}
2. 插件初始化
某些插件需要在 Vue 初始化之前设置:
beforeCreate() {
this.$options.plugins = loadPlugins()
}
created 在实例创建完成后调用。此时实例已完成数据观测、属性和方法的运算、watch/event 事件回调。
beforeCreate
│
▼
初始化 data、methods、computed、watch
│
▼
created ← 此时 data、methods 都可访问
new Vue({
data: {
message: 'Hello',
users: []
},
methods: {
greet() {
console.log(this.message)
}
},
created() {
console.log('created')
console.log(this.message)
this.greet()
this.fetchUsers()
},
methods: {
async fetchUsers() {
const response = await fetch('/api/users')
this.users = await response.json()
}
}
})
输出结果:
created
Hello
Hello
created 是最常用的生命周期钩子之一:
1. 发起异步请求
created() {
this.loadUserInfo()
this.loadSettings()
},
methods: {
async loadUserInfo() {
const res = await api.getUserInfo()
this.userInfo = res.data
},
async loadSettings() {
const res = await api.getSettings()
this.settings = res.data
}
}
2. 初始化数据
created() {
this.initForm()
},
methods: {
initForm() {
this.form = {
username: '',
email: '',
role: 'user'
}
}
}
3. 设置定时器
created() {
this.timer = setInterval(() => {
this.updateTime()
}, 1000)
},
beforeDestroy() {
clearInterval(this.timer)
}
4. 事件监听
created() {
eventBus.$on('user-login', this.handleLogin)
eventBus.$on('user-logout', this.handleLogout)
},
beforeDestroy() {
eventBus.$off('user-login', this.handleLogin)
eventBus.$off('user-logout', this.handleLogout)
}
两个钩子的对比:
| 特性 | beforeCreate | created |
|---|---|---|
| data | 不可访问 | 可访问 |
| methods | 不可访问 | 可访问 |
| computed | 不可访问 | 可访问 |
| watch | 不可访问 | 可访问 |
| $el | 不可访问 | 不可访问 |
| 使用频率 | 低 | 高 |
Vue.component('user-profile', {
template: `
<div class="user-profile">
<div v-if="loading">加载中...</div>
<div v-else>
<h2>{{ user.name }}</h2>
<p>{{ user.email }}</p>
</div>
</div>
`,
data() {
return {
user: null,
loading: true
}
},
created() {
this.loadUser()
},
methods: {
async loadUser() {
try {
const response = await fetch(`/api/users/${this.userId}`)
this.user = await response.json()
} catch (error) {
console.error('加载用户失败:', error)
} finally {
this.loading = false
}
}
},
props: {
userId: {
type: Number,
required: true
}
}
})
Vue.component('user-form', {
template: `
<form @submit.prevent="submit">
<input v-model="form.name" placeholder="姓名">
<input v-model="form.email" placeholder="邮箱">
<button type="submit">提交</button>
</form>
`,
props: {
initialData: Object
},
data() {
return {
form: {
name: '',
email: ''
}
}
},
created() {
if (this.initialData) {
this.form = { ...this.initialData }
}
},
methods: {
submit() {
this.$emit('submit', this.form)
}
}
})
new Vue({
data() {
return {
config: null,
error: null
}
},
created() {
this.validateConfig()
},
methods: {
validateConfig() {
const config = localStorage.getItem('app-config')
if (!config) {
this.error = '配置不存在'
return
}
try {
this.config = JSON.parse(config)
if (!this.config.apiKey) {
this.error = 'API Key 缺失'
}
} catch (e) {
this.error = '配置格式错误'
}
}
}
})
在服务端渲染(SSR)时,created 钩子会在服务端执行:
export default {
data() {
return {
article: null
}
},
created() {
if (typeof window === 'undefined') {
console.log('服务端执行')
} else {
console.log('客户端执行')
}
}
}
注意:
1. 数据请求放在 created
created() {
this.fetchData()
}
2. 避免在 created 中操作 DOM
created() {
console.log(this.$el)
}
3. 合理使用异步操作
created() {
Promise.all([
this.fetchUser(),
this.fetchSettings()
]).then(() => {
this.ready = true
})
}