Vue 工程化开发:组件复用、插槽、项目结构与 ES6 模块化

📅 2026/8/24 13:50:29
Vue 工程化开发:组件复用、插槽、项目结构与 ES6 模块化
一、组件基础组件是可复用的界面单元通常包含自己的模板、数据、方法、样式和生命周期。把页面拆成组件可以降低单个文件的复杂度也便于多人协作和后续维护。组件的data必须是一个返回对象的函数。这样每次创建组件实例时都会得到独立的数据避免多个实例共享同一个对象。二、全局组件与局部组件1. 全局组件全局组件通过Vue.component()注册注册后当前页面中的所有 Vue 实例和子组件都可以使用。全局组件适合按钮、图标等通用程度很高的组件但数量过多会增加命名冲突和维护成本。dividappchild-card/child-card/divscriptsrc./vue2/vue.js/scriptscriptVue.component(child-card,{template:section h2{{ name }}/h2 button clickshowMessage显示提示/button /section,data(){return{name:子组件}},methods:{showMessage(){alert(组件按钮被点击了)}}})newVue({el:#app})/script2. 局部组件局部组件只在注册它的父组件模板中可用更适合业务页面中的专用组件。推荐把组件对象单独放在.vue文件中再通过import引入。dividappphoto-card/photo-card/divscriptsrc./vue2/vue.js/scriptscriptconstPhotoCard{template:div img :srcimage alt示例图片 width200 button clickchangeImage切换图片/button /div,data(){return{image:./img/1.png}},methods:{changeImage(){this.image./img/2.png}}}newVue({el:#app,components:{PhotoCard}})/script三、动态组件与 keep-alive动态组件使用component :is...根据变量切换组件适合选项卡、不同商品分类和多步骤表单。相比堆叠多个v-if动态组件能让切换逻辑更集中。dividappbuttonclickcurrent fresh-panel生鲜/buttonbuttonclickcurrent seafood-panel水产/buttonbuttonclickcurrent meat-panel肉类/buttoncomponent:iscurrent/component/divscriptVue.component(fresh-panel,{template:h3生鲜商品/h3})Vue.component(seafood-panel,{template:h3水产商品/h3})Vue.component(meat-panel,{template:h3肉类商品/h3})newVue({el:#app,data:{current:fresh-panel}})/script默认切换组件时旧组件可能被销毁输入框内容和局部状态也会丢失。keep-alive会缓存动态组件实例使组件切换回来时保留状态。keep-alivecomponent:iscurrent/component/keep-alive被缓存组件可以使用activated和deactivated处理激活、停用逻辑。缓存不是越多越好页面数量较多时要结合include、exclude或max控制缓存范围。四、插槽 slot插槽用于让父组件向子组件传入模板内容。子组件负责统一布局父组件决定具体内容因此很适合封装卡片、弹窗和页面布局。1. 默认插槽dividappbase-cardp这是父组件传入的正文。/p/base-card/divscriptVue.component(base-card,{template:section classcard h2通用卡片/h2 slot没有传入内容时显示的默认文本/slot /section})newVue({el:#app})/script父组件写在base-card标签内部的内容会渲染到子组件的slot位置。没有传入内容时slot标签内部的文本会作为默认内容。2. 具名插槽一个组件需要多个内容区域时可以使用具名插槽。Vue 2 中父组件使用slot名称子组件用slot name名称接收。base-layouttemplateslotheaderh2文章标题/h2/templatep文章正文内容。/ptemplateslotfooterbutton保存/button/template/base-layoutscriptVue.component(base-layout,{template:div classlayout headerslot nameheader/slot/header mainslot/slot/main footerslot namefooter/slot/footer /div})/scriptVue 3 使用v-slot或#header的写法。项目升级时应按照对应版本的插槽语法编写避免混用。五、创建 Vue 项目Vue 2 常使用 Vue CLI 创建项目Vue 3 新项目通常使用 Vite。两者都依赖 Node.js 环境Node.js 提供运行时npm 负责安装和管理依赖。# 查看 Node.js 和 npm 是否安装成功node-vnpm-v# 可选配置 npm 镜像源npmconfigsetregistry https://registry.npmmirror.comnpmconfig get registry# Vue CLI主要用于 Vue 2 或旧项目npminstall-gvue/cli vue create vue-demo# 进入项目并启动开发服务器cdvue-demonpmrun serve包管理器的核心职责是根据package.json安装依赖。不要把node_modules提交到 Git把项目交给其他人时执行npm install即可依据锁定文件重新安装依赖。六、Vue 项目目录结构典型 Vue CLI 项目结构如下vue-demo/ ├─ public/ │ └─ index.html # SPA 的 HTML 入口 ├─ src/ │ ├─ assets/ # 需要经过构建处理的图片、样式 │ ├─ components/ # 可复用的小组件 │ ├─ views/ # 页面级组件 │ ├─ router/ # 路由配置 │ ├─ store/ # 状态管理配置 │ ├─ App.vue # 根组件 │ └─ main.js # 应用启动入口 ├─ package.json # 项目脚本和依赖声明 ├─ package-lock.json # 依赖版本锁定文件 └─ vue.config.js # Vue CLI 构建配置可选public/index.html通常只保留挂载点Vue 会把根组件渲染到#app。业务代码主要写在src中。assets中的资源会被构建工具处理直接放在public的资源则按原路径提供。七、Vue 单文件组件规范.vue文件通常由template、script和style三部分组成。scoped会让样式只作用于当前组件生成的节点避免普通类名污染其他组件。template header classtop-bar button clickgoBack后退/button span{{ title }}/span button clickgoForward前进/button /header /template script export default { name: TopBar, data() { return { title: 首页 } }, methods: { goBack() { window.history.back() }, goForward() { window.history.forward() } } } /script style scoped .top-bar { display: flex; justify-content: space-between; align-items: center; } /style在其他组件中使用时需要先导入再注册最后在模板中使用template div idapp TopBar / /div /template script import TopBar from /components/TopBar.vue export default { name: App, components: { TopBar } } /script通常是构建工具配置的src别名。组件名推荐使用多单词形式避免和原生 HTML 标签冲突。八、路由与页面组件使用 Vue Router 后URL 和页面组件的对应关系由路由表决定。App.vue一般只保留布局和router-view /当前路由匹配的页面会渲染到这个位置。// src/router/index.jsimportVuefromvueimportVueRouterfromvue-routerimportHomeViewfrom/views/HomeView.vueimportAboutViewfrom/views/AboutView.vueVue.use(VueRouter)exportdefaultnewVueRouter({mode:history,routes:[{path:/,name:home,component:HomeView},{path:/about,name:about,component:AboutView}]})!-- App.vue -- template div idapp router-link to/首页/router-link router-link to/about关于/router-link router-view / /div /template创建新页面时通常在views中新建页面组件再在路由配置中注册路径。组件内部的可复用部分放入components不要把所有代码都堆在页面组件中。九、ES6 常用语法1. let、const 与块级作用域let声明可重新赋值的块级变量const声明不能重新赋值的绑定。对象用const声明后仍然可以修改对象内部属性不能做的是给变量重新绑定另一个对象。letcount1count2constuser{name:lqz}user.namenew name// 可以修改属性// user {} // 不允许重新赋值if(true){letinside只在代码块内有效constfixed1}// console.log(inside) // ReferenceErrorvar具有函数作用域和变量提升容易造成意外覆盖。现代项目通常优先使用const确实需要重新赋值时使用let。2. 模板字符串反引号字符串支持换行和插值适合拼接提示文本或组件模板constnamelqzconstmessage你好${name}console.log(message)3. 解构赋值解构可以从对象或数组中提取值接口返回数据和函数参数处理中经常使用。constuser{name:lqz,age:19}const{name,age,city未知}userconstnumbers[11,22,33]const[first,second]numbersfunctiongetUser(){return{username:tom,role:admin}}const{username,role}getUser()console.log(name,age,city,first,second,username,role)缺少的对象属性会得到undefined可以在解构时使用提供默认值。4. 默认参数与展开运算符functiongreet(name访客){return你好${name}}constbase{age:19,hobby:阅读}constuser{name:lqz,...base}constfirst[1,2]constall[0,...first,3]functioncollect(firstValue,...rest){return{firstValue,rest}}console.log(greet())console.log(user,all,collect(...[10,20,30]))对象展开通常用于浅拷贝和合并配置嵌套对象仍然共享引用需要深拷贝时应使用专门方案。十、ES6 模块化模块通过export暴露内容通过import引入内容。默认导出一个模块只能有一个命名导出可以有多个。// utils.js默认导出constappNameVue Demofunctionadd(a,b){returnab}exportdefault{appName,add}// 使用默认导出importutilsfrom./utils.jsconsole.log(utils.appName)console.log(utils.add(3,4))// utils.js命名导出exportconstversion1.0.0exportfunctionsubtract(a,b){returna-b}import{version,subtractasminus}from./utils.jsconsole.log(version,minus(8,3))如果目录下存在index.js导入时通常可以只写目录路径。模块化的价值在于拆分职责、避免全局变量污染并使依赖关系在文件顶部清晰可见。十一、总结与练习全局组件使用方便但容易产生命名和维护问题业务组件优先局部注册。动态组件负责切换keep-alive负责缓存插槽负责让父组件注入可变内容。Vue 项目通过main.js启动页面组件放在views可复用组件放在components路由配置集中在router。let、const、解构、展开和模块化是 Vue 工程中高频使用的 ES6 语法。建议完成一个带选项卡、可缓存表单、具名插槽卡片和路由页面的综合练习体会组件拆分和数据复用。