当前位置: 首页 > article >正文

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实例从创建到销毁的整个过程,这一过程可分为四个阶段:创建、挂载、更新和销毁。

(一)生命周期的四个阶段

  1. 创建阶段:在这个阶段,Vue实例开始创建,会进行响应式数据的初始化等操作。虽然此时数据已准备好,但DOM尚未渲染,无法进行DOM操作。例如在创建一个计数器的实例时:
data: {
  title: '计数器',
  count: 100
}

在创建阶段,titlecount 数据被初始化,但我们无法直接操作DOM元素来显示它们。
2. 挂载阶段:Vue会将模板渲染成真实的DOM,此时可以开始操作DOM。如在新闻列表案例中,当模板渲染完成后,我们可以获取新闻列表的DOM元素并进行一些初始化操作 ,mounted 钩子函数会在这个阶段被调用。
3. 更新阶段:当响应式数据发生变化时,Vue会自动更新视图。在这个阶段,数据的修改会触发视图的重新渲染,以保证数据与视图的一致性。
4. 销毁阶段:Vue实例被销毁,此时可以进行一些资源的释放操作,比如清除定时器、延时器等。在 destroyed 钩子函数中执行这些操作,确保应用在销毁时不会留下无效的资源占用。

(二)生命周期钩子函数

Vue在生命周期的各个阶段会自动运行一些函数,称为生命周期钩子函数,这让开发者能够在特定阶段运行自己的代码。

  1. created:在数据准备好后调用,适合发送初始化渲染请求。在小黑记账清单案例中,可在这个钩子函数中请求数据,并将数据更新给 data,实现数据的动态渲染。
created() {
  // 发送初始化数据请求,假设这里使用axios库
  axios.get('your-api-url').then((response) => {
    this.data = response.data;
  });
}
  1. 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>

就可以使输入框具有自动聚焦的功能

image-20250114104742061

二、综合案例:小黑记账清单

项目概述

我们要实现的小黑记账清单是一个简单的财务管理应用,用户可以在页面上添加账单,查看账单列表,删除账单,并通过饼图直观地展示消费分布情况。下面我们将详细分析每个功能的实现细节。

项目代码结构

(一)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 方法重新获取列表数据,确保列表及时更新。

    image-20250114194824181

4. 饼图渲染
  • mounted 生命周期钩子函数中,使用 echarts.init(document.querySelector('#main')) 初始化 Echarts 实例。

  • 首先设置了一个初始的饼图选项,包含一些默认数据。

  • getList 方法中,当获取到账单列表数据后,使用 this.list.map(item => ({ value: item.price, name: item.name })) 将账单数据映射为 Echarts 所需的数据格式,并通过 setOption 方法更新饼图数据,实现了饼图的动态更新。

    image-20250114194834536

总结

这个小黑记账清单项目展示了 Vue 如何与后端 API 进行交互,并通过 Vue 的响应式数据绑定、生命周期钩子函数和计算属性等特性实现了一个功能完整的应用。我们通过 v-for 指令实现列表的动态渲染,使用 axios 进行数据的获取、添加和删除操作,以及利用 Echarts 实现了饼图的动态更新。在开发过程中,要注意 v-model 的使用,它能方便地实现表单元素与数据的双向绑定;同时,使用 async/await 让异步操作的代码更加简洁和易读。另外,处理请求时的错误捕获和异常处理也非常重要,可以帮助我们更好地调试和优化应用。

三、工程化开发入门

(一)开发Vue的两种方式

  1. 核心包传统开发模式:基于html、css、js文件,直接引入核心包进行Vue开发。这种方式适用于小型、简单的项目,但对于复杂项目,其配置和管理可能较为繁琐。
  2. 工程化开发模式:基于构建工具(如webpack)的环境中开发Vue。虽然这种方式功能强大,但webpack的配置较为复杂,缺乏统一标准。于是,Vue CLI应运而生。

(二)Vue CLI:快速搭建Vue项目的利器

Vue CLI是Vue官方提供的全局命令工具,能够帮助我们快速创建一个开发Vue项目的标准化基础架子,集成了webpack配置,具有诸多优势。

  1. 使用步骤

    • 全局安装:通过yarn global add @vue/clinpm i @vue/cli -g进行全局安装,此操作只需执行一次。

    • 查看版本:使用vue --version命令查看安装的Vue CLI版本。

      image-20250114195548054

    • 创建项目架子:执行vue create project-name(项目名不能使用中文)命令创建项目,该命令会引导用户进行一系列项目配置,生成一个标准化的Vue项目结构。

    • 启动项目:使用yarn servenpm run serve命令启动项目,这会根据package.json中的配置启动开发服务器,自动打开浏览器并展示项目页面。

  2. 目录文件介绍

    image-20250114195624750

    • 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通常就是根组件。

(二)组件的注册方式

  1. 局部注册:只能在注册的组件内使用。首先需要创建.vue文件,包含template(结构,有且只能有一个根元素)、script(js逻辑)、style(样式,支持less,需安装lessless-loader相关依赖)三个部分。然后在使用该组件的父组件内导入并注册,示例如下:
// 导入需要注册的组件
import HmHeader from './components/HmHeader' 
export default {
  components: {
    // 局部注册,键值对形式,键为组件名,值为组件对象
    HmHeader: HmHeader 
  }
}
  1. 全局注册:所有组件内都能使用。同样先创建.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 的组件化开发能力,将它们有机地组合在一起,形成一个完整的页面。这不仅能提高代码的可读性,还能让我们在开发大型项目时更加得心应手。


http://www.kler.cn/a/506751.html

相关文章:

  • 【C语言】_字符串拷贝函数strcpy
  • 配置AOSP下载环境
  • PT8M2302 触控 A/D 型 8-Bit MCU
  • Elasticsearch:Jira 连接器教程第一部分
  • 从网络的角度来看,用户输入网址到网页显示,期间发生了什么?
  • 初识 Git——《Pro Git》
  • @Query(org.springframework.data.jpa.repository.Query)
  • HTTP 到 HTTPS – 以下是操作步骤
  • 【Java设计模式-5】装饰模式:给咖啡加点“佐料”
  • 海太长江隧道:科技防水筑就跨江新通道
  • 卷积神经04-TensorFlow环境安装
  • Dexie.js 的批量操作与索引优化
  • 《深度学习神经网络训练:数据集下载资源列表》
  • 使用Eclipse将Springboot项目打jar包
  • GPU算力平台|在GPU算力平台部署轻量级中文OCR项目(chineseocr_lite)
  • 机器学习-学习算法
  • java实现word转html(支持docx及doc文件)
  • 常见的安全测试漏洞详解
  • VLANIF配置之区别(Differences in VLANIF Configuration)
  • 高德地图自定义点聚合样式
  • 数据结构-顺序表及链表结构分析
  • 【odbc】odbc连接kerberos认证的 hive和spark thriftserver
  • 矩阵Strassen 算法
  • C#异步编程:掌握上下文捕获,有效避免死锁
  • Navicat Premium 原生支持阿里云 PolarDB 数据库
  • EtherCAT PDO映射概述