Vue.js入门教程第十讲聚焦Vue Router基础,学习路由配置、动态路由与嵌套路由的搭建方法,通过router-link实现导航跳转,router-view渲染组件,结合导航守卫进行权限控制,实践了单页应用多页面切换逻辑,掌握了路由参数传递与重定向技巧,为构建交互式前端应用奠定基础。
Vue.js入门教程第十讲:深入组件通信与生命周期,构建动态交互应用
在Vue.js入门教程的前九讲中,我们已经系统学习了Vue的基础语法、模板语法、指令、计算属性、侦听器等核心概念,并初步掌握了组件的基本使用方法,从第十讲开始,我们将正式进入Vue组件化开发的进阶阶段——组件通信与生命周期钩子,这两个知识点是构建复杂动态应用的关键,掌握它们能让你的组件"活"起来,实现数据与逻辑的高效协作,为打造响应式、可维护的前端应用奠定坚实基础。
第十讲核心:组件通信——组件间如何"对话"?
在现代单页应用(SPA)开发中,页面通常由多个组件有机拆分而成,而这些组件之间往往需要共享数据或触发彼此的行为,比如父组件需要向子组件传递配置信息,子组件需要通知父组件自己的状态变化,甚至跨层级的组件(如祖父组件与孙子组件)也需要高效通信,这就是"组件通信"的核心目标,Vue提供了多种通信方式,本讲将重点讲解最常用的三种:Props(父子通信)、自定义事件(子父通信)、Provide/Inject(跨层级通信)。
Props:父组件向子组件传递数据
Props是Vue中最基础且常用的父子通信方式,它允许父组件通过属性(attribute)向子组件传递数据,子组件通过props选项接收这些数据,并在模板中灵活使用。
使用场景
- 父组件需要向子组件传递静态数据(如标题、配置项、样式类名)
- 父组件需要向子组件传递动态数据(如列表数据、用户信息、表单数据)
- 子组件需要根据父组件传递的数据进行渲染或计算
代码示例
<!-- 父组件 Parent.vue -->
<template>
<div>
<h2>父组件</h2>
<Child :user-name="userName" :user-age="userAge" :user-profile="userProfile" />
</div>
</template>
<script>
import Child from './Child.vue'
export default {
components: { Child },
data() {
return {
userName: '张三',
userAge: 25,
userProfile: {
occupation: '前端开发',
location: '北京'
}
}
}
}
</script>
<!-- 子组件 Child.vue -->
<template>
<div>
<p>子组件接收到的用户名:{{ userName }}</p>
<p>子组件接收到的年龄:{{ userAge }}</p>
<p>职业:{{ userProfile.occupation }}</p>
<p>所在地:{{ userProfile.location }}</p>
</div>
</template>
<script>
export default {
props: {
userName: {
type: String,
default: '匿名用户' // 设置默认值
},
userAge: {
type: Number,
required: true, // 必传校验
validator: value => value > 0 // 自定义验证
},
userProfile: {
type: Object,
default: () => ({}) // 对象类型默认值需返回函数
}
}
}
</script>
注意事项
- 单向数据流:Props遵循单向数据流原则,父组件的数据更新会流向子组件,但子组件不能直接修改props(避免数据混乱),如果子组件需要修改数据,应通过
$emit触发父组件方法,由父组件统一更新数据。 - 类型校验:Props支持丰富的类型校验(String、Number、Boolean、Array、Object、Function、Symbol等),以及自定义验证函数,增强代码健壮性。
- 命名规范:Props命名在模板中应使用kebab-case(短横线命名),在JavaScript中使用camelCase(驼峰命名)。
自定义事件:子组件向父组件传递数据
当子组件需要通知父组件自己的状态变化(如用户点击按钮、表单提交、数据变更)时,可以通过自定义事件实现,子组件通过$emit方法触发事件,父组件通过v-on(或)监听事件并处理相应逻辑。
使用场景
- 子组件需要触发父组件的某个行为(如删除列表项、提交表单数据)
- 子组件需要向父组件传递内部状态变化
- 子组件需要通知父组件操作结果(如保存成功/失败)
代码示例
<!-- 父组件 Parent.vue -->
<template>
<div>
<h2>父组件</h2>
<p>待办事项列表:</p>
<ul>
<TodoItem
v-for="todo in todos"
:key="todo.id"
:todo="todo"
@delete-todo="handleDelete"
@update-todo="handleUpdate"
/>
</ul>
<p>总任务数:{{ totalTodos }}</p>
</div>
</template>
<script>
import TodoItem from './TodoItem.vue'
export default {
components: { TodoItem },
data() {
return {
todos: [
{ id: 1, text: '学习Vue', completed: false },
{ id: 2, text: '写代码', completed: true }
]
}
},
computed: {
totalTodos() {
return this.todos.length
}
},
methods: {
handleDelete(id) {
this.todos = this.todos.filter(todo => todo.id !== id)
console.log(`删除了任务ID为${id}的待办事项`)
},
handleUpdate(updatedTodo) {
const index = this.todos.findIndex(todo => todo.id === updatedTodo.id)
if (index !== -1) {
this.todos.splice(index, 1, updatedTodo)
}
}
}
}
</script>
<!-- 子组件 TodoItem.vue -->
<template>
<li :class="{ completed: todo.completed }">
<input
type="checkbox"
:checked="todo.completed"
@change="toggleComplete"
/>
<span>{{ todo.text