2026/2/7 4:18:40
网站建设
项目流程
手机主页哪个网站好,为什么做域名跳转网站样式不见了,中国能源建设集团有限公司董事长,修改wordpress默认主题标题1 学习指南1.1 学习目标认知层级目标描述对应章节了解掌握组件化开发思想与核心价值2.1 组件化思想掌握组件注册、父子通信基础用法3.1-3.2、4.1-4.2熟练高级组件特性与复杂场景应用4.3-4.5、6.0应用独立完成中型项目组件拆分与实现5.0 实战案例1.2 前置知识掌握 Vue 基础语法模板、指令、响应式数据了解 ES6 语法解构、箭头函数、模块化具备 HTML/CSS 基础2 组件的简介组件是 Vue.js 的核心概念是可复用的 Vue 实例相当于页面的 “功能积木”。将复杂页面拆分为独立、可复用的组件能实现代码模块化单个组件专注单一功能维护成本降低复用性提升同一组件可在多个页面重复使用协作高效多人开发时可并行开发不同组件组件的本质是 “独立的视图 逻辑单元”类比现实中的 “乐高积木”—— 每个积木有固定功能比如轮子、车身组合起来形成完整模型应用。3 组件的使用3.1 组件注册方式3.1.1 全局注册全局可用// main.js import { createApp } from vue import App from ./App.vue import GlobalComponent from ./components/GlobalComponent.vue const app createApp(App) // 全局注册所有组件均可直接使用 app.component(GlobalComponent, GlobalComponent) app.mount(#app)3.1.2 局部注册仅当前组件可用LocalComponent / 局部组件只能在当前父组件使用 -- // 局部注册导入即注册无需额外配置 import LocalComponent from ./LocalComponent.vue /script3.2 组件使用规范注册方式对比注册方式适用场景优点缺点最佳实践全局注册通用基础组件如 Button/Icon全局可直接使用无需导入增加打包体积未使用组件无法 Tree-Shaking注册不超过 5 个核心基础组件局部注册业务组件如 TodoInput/TodoItem按需导入减小打包体积需手动导入后使用业务模块优先使用配合自动导入插件组件名建议使用kebab-case短横线分隔如todo-item单文件组件SFC统一后缀为.vue包含template/script/ 三部分样式隔离在标签添加scoped 属性避免样式污染4 组件之间的通信组件通信是组件协作的核心Vue3 提供了多种通信方案重点关注父子组件通信。4.1 父组件向子组件通信已完成核心方案Props 传递单向数据流父传子子不可直接修改 propsParent.vue -- :usernameuserName :ageuserAge / script setup import { ref } from vue import ChildComponent from ./ChildComponent.vue const userName ref(张三) const userAge ref(18) /script 组件 ChildComponent.vue -- template p姓名{{ username }}/p p年龄{{ age }}/p // 定义props并指定类型、默认值、必填项 const props defineProps({ username: { type: String, required: true }, age: { type: Number, default: 18 // 未传递时使用默认值 } }) /script4.2 子组件向父组件通信核心方案自定义事件$emit类比 “儿子向父亲汇报情况”子组件触发事件父组件监听并处理。4.2.1 基础用法3 步实现子组件声明可触发的事件defineEmits子组件触发事件emit(事件名, 数据)父组件监听事件事件名处理函数!-- 子组件 ChildComponent.vue -- sendMessage向父组件发送消息 inputValue placeholder输入要传递的内容 / script setup import { ref } from vue // 1. 声明可触发的事件支持多个数组形式 const emit defineEmits([message-sent, value-change]) const inputValue ref() // 2. 触发事件第一个参数是事件名后续是传递的数据 function sendMessage() { emit(message-sent, 子组件问候你好父组件) // 传递字符串 emit(value-change, inputValue.value) // 传递输入框值 } .vue -- message-senthandleMessage value-changehandleValueChange / 的消息{{ parentMessage }}/p p父组件接收的输入值{{ parentValue }}/p import { ref } from vue import ChildComponent from ./ChildComponent.vue const parentMessage ref() const parentValue ref() // 3. 监听事件并处理数据 function handleMessage(msg) { parentMessage.value msg } function handleValueChange(val) { parentValue.value val } #### 4.2.2 进阶用法v-model双向绑定语法糖 v-model是props emit的组合适用于“父子组件数据同步”场景如自定义输入框 vue !-- 子组件 CustomInput.vue -- :valuemodelValue inputemit(update:modelValue, $event.target.value) / 接收父组件v-model传递的value默认名modelValue defineProps([modelValue]) // 声明更新事件固定格式update:modelValue const emit defineEmits([update:modelValue]) .vue -- ValuesearchText update:modelValuesearchText $event / -- v-modelsearchText / 搜索内容{{ searchText }}/p import { ref } from vue import CustomInput from ./CustomInput.vue const searchText ref()4.2.2 注意事项事件名建议使用kebab-case短横线分隔与组件名规范一致可传递任意类型数据字符串、对象、数组等子组件不可直接修改父组件数据必须通过 “触发事件” 让父组件自行修改遵循单向数据流5 组件实战案例TodoList 任务清单5.1 案例需求实现一个简易 TodoList包含功能父组件管理任务列表数据存储子组件 1TodoInput输入任务并添加到列表子传父子组件 2TodoItem展示单个任务支持删除功能子传父父组件向子组件传递任务数据父传子5.2 代码实现5.2.1 目录结构src/ ├── components/ │ ├── TodoInput.vue // 任务输入组件子 │ └── TodoItem.vue // 单个任务组件子 └── App.vue // 父组件任务列表管理5.2.2 子组件 1TodoInput.vue添加任务-input v-modelnewTodo placeholder请输入新任务 keyup.enteraddTodo / clickaddTodo添加/button /div { ref } from vue const emit defineEmits([add-todo]) // 声明添加事件 const newTodo ref() function addTodo() { if (newTodo.value.trim()) { // 传递任务对象给父组件 emit(add-todo, { id: Date.now(), // 用时间戳作为唯一ID content: newTodo.value, done: false }) newTodo.value // 清空输入框 } } style scoped .todo-input { margin: 20px 0; display: flex; gap: 10px; } input { flex: 1; padding: 8px; } button { padding: 8px 16px; background: #42b983; color: white; border: none; border-radius: 4px; cursor: pointer; } /style5.2.3 子组件 2TodoItem.vue单个任务template classtodo-item done: todo.done } clicktoggleDone {{ todo.content }} deleteTodo删除/button script setup const props defineProps({ todo: { type: Object, required: true, // 验证todo对象结构 validator: (value) { return id in value content in value done in value } } }) const emit defineEmits([delete-todo, toggle-done]) // 触发删除事件传递任务ID function deleteTodo() { emit(delete-todo, props.todo.id) } // 触发状态切换事件 function toggleDone() { emit(toggle-done, props.todo.id) } /script oped .todo-item { display: flex; justify-content: space-between; align-items: center; padding: 8px; border-bottom: 1px solid #eee; } .done { text-decoration: line-through; color: #999; } button { background: #ff4444; color: white; border: none; border-radius: 4px; padding: 4px 8px; cursor: pointer; }5.2.4 父组件App.vue核心管理template 1TodoList 任务清单 输入任务子传父添加任务 -- add-todohandleAddTodo / 子组件2展示任务父传子任务数据子传父删除/切换 -- todo-list TodoItem v-fortodo in todoList :keytodo.id :todotodo delete-todohandleDeleteTodo toggle-donehandleToggleDone / /div import { ref } from vue import TodoInput from ./components/TodoInput.vue import TodoItem from ./components/TodoItem.vue // 父组件维护任务列表响应式数据 const todoList ref([ { id: 1, content: 学习Vue组件通信, done: false }, { id: 2, content: 完成实战案例, done: false } ]) // 处理添加任务接收子组件传递的任务对象 function handleAddTodo(newTodo) { todoList.value.push(newTodo) } // 处理删除任务接收子组件传递的任务ID function handleDeleteTodo(todoId) { todoList.value todoList.value.filter(todo todo.id ! todoId) } // 处理切换任务状态接收子组件传递的任务ID function handleToggleDone(todoId) { const todo todoList.value.find(todo todo.id todoId) if (todo) todo.done !todo.done } /script scoped h1 { color: #333; } .todo-list { border: 1px solid #eee; border-radius: 4px; padding: 10px; }5.3 案例效果- 输入任务内容点击“添加”或按回车任务会添加到列表子传父- 点击任务文本切换完成状态子传父触发状态更新- 点击“删除”按钮移除对应任务子传父触发删除- 父组件通过props将任务数据传递给TodoItem组件父传子5.4 案例核心知识点总结1. 组件拆分按功能拆分为“输入组件”“列表项组件”“父组件”职责单一2. 父传子通过props传递任务数据、配置项3. 子传父通过自定义事件传递操作添加/删除/切换和数据任务ID/对象4. 响应式数据父组件维护核心数据子组件仅负责展示和触发事件如果需要补充某部分细节如 TypeScript 支持、组件复用技巧或想扩展其他实战案例如购物车、表单组件可以随时告诉我