Vue学习之旅:从生命周期到工程化开发与组件实践(生命周期+工程化开发)
Vue学习之旅:从生命周期到工程化开发与组件实践
文章目录
- Vue学习之旅:从生命周期到工程化开发与组件实践
- 一、Vue生命周期:理解组件的“一生”
- (一)生命周期的四个阶段
- (二)生命周期钩子函数
- 二、综合案例:小黑记账清单
- 项目概述
- 项目代码结构
- (一)HTML 部分
- (二)JavaScript 部分
- 1. 列表渲染
- 2. 添加功能
- 3. 删除功能
- 4. 饼图渲染
- 总结
- 三、工程化开发入门
- (一)开发Vue的两种方式
- (二)Vue CLI:快速搭建Vue项目的利器
- 四、组件化开发
- (一)组件化的概念与优势
- (二)组件的注册方式
- 五、综合案例:小兔鲜首页
- 一、页面结构与功能概述
- 二、组件拆分与实现
- (一)快捷链接组件 `XtxShortCut`
- (二)顶部导航组件 `XtxHeaderNav`
- (三)轮播区域组件 `XtxCarousel`
- (四)新鲜好物组件 `XtxFreshGoods`
- (五)热门品牌组件 `XtxHotBrands`
- (六)最新专题组件 `XtxLatestTopics`
- (七)版权底部组件 `XtxFooter`
- 三、组件的注册方式
- (一)局部注册
- (二)全局注册
- 四、总结
- (二)全局注册
- 四、总结
在Vue的学习进程中,今天接触了Vue的生命周期、工程化开发以及组件化相关的丰富内容。这些知识对于构建高效、可维护的Vue应用至关重要,下面我将详细分享今天的学习收获。
一、Vue生命周期:理解组件的“一生”
Vue生命周期指的是一个Vue实例从创建到销毁的整个过程,这一过程可分为四个阶段:创建、挂载、更新和销毁。
(一)生命周期的四个阶段
- 创建阶段:在这个阶段,Vue实例开始创建,会进行响应式数据的初始化等操作。虽然此时数据已准备好,但DOM尚未渲染,无法进行DOM操作。例如在创建一个计数器的实例时:
data: {
title: '计数器',
count: 100
}
在创建阶段,title
和 count
数据被初始化,但我们无法直接操作DOM元素来显示它们。
2. 挂载阶段:Vue会将模板渲染成真实的DOM,此时可以开始操作DOM。如在新闻列表案例中,当模板渲染完成后,我们可以获取新闻列表的DOM元素并进行一些初始化操作 ,mounted
钩子函数会在这个阶段被调用。
3. 更新阶段:当响应式数据发生变化时,Vue会自动更新视图。在这个阶段,数据的修改会触发视图的重新渲染,以保证数据与视图的一致性。
4. 销毁阶段:Vue实例被销毁,此时可以进行一些资源的释放操作,比如清除定时器、延时器等。在 destroyed
钩子函数中执行这些操作,确保应用在销毁时不会留下无效的资源占用。
(二)生命周期钩子函数
Vue在生命周期的各个阶段会自动运行一些函数,称为生命周期钩子函数,这让开发者能够在特定阶段运行自己的代码。
created
:在数据准备好后调用,适合发送初始化渲染请求。在小黑记账清单案例中,可在这个钩子函数中请求数据,并将数据更新给data
,实现数据的动态渲染。
created() {
// 发送初始化数据请求,假设这里使用axios库
axios.get('your-api-url').then((response) => {
this.data = response.data;
});
}
mounted
:模板渲染完成后调用,可以开始操作DOM。在实现输入框自动聚焦功能时,可以在mounted
钩子函数中获取输入框的DOM元素并调用聚焦方法:
mounted() {
this.$refs.inputElement.focus();
}
这里假设在模板中有一个输入框,并通过 ref
指令为其设置了 inputElement
的引用。
如:
<body>
<div class="container" id="app">
<div class="search-container">
<img src="https://www.itheima.com/images/logo.png" alt="">
<div class="search-box">
<input type="text" v-model="words" id="inp">
<button>搜索一下</button>
</div>
</div>
</div>
<script src="./vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
words: ''
},
mounted() {
document.querySelector('#inp').focus()
},
})
</script>
</body>
就可以使输入框具有自动聚焦的功能
二、综合案例:小黑记账清单
项目概述
我们要实现的小黑记账清单是一个简单的财务管理应用,用户可以在页面上添加账单,查看账单列表,删除账单,并通过饼图直观地展示消费分布情况。下面我们将详细分析每个功能的实现细节。
项目代码结构
(一)HTML 部分
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<!-- 引入 Bootstrap 的 CSS 样式文件 -->
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css"
/>
<style>
.red {
color: red!important;
}
.search {
width: 300px;
margin: 20px 0;
}
.my-form {
display: flex;
margin: 20px 0;
}
.my-form input {
flex: 1;
margin-right: 20px;
}
.table > :not(:first-child) {
border-top: none;
}
.contain {
display: flex;
padding: 10px;
}
.list-box {
flex: 1;
padding: 0 30px;
}
.list-box a {
text-decoration: none;
}
.echarts-box {
width: 600px;
height: 400px;
padding: 30px;
margin: 0 auto;
border: 1px solid #ccc;
}
tfoot {
font-weight: bold;
}
@media screen and (max-width: 1000px) {
.contain {
flex-wrap: wrap;
}
.list-box {
width: 100%;
}
.echarts-box {
margin-top: 30px;
}
}
</style>
</head>
<body>
<div id="app">
<div class="contain">
<!-- 左侧列表 -->
<div class="list-box">
<!-- 添加资产 -->
<form class="my-form">
<!-- 输入框,使用 v-model.trim 对输入的消费名称进行双向绑定并去除首尾空格 -->
<input v-model.trim="name" type="text" class="form-control" placeholder="消费名称" />
<!-- 输入框,使用 v-model.number 对输入的消费价格进行双向绑定并将其转换为数字类型 -->
<input v-model.number="price" type="text" class="form-control" placeholder="消费价格" />
<!-- 点击按钮调用 add 方法添加账单 -->
<button @click="add" type="button" class="btn btn-primary">添加账单</button>
</form>
<table class="table table-hover">
<thead>
<tr>
<th>编号</th>
<th>消费名称</th>
<th>消费价格</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<!-- 使用 v-for 指令遍历 list 数组生成账单列表 -->
<tr v-for="(item, index) in list" :key="item.id">
<td>{{ index + 1}}</td>
<td>{{ item.name }}</td>
<!-- 根据价格是否大于 500 为价格单元格添加 red 类 -->
<td :class="{ red: item.price > 500 }">{{ item.price.toFixed(2) }}</td>
<!-- 点击删除链接调用 del 方法并传递 id -->
<td><a @click="del(item.id)" href="javascript:;">删除</a></td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="4">消费总计: {{ totalPrice.toFixed(2) }}</td>
</tr>
</tfoot>
</table>
</div>
<!-- 右侧图表 -->
<div class="echarts-box" id="main"></div>
</div>
</div>
<!-- 引入 Echarts 库 -->
<script src="../echarts.min.js"></script>
<!-- 引入 Vue 库 -->
<script src="../vue.js"></script>
<!-- 引入 Axios 库用于发送 HTTP 请求 -->
<script src="../axios.js"></script>
<script>
</script>
</body>
</html>
这个 HTML 部分的核心是 div
元素 id="app"
,它是 Vue 应用的挂载点。页面布局使用了 Bootstrap 进行基本样式设置,包含一个表单用于添加账单,一个表格用于显示账单列表,以及一个 echarts-box
用于展示饼图。
(二)JavaScript 部分
/**
* 接口文档地址:
* https://www.apifox.cn/apidoc/shared-24459455-ebb1-4fdc-8df8-0aff8dc317a8/api-53371058
*
* 功能需求:
* 1. 基本渲染
* 2. 添加功能
* 3. 删除功能
* 4. 饼图渲染
*/
const app = new Vue({
el: '#app',
data: {
list: [], // 存储账单列表的数据
name: '', // 存储输入的消费名称
price: '' // 存储输入的消费价格
},
computed: {
// 计算属性 totalPrice 用于计算账单的总价
totalPrice() {
return this.list.reduce((sum, item) => sum + item.price, 0);
}
},
created() {
// 在组件创建时调用 getList 方法获取账单列表数据
this.getList();
},
mounted() {
// 在组件挂载后初始化 Echarts 实例并设置初始的饼图选项
this.myChart = echarts.init(document.querySelector('#main'));
this.myChart.setOption({
title: {
text: '消费账单明细',
left: 'center'
},
tooltip: {
trigger: 'item'
},
legend: {
orient: 'vertical',
left: 'left'
},
series: [
{
name: '消费账单',
type: 'pie',
radius: '50%',
data: [
{ value: 1048, name: 'Search Engine' },
{ value: 735, name: 'Direct' },
{ value: 580, name: 'Email' },
{ value: 484, name: 'Union Ads' },
{ value: 300, name: 'Video Ads' }
],
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
}
]
});
},
methods: {
async getList() {
try {
// 发送 GET 请求获取账单列表数据
const res = await axios.get('https://applet-base-api-t.itheima.net/bill', {
params: {
creator: '小黑'
}
});
this.list = res.data.data;
// 根据获取的数据更新饼图的数据
this.myChart.setOption({
series: [
{
data: this.list.map(item => ({ value: item.price, name: item.name }))
}
]
});
} catch (error) {
console.error('获取账单列表失败:', error);
}
},
async add() {
if (!this.name) {
alert("请输入正确的商品名称");
return;
}
if (typeof this.price!=='number') {
alert("请输入正确的商品价格");
return;
}
try {
// 发送 POST 请求添加账单
const res = await axios.post('https://applet-base-api-t.itheima.net/bill', {
creator: '小黑',
name: this.name,
price: this.price
});
// 添加成功后重新获取账单列表
this.getList();
this.name = '';
this.price = '';
} catch (error) {
console.error('添加账单失败:', error);
}
},
async del(id) {
try {
// 发送 DELETE 请求删除账单
const res = await axios.delete(`https://applet-base-api-t.itheima.net/bill/${id}`);
// 删除成功后重新获取账单列表
this.getList();
} catch (error) {
console.error('删除账单失败:', error);
}
}
}
});
1. 列表渲染
- 在
created
生命周期钩子函数中,调用getList
方法。 getList
方法使用axios
发送 GET 请求到https://applet-base-api-t.itheima.net/bill
接口,并将creator
参数设置为小黑
。- 获取到的数据存储在
list
数组中,实现了列表的渲染。同时,使用v-for
指令将列表数据渲染到表格中,:key
属性确保 Vue 能正确更新列表。
2. 添加功能
- 当用户点击添加账单按钮时,会调用
add
方法。 add
方法首先检查name
是否为空和price
是否为数字类型,如果不符合要求会弹出警告信息。- 满足条件后,使用
axios.post
发送请求添加账单,请求成功后调用getList
方法重新获取列表数据,同时清空输入框。
3. 删除功能
-
当用户点击删除按钮时,调用
del
方法并传递id
。 -
del
方法使用axios.delete
发送请求删除账单,删除成功后调用getList
方法重新获取列表数据,确保列表及时更新。
4. 饼图渲染
-
在
mounted
生命周期钩子函数中,使用echarts.init(document.querySelector('#main'))
初始化 Echarts 实例。 -
首先设置了一个初始的饼图选项,包含一些默认数据。
-
在
getList
方法中,当获取到账单列表数据后,使用this.list.map(item => ({ value: item.price, name: item.name }))
将账单数据映射为 Echarts 所需的数据格式,并通过setOption
方法更新饼图数据,实现了饼图的动态更新。
总结
这个小黑记账清单项目展示了 Vue 如何与后端 API 进行交互,并通过 Vue 的响应式数据绑定、生命周期钩子函数和计算属性等特性实现了一个功能完整的应用。我们通过 v-for
指令实现列表的动态渲染,使用 axios
进行数据的获取、添加和删除操作,以及利用 Echarts 实现了饼图的动态更新。在开发过程中,要注意 v-model
的使用,它能方便地实现表单元素与数据的双向绑定;同时,使用 async/await
让异步操作的代码更加简洁和易读。另外,处理请求时的错误捕获和异常处理也非常重要,可以帮助我们更好地调试和优化应用。
三、工程化开发入门
(一)开发Vue的两种方式
- 核心包传统开发模式:基于html、css、js文件,直接引入核心包进行Vue开发。这种方式适用于小型、简单的项目,但对于复杂项目,其配置和管理可能较为繁琐。
- 工程化开发模式:基于构建工具(如webpack)的环境中开发Vue。虽然这种方式功能强大,但webpack的配置较为复杂,缺乏统一标准。于是,Vue CLI应运而生。
(二)Vue CLI:快速搭建Vue项目的利器
Vue CLI是Vue官方提供的全局命令工具,能够帮助我们快速创建一个开发Vue项目的标准化基础架子,集成了webpack配置,具有诸多优势。
-
使用步骤
-
全局安装:通过
yarn global add @vue/cli
或npm i @vue/cli -g
进行全局安装,此操作只需执行一次。 -
查看版本:使用
vue --version
命令查看安装的Vue CLI版本。 -
创建项目架子:执行
vue create project-name
(项目名不能使用中文)命令创建项目,该命令会引导用户进行一系列项目配置,生成一个标准化的Vue项目结构。 -
启动项目:使用
yarn serve
或npm run serve
命令启动项目,这会根据package.json
中的配置启动开发服务器,自动打开浏览器并展示项目页面。
-
-
目录文件介绍
node_modules
:存放项目的第三方依赖包。public
:放置html文件,index.html
是网站的模板文件,favicon.ico
是网站图标。src
:源代码目录,是后续编写代码的主要文件夹。其中,assets
用于存放静态资源,如图片、字体等;components
用于存放通用组件;App.vue
是根组件,项目运行看到的内容在此编写;main.js
是入口文件,打包或运行时第一个执行的文件,其核心代码如下:
import Vue from 'vue' // 导入Vue
import App from './App.vue' // 导入App.vue
new Vue({
render: h => h(App),
}).$mount('#app') // 实例化Vue,将App.vue渲染到index.html容器中
- 其他文件如`.gitignore`是git忽视文件,`babel.config.js`是babel配置文件,`jsconfig.json`是js配置文件,`package.json`包含项目名、版本号、scripts、依赖包等信息,`README.md`是项目说明文档,`vue.config.js`是vue-cli配置文件,`yarn.lock`是yarn锁文件,用于锁定安装版本。
四、组件化开发
(一)组件化的概念与优势
组件化是将一个页面拆分成一个个独立的组件,每个组件都有自己独立的结构、样式和行为。组件化的好处在于便于维护和复用,极大地提升了开发效率。组件可分为普通组件和根组件。根组件是整个应用最上层的组件,包裹所有普通小组件,如App.vue
通常就是根组件。
(二)组件的注册方式
- 局部注册:只能在注册的组件内使用。首先需要创建
.vue
文件,包含template
(结构,有且只能有一个根元素)、script
(js逻辑)、style
(样式,支持less
,需安装less
和less-loader
相关依赖)三个部分。然后在使用该组件的父组件内导入并注册,示例如下:
// 导入需要注册的组件
import HmHeader from './components/HmHeader'
export default {
components: {
// 局部注册,键值对形式,键为组件名,值为组件对象
HmHeader: HmHeader
}
}
- 全局注册:所有组件内都能使用。同样先创建
.vue
组件,然后在main.js
中进行全局注册 ,代码如下:
import HmButton from './components/HmButton'
Vue.component('HmButton', HmButton)
注册后,在任何组件中都可像使用HTML标签一样使用该组件<HmButton></HmButton>
。一般优先使用局部注册,当发现组件确实具有通用性时,再将其定义到全局。
五、综合案例:小兔鲜首页
今天我要和大家分享一下我在开发小兔鲜儿电商页面时的经验,我们将深入探讨如何使用 Vue 进行组件化开发,将一个完整的页面拆分成多个可维护、可复用的组件,从而让代码更加清晰、易于管理。让我们逐步分析这个页面的开发过程,看看如何通过组件化来实现一个功能丰富的电商页面。
一、页面结构与功能概述
小兔鲜儿电商页面包含了多个功能模块,如快捷链接、头部导航、轮播区域、新鲜好物展示、热门品牌展示、最新专题以及版权底部等。为了使代码结构更加清晰,我们将按照功能模块把页面拆分成多个组件,以便更好地管理和维护。
二、组件拆分与实现
(一)快捷链接组件 XtxShortCut
代码示例:
<template>
<div class="shortcut">
<div class="wrapper">
<ul>
<li><a href="#" class="login">请先登录</a></li>
<li><a href="#">免费注册</a></li>
<li><a href="#">我的订单</a></li>
<li><a href="#">会员中心</a></li>
<li><a href="#">帮助中心</a></li>
<li><a href="#">在线客服</a></li>
<li>
<a href="#"
><span class="iconfont icon-mobile-phone"></span>手机版</a
>
</li>
</ul>
</div>
</div>
</template>
<script>
export default {
// 在这里可以添加组件的逻辑,例如数据、方法、生命周期钩子等
}
</script>
<style>
/* 为快捷链接组件添加样式 */
.shortcut {
/* 你可以添加相应的样式,这里只是示例 */
}
.shortcut ul {
list-style: none;
display: flex;
justify-content: flex-end;
padding: 10px 0;
}
.shortcut li {
margin: 0 10px;
}
</style>
功能说明:
快捷链接组件 XtxShortCut
提供了一些用户常用的快捷操作链接,如登录、注册、订单查看、客服等。通过将其拆分为一个独立的组件,我们可以方便地在页面的不同位置复用该组件,或者对其样式和功能进行独立修改而不影响其他部分。
(二)顶部导航组件 XtxHeaderNav
代码示例:
<template>
<div class="header wrapper">
<!-- logo -->
<div class="logo">
<h1>
<a href="#">小兔鲜儿</a>
</h1>
</div>
<!-- 导航 -->
<div class="nav">
<ul>
<li><a href="#">首页</a></li>
<li><a href="#">生鲜</a></li>
<li><a href="#">美食</a></li>
<li><a href="#">餐厨</a></li>
<li><a href="#">电器</a></li>
<li><a href="#">居家</a></li>
<li><a href="#">洗护</a></li>
<li><a href="#">孕婴</a></li>
<li><a href="#">服装</a></li>
</ul>
</div>
<!-- 搜索 -->
<div class="search">
<span class="iconfont icon-search"></span>
<input type="text" placeholder="搜一搜" />
</div>
<!-- 购物车 -->
<div class="cart">
<span class="iconfont icon-cart-full"></span>
<i>2</i>
</div>
</div>
</template>
<script>
export default {
// 可以在这里添加组件的逻辑,如处理搜索功能等
}
</script>
<style>
/* 为顶部导航组件添加样式 */
.header {
display: flex;
align-items: center;
justify-content: space-between;
height: 80px;
background-color: #fff;
padding: 0 20px;
}
.header.logo {
font-size: 24px;
}
.header.nav ul {
display: flex;
list-style: none;
}
.header.nav li {
margin: 0 15px;
}
.header.search input {
padding: 5px 10px;
border: 1px solid #ccc;
border-radius: 5px;
}
.header.cart {
position: relative;
}
.header.cart i {
position: absolute;
top: -10px;
right: -10px;
background-color: red;
color: white;
border-radius: 50%;
padding: 3px 6px;
font-size: 12px;
}
</style>
功能说明:
顶部导航组件 XtxHeaderNav
包含了网站的 logo、主要导航菜单、搜索框和购物车图标等元素。这个组件可以被视为页面的头部,负责用户的导航和搜索操作。将其作为独立组件,有助于实现导航菜单的灵活管理和样式调整。
(三)轮播区域组件 XtxCarousel
代码示例:
<template>
<div class="banner">
<div class="wrapper">
<!-- 图 -->
<ul class="pic">
<li>
<a href="#"><img src="@/assets/images/banner1.png" alt="" /></a>
</li>
<li>
<a href="#"><img src="@/assets/images/banner1.png" alt="" /></a>
</li>
</ul>
<!-- 侧导航 -->
<div class="subnav">
<ul>
<li>
<div>
<span><a href="#">生鲜</a></span>
<span><a href="#">水果</a><a href="#">蔬菜</a></span>
</div>
<i class="iconfont icon-arrow-right-bold"></i>
</li>
<li>
<div>
<span><a href="#">美食</a></span>
<span><a href="#">面点</a><a href="#">干果</a></span>
</div>
<i class="iconfont icon-arrow-right-bold"></i>
</li>
<li>
<div>
<span><a href="#">餐厨</a></span>
<span><a href="#">数码产品</a></span>
</div>
<i class="iconfont icon-arrow-right-bold"></i>
</li>
<li>
<div>
<span><a href="#">电器</a></span>
<span
><a href="#">床品</a><a href="#">四件套</a
><a href="#">被枕</a></span
>
</div>
<i class="iconfont icon-arrow-right-bold"></i>
</li>
<li>
<div>
<span><a href="#">居家</a></span>
<span
><a href="#">奶粉</a><a href="#">玩具</a
><a href="#">辅食</a></span
>
</div>
<i class="iconfont icon-arrow-right-bold"></i>
</li>
<li>
<div>
<span><a href="#">洗护</a></span>
<span
><a href="#">洗发</a><a href="#">洗护</a
><a href="#">美妆</a></span
>
</div>
<i class="iconfont icon-arrow-right-bold"></i>
</li>
<li>
<div>
<span><a href="#">孕婴</a></span>
<span><a href="#">奶粉</a><a href="#">玩具</a></span>
</div>
<i class="iconfont icon-arrow-right-bold"></i>
</li>
<li>
<div>
<span><a href="#">服饰</a></span>
<span><a href="#">女装</a><a href="#">男装</a></span>
</div>
<i class="iconfont icon-arrow-right-bold"></i>
</li>
<li>
<div>
<span><a href="#">杂货</a></span>
<span><a href="#">户外</a><a href="#">图书</a></span>
</div>
<i class="iconfont icon-arrow-right-bold"></i>
</li>
<li>
<div>
<span><a href="#">品牌</a></span>
<span><a href="#">品牌制造</a></span>
</div>
<i class="iconfont icon-arrow-right-bold"></i>
</li>
</ul>
</div>
<!-- 指示器 -->
<ol>
<li class="current"><i></i></li>
<li><i></i></li>
<li><i></i></li>
</ol>
</div>
</div>
</template>
<script>
export default {
// 可以在这里添加轮播逻辑,如切换图片、处理指示器点击等
}
</script>
<style>
/* 为轮播区域组件添加样式 */
.banner {
position: relative;
overflow: hidden;
height: 300px;
}
.banner.pic {
display: flex;
list-style: none;
width: 300%;
height: 100%;
margin: 0;
padding: 0;
transition: transform 0.5s;
}
.banner.pic li {
flex: 1;
}
.banner.pic img {
width: 100%;
height: 100%;
object-fit: cover;
}
.banner.subnav {
position: absolute;
top: 0;
left: 0;
width: 200px;
background-color: rgba(255, 255, 255, 0.8);
height: 100%;
}
.banner.subnav ul {
list-style: none;
padding: 10px;
}
.banner.ol {
position: absolute;
bottom: 10px;
left: 50%;
transform: translateX(-50%);
display: flex;
list-style: none;
}
.banner.ol li {
width: 10px;
height: 10px;
border-radius: 50%;
background-color: #ccc;
margin: 0 5px;
}
.banner.ol li.current {
background-color: red;
}
</style>
功能说明:
轮播区域组件 XtxCarousel
是页面中非常重要的部分,用于展示广告或主推商品。该组件包含轮播图片、侧导航和指示器。我们可以将轮播的切换逻辑、指示器的交互逻辑都封装在这个组件中,实现组件内部的自洽。
(四)新鲜好物组件 XtxFreshGoods
代码示例:
<template>
<div class="goods wrapper">
<div class="title">
<div class="left">
<h3>新鲜好物</h3>
<p>新鲜出炉 品质靠谱</p>
</div>
<div class="right">
<a href="#" class="more"
>查看全部<span class="iconfont icon-arrow-right-bold"></span
></a>
</div>
</div>
<div class="bd">
<ul>
<li>
<a href="#">
<div class="pic"><img src="@/assets/images/goods1.png" alt="" /></div>
<div class="txt">
<h4>KN95级莫兰迪色防护口罩</h4>
<p>¥ <span>79</span></p>
</div>
</a>
</li>
<li>
<a href="#">
<div class="pic"><img src="@/assets/images/goods2.png" alt="" /></div>
<div class="txt">
<h4>KN95级莫兰迪色防护口罩</h4>
<p>¥ <span>566</span></p>
</div>
</a>
</li>
<li>
<a href="#">
<div class="pic"><img src="@/assets/images/goods3.png" alt="" /></div>
<div class="txt">
<h4>法拉蒙高颜值记事本可定制</h4>
<p>¥ <span>58</span></p>
</div>
</a>
</li>
<li>
<a href="#">
<div class="pic"><img src="@/assets/images/goods4.png" alt="" /></div>
<div class="txt">
<h4>科技布布艺沙发</h4>
<p>¥ <span>3759</span></p>
</div>
</a>
</li>
</ul>
</div>
</div>
</template>
<script>
export default {
// 可以添加处理商品点击等逻辑
}
</script>
<style>
/* 为新鲜好物组件添加样式 */
.goods {
margin-top: 20px;
}
.goods.title {
display: flex;
justify-content: space-between;
align-items: center;
}
.goods.bd ul {
display: flex;
list-style: none;
padding: 0;
}
.goods.bd li {
margin: 0 10px;
}
.goods.bd.pic img {
width: 100%;
}
.goods.txt {
text-align: center;
}
</style>
功能说明:
新鲜好物组件 XtxFreshGoods
用于展示一些推荐的新鲜好物,包括商品的图片、名称和价格。将其作为一个组件,方便后续进行商品数据的动态绑定和渲染,同时可以添加商品的点击跳转逻辑等。
(五)热门品牌组件 XtxHotBrands
代码示例:
<template>
<div class="hot">
<div class="wrapper">
<div class="title">
<div class="left">
<h3>热门品牌</h3>
<p>国际经典 品质认证</p>
</div>
<div class="button">
<a href="#"><i class="iconfont icon-arrow-left-bold"></i></a>
<a href="#"><i class="iconfont icon-arrow-right-bold"></i></a>
</div>
</div>
<div class="bd">
<ul>
<li>
<a href="#">
<img src="@/assets/images/hot1.png" alt="" />
</a>
</li>
<li>
<a href="#">
<img src="@/assets/images/hot2.png" alt="" />
</a>
</li>
<li>
<a href="#">
<img src="@/assets/images/hot3.png" alt="" />
</a>
</li>
<li>
<a href="#">
<img src="@/assets/images/hot4.png" alt="" />
</a>
</li>
<li>
<a href="#">
<img src="@/assets/images/hot5.png" alt="" />
</a>
</li>
</ul>
</div>
</div>
</template>
<script>
export default {
// 可以添加左右切换品牌的逻辑
}
</script>
<style>
/* 为热门品牌组件添加样式 */
.hot {
margin-top: 20px;
}
.hot.title {
display: flex;
justify-content: space-between;
align-items: center;
}
.hot.bd ul {
display: flex;
list-style: none;
overflow: hidden;
padding: 0;
}
.hot.bd li {
margin: 0 10px;
}
.hot.bd img {
width: 100px;
}
</style>
功能说明:
功能说明:
热门品牌组件 XtxHotBrands
用于展示一系列热门品牌的图片,为用户提供品牌信息。这里可以添加左右切换品牌的逻辑,比如通过点击左右箭头按钮实现品牌列表的滚动或切换,以展示更多的品牌信息。
(六)最新专题组件 XtxLatestTopics
代码示例:
<template>
<div class="topic wrapper">
<div class="title">
<div class="left">
<h3>最新专题</h3>
</div>
<div class="right">
<a href="#" class="more"
>查看全部<span class="iconfont icon-arrow-right-bold"></span
></a>
</div>
</div>
<div class="topic_bd">
<ul>
<li>
<a href="#">
<div class="pic">
<img src="@/assets/images/topic1.png" alt="" />
<div class="info">
<div class="left">
<h5>吃这些美食才不算辜负自己</h5>
<p>餐厨起居洗护好物</p>
</div>
<div class="right">¥<span>29.9</span>起</div>
</div>
</div>
<div class="txt">
<div class="left">
<p>
<span class="iconfont icon-favorites-fill red"></span>
<i>1200</i>
</p>
<p>
<span class="iconfont icon-browse"></span>
<i>1800</i>
</p>
</div>
<div class="right">
<span class="iconfont icon-comment"></span>
<i>246</i>
</div>
</div>
</a>
</li>
<li>
<a href="#">
<div class="pic">
<img src="@/assets/images/topic2.png" alt="" />
<div class="info">
<div class="left">
<h5>吃这些美食才不算辜负自己</h5>
<p>餐厨起居洗护好物</p>
</div>
<div class="right">¥<span>29.9</span>起</div>
</div>
</div>
<div class="txt">
<div class="left">
<p>
<span class="iconfont icon-fabulous"></span>
<i>1200</i>
</p>
<p>
<span class="iconfont icon-browse"></span>
<i>1800</i>
</p>
</div>
<div class="right">
<span class="iconfont icon-comment"></span>
<i>246</i>
</div>
</div>
</a>
</li>
<li>
<a href="#">
<div class="pic">
<img src="@/assets/images/topic3.png" alt="" />
<div class="info">
<div class="left">
<h5>吃这些美食才不算辜负自己</h5>
<p>餐厨起居洗护好物</p>
</div>
<div class="right">¥<span>29.9</span>起</div>
</div>
</div>
<div class="txt">
<div class="left">
<p>
<span class="iconfont icon-fabulous"></span>
<i>1200</i>
</p>
<p>
<span class="iconfont icon-browse"></span>
<i>1800</i>
</p>
</div>
<div class="right">
<span class="iconfont icon-comment"></span>
<i>246</i>
</div>
</div>
</a>
</li>
</ul>
</div>
</div>
</template>
<script>
export default {
// 可以添加专题相关的逻辑,例如点击查看更多详情等
}
</script>
<style>
/* 为最新专题组件添加样式 */
.topic {
margin-top: 20px;
}
.topic.title {
display: flex;
justify-content: space-between;
align-items: center;
}
.topic.topic_bd ul {
list-style: none;
padding: 0;
}
.topic.topic_bd li {
margin-bottom: 20px;
}
.topic.topic_bd.pic {
position: relative;
}
.topic.topic_bd.pic img {
width: 100%;
}
.topic.topic_bd.info {
position: absolute;
bottom: 0;
left: 0;
background-color: rgba(255, 255, 255, 0.8);
width: 100%;
padding: 10px;
}
.topic.txt {
display: flex;
justify-content: space-between;
}
</style>
功能说明:
最新专题组件 XtxLatestTopics
展示了一些最新的专题信息,包含专题图片、价格信息以及一些统计数据(如收藏数、浏览数、评论数等)。将其作为一个独立组件,可以方便后续对专题数据的更新和样式调整。
(七)版权底部组件 XtxFooter
代码示例:
<template>
<div class="footer">
<div class="wrapper">
<div class="service">
<ul>
<li>
<span></span>
<p>价格亲民</p>
</li>
<li>
<span></span>
<p>物流快捷</p>
</li>
<li>
<span></span>
<p>品质新鲜</p>
</li>
<li>
<span></span>
<p>售后无忧</p>
</li>
</ul>
</div>
<div class="help">
<div class="left">
<dl>
<dt>购物指南</dt>
<dd><a href="#">购物流程</a></dd>
<dd><a href="#">支付方式</a></dd>
<dd><a href="#">售后规则</a></dd>
</dl>
<dl>
<dt>配送方式</dt>
<dd><a href="#">配送运费</a></dd>
<dd><a href="#">配送范围</a></dd>
<dd><a href="#">配送时间</a></dd>
</dl>
<dl>
<dt>关于我们</dt>
<dd><a href="#">平台规则</a></dd>
<dd><a href="#">联系我们</a></dd>
<dd><a href="#">问题反馈</a></dd>
</dl>
<dl>
<dt>售后服务</dt>
<dd><a href="#">售后政策</a></dd>
<dd><a href="#">退款说明</a></dd>
<dd><a href="#">取消订单</a></dd>
</dl>
<dl>
<dt>服务热线</dt>
<dd>
<a href="#"
>在线客服<span class="iconfont icon-customer-service"></span
></a>
</dd>
<dd><a href="#">客服电话 400-0000-000</a></dd>
<dd><a href="#">工作时间 周一至周日 8:00-18:00</a></dd>
</dl>
</div>
<div class="right">
<ul>
<li>
<div><img src="@/assets/images/wechat.png" alt="" /></div>
<p>微信公众号</p>
</li>
<li>
<div><img src="@/assets/images/app.png" alt="" /></div>
<p>APP下载二维码</p>
</li>
</ul>
</div>
</div>
<div class="copyright">
<p>
<a href="#">关于我们</a>|<a href="#">帮助中心</a>|<a href="#"
>售后服务</a
>|<a href="#">配送与验收</a>|<a href="#">商务合作</a>|<a href="#"
>搜索推荐</a
>|<a href="#">友情链接</a>
</p>
<p>CopyRight © 小兔鲜</p>
</div>
</div>
</div>
</template>
<script>
export default {
// 可以添加底部功能的逻辑,例如点击客服联系、点击下载APP等
}
</script>
<style>
/* 为版权底部组件添加样式 */
.footer {
margin-top: 20px;
background-color: #f5f5f5;
padding: 20px;
}
.footer.service ul {
display: flex;
list-style: none;
justify-content: center;
}
.footer.service li {
margin: 0 20px;
}
.footer.help {
display: flex;
justify-content: space-between;
}
.footer.help dl {
margin-right: 30px;
}
.footer.help dd {
margin-bottom: 5px;
}
.footer.right ul {
list-style: none;
}
.footer.right li {
margin-bottom: 10px;
}
.footer.copyright {
text-align: center;
margin-top: 20px;
}
</style>
功能说明:
版权底部组件 XtxFooter
包含了服务信息、帮助信息、客服信息、版权信息等,将其作为一个组件,方便后期维护和更新,同时也使页面结构更加清晰,将不同功能模块分离。
三、组件的注册方式
(一)局部注册
在 Vue 中,我们可以在需要使用组件的父组件中进行局部注册。假设我们在 App.vue
中使用上述拆分出来的组件,代码如下:
<template>
<div class="App">
<XtxShortCut></XtxShortCut>
<XtxHeaderNav></XtxHeaderNav>
<XtxCarousel></XtxCarousel>
<XtxFreshGoods></XtxFreshGoods>
<XtxHotBrands></XtxHotBrands>
<XtxLatestTopics></XtxLatestTopics>
<XtxFooter></XtxFooter>
</div>
</template>
<script>
import XtxShortCut from './components/XtxShortCut.vue';
import XtxHeaderNav from './components/XtxHeaderNav.vue';
import XtxCarousel from './components/XtxCarousel.vue';
import XtxFreshGoods from './components/XtxFreshGoods.vue';
import XtxHotBrands from './components/XtxHotBrands.vue';
import XtxLatestTopics from './components/XtxLatestTopics.vue';
import XtxFooter from './components/XtxFooter.vue';
export default {
components: {
XtxShortCut,
XtxHeaderNav,
XtxCarousel,
XtxFreshGoods,
XtxHotBrands,
XtxLatestTopics,
XtxFooter
}
};
</script>
<style>
/* 可以在这里添加 App.vue 的全局样式 */
</style>
代码解释:
- 在
<script>
部分,我们使用import
语句导入各个组件。 - 在
components
对象中,以键值对的形式注册这些组件,键为组件名,值为导入的组件对象。这样就完成了组件的局部注册,这些组件只能在App.vue
中使用。
(二)全局注册
如果我们希望某些组件在整个应用中都能使用,可以进行全局注册。一般在 main.js
中进行全局注册,代码如下:
import Vue from 'vue';
import App from './App.vue';
import XtxShortCut from './components/XtxShortCut.vue';
import XtxHeaderNav from './components/XtxHeaderNav.vue';
import XtxCarousel from './components/XtxCarousel.vue';
Vue.component('XtxShortCut', XtxShortCut);
Vue.component('XtxHeaderNav', XtxHeaderNav);
Vue.component('XtxCarousel', XtxCarousel);
new Vue({
render: (createElement) => {
return createElement(App);
}
}).$mount('#app');
代码解释:
- 使用
Vue.component('组件名', 组件对象)
方法将组件注册为全局组件。 - 这样,在任何 Vue 组件中,都可以直接使用这些组件,无需再次导入和注册,例如
<XtxShortCut></XtxShortCut>
。
四、总结
通过将小兔鲜儿电商页面拆分成多个组件,我们可以清晰地看到每个组件的职责和功能,并且可以方便地进行局部或全局注册。组件化开发使得代码结构更加清晰,易于维护和扩展。在开发过程中,我们可以根据组件的复用性和使用范围选择合适的注册方式,局部注册适合在特定组件内使用的组件,而全局注册则适用于通用的组件。同时,在每个组件的 .vue
文件中,我们可以独立管理模板、逻辑和样式,提高了开发效率和代码的可维护性。你可以根据实际需求,为每个组件添加更多的功能和交互逻辑,让小兔鲜儿页面更加丰富和完善。
希望这篇博客能帮助你更好地理解 Vue 的组件化开发过程,如果你有任何问题或想法,欢迎随时和我交流哦 你也可以尝试添加更多的功能,如用户登录、购物车功能、商品详情页等,让这个电商项目更加完善。
在开发过程中,我们可以根据页面的设计图,将每个部分都细化为一个组件,然后通过 Vue 的组件化开发能力,将它们有机地组合在一起,形成一个完整的页面。这不仅能提高代码的可读性,还能让我们在开发大型项目时更加得心应手。
script>部分,我们使用
import` 语句导入各个组件。
- 在
components
对象中,以键值对的形式注册这些组件,键为组件名,值为导入的组件对象。这样就完成了组件的局部注册,这些组件只能在App.vue
中使用。
(二)全局注册
如果我们希望某些组件在整个应用中都能使用,可以进行全局注册。一般在 main.js
中进行全局注册,代码如下:
import Vue from 'vue';
import App from './App.vue';
import XtxShortCut from './components/XtxShortCut.vue';
import XtxHeaderNav from './components/XtxHeaderNav.vue';
import XtxCarousel from './components/XtxCarousel.vue';
Vue.component('XtxShortCut', XtxShortCut);
Vue.component('XtxHeaderNav', XtxHeaderNav);
Vue.component('XtxCarousel', XtxCarousel);
new Vue({
render: (createElement) => {
return createElement(App);
}
}).$mount('#app');
代码解释:
- 使用
Vue.component('组件名', 组件对象)
方法将组件注册为全局组件。 - 这样,在任何 Vue 组件中,都可以直接使用这些组件,无需再次导入和注册,例如
<XtxShortCut></XtxShortCut>
。
四、总结
通过将小兔鲜儿电商页面拆分成多个组件,我们可以清晰地看到每个组件的职责和功能,并且可以方便地进行局部或全局注册。组件化开发使得代码结构更加清晰,易于维护和扩展。在开发过程中,我们可以根据组件的复用性和使用范围选择合适的注册方式,局部注册适合在特定组件内使用的组件,而全局注册则适用于通用的组件。同时,在每个组件的 .vue
文件中,我们可以独立管理模板、逻辑和样式,提高了开发效率和代码的可维护性。你可以根据实际需求,为每个组件添加更多的功能和交互逻辑,让小兔鲜儿页面更加丰富和完善。
希望这篇博客能帮助你更好地理解 Vue 的组件化开发过程,如果你有任何问题或想法,欢迎随时和我交流哦 你也可以尝试添加更多的功能,如用户登录、购物车功能、商品详情页等,让这个电商项目更加完善。
在开发过程中,我们可以根据页面的设计图,将每个部分都细化为一个组件,然后通过 Vue 的组件化开发能力,将它们有机地组合在一起,形成一个完整的页面。这不仅能提高代码的可读性,还能让我们在开发大型项目时更加得心应手。