Vue入门3.0:Vue组件化实战开发

459 阅读7分钟

前言

我们本篇文章带大家一起完成一次vue的组件化开发。在阅读本篇文章前还请阅读

vue入门1.0vue入门2.0,看完之后再看本篇文章,相信对vue的理解一定会更上一层楼!

什么是组件化开发

Vue 的组件化开发是一种软件工程实践,它将应用程序分解为多个独立的、可重用的组件,每个组件封装了自己的模板(HTML)、逻辑(JavaScript)和样式(CSS)。这种方法不仅有助于代码的组织和维护,还能够提高开发效率和代码的可读性。

1. 什么是组件?

在 Vue 中,组件是一个拥有预定义选项的 Vue 实例。组件可以包含以下部分:

  • 模板(Template):定义组件的 HTML 结构。
  • 脚本(Script):定义组件的逻辑,如数据、方法和生命周期钩子。
  • 样式(Style):定义组件的样式。

2. 为什么使用组件化开发?

  • 复用性:组件可以在多个地方重复使用,减少代码重复。
  • 模块化:将复杂的应用划分为小块,使代码更容易理解和维护。
  • 独立性:组件之间相对独立,修改一个组件不会影响其他组件,降低了出错的风险。
  • 可测试性:组件可以单独测试,提高了代码的可测试性和稳定性。

准备工作

我们先给大家看一下我们这次的完成效果

image.png

image.png

我们这次要完成两个页面一个是购物车,一个是todos,当然页面是以我们手动点击来切换的。

建立目录

image.png

因为我们是做vue的组件化开发,因此我们在src的下一级建立components文件夹,里面存放我们的两大页面。

<template>
    <div class="app">
      <button class="btn" @click="changeTab(1)">购物车</button>
      <button class="btn" @click="changeTab(2)">todos</button>
  
      <!-- shopping -->
      <Shopping v-if="tabIndex === 1"></Shopping>
      <!-- todos -->
      <Todos v-else></Todos>
  
    </div>
  </template>
  
  <script setup>
  import { ref } from 'vue'
  import Shopping from './components/Shopping.vue'
  import Todos from './components/Todos.vue'
  
  let tabIndex = ref(1)
  
  const changeTab = (index) => {
    // console.log(index);
    tabIndex.value = index
  }
  
  </script>
  
  <style lang="css" scoped>
  .app{
    text-align: center;
  }
  .btn{
    font-size: 20px;
    width: 100px;
    height: 40px;
    margin: 20px;
  }
  </style>

这段代码是一个基于 Vue 3 的组件,它包含了两个按钮和两个子组件 ShoppingTodos。当点击按钮时,会根据按钮的索引值来切换显示不同的子组件。

<template> 部分,定义了两个按钮,分别绑定了点击事件 changeTab(1)changeTab(2),用来切换显示不同的子组件。

<script setup> 部分,使用了 Composition API 中的 ref 来创建了名为 tabIndex 的响应式数据,并定义了 changeTab 方法,用于改变 tabIndex 的值,从而控制显示的子组件。

<style> 部分,定义了组件的样式,其中使用了 scoped 关键字,表示这些样式只对当前组件有效。

我们的App.vue直接引入这两个我们写的vue项目,然后直接放在我们的html中,我们该如何去控制两个页面只显示一个呢?这就要用到我们的v-if了,配合v-else使用,最后看判断逻辑。我们首先将tabIndex设置为1,然后给;购物车和todos按钮绑定点击事件,我们可以绑定相同的事件然后后面接一个参数,这样我们点击购物车tabindex就变成1,点击todostabindex就变成2,也就达到了我们想要的显示效果。然后我们写一些简单的css去进行修饰。

这是我们组件化开发的第一步,也是很重要的一步!

Shopping

<div class="shopping">
  
      <table>
        <thead>
          <th>序号</th>
          <th>书籍名称</th>
          <th>出版日期</th>
          <th>价格</th>
          <th>购买数量</th>
          <th>操作</th>
        </thead>
        <tbody>
          <tr v-for="(book, index) in books">
            <td>{{index + 1}}</td>
            <td>{{book.name}}</td>
            <td>{{book.date}}</td>
            <td>{{book.price}}</td>
            <td>{{book.count}}</td>
            <td>
              <button :disabled="book.count <= 0" @click="decrementCount(index)">-</button>
              <span class="counter">{{book.count}}</span>
              <button @click="addCount(index)">+</button>
            </td>
          </tr>
        </tbody>
      </table>
      <h3>总价格:{{totalPrice}}</h3>
    </div>

在模板中,使用了一个表格来展示书籍的信息,包括序号、书籍名称、出版日期、价格、购买数量和操作按钮。

v-for="(book, index) in books" 中对 books 数组进行遍历,然后将书籍的信息逐一展示在表格的每一行中。通过 {{index + 1}} 可以显示书籍的序号,而 {{book.name}}{{book.date}}{{book.price}}{{book.count}} 则分别显示了书籍的名称、出版日期、价格和购买数量。

在操作列中,每一行都有两个按钮,一个用于减少购买数量,另一个用于增加购买数量。通过 @click="decrementCount(index)"@click="addCount(index)" 来绑定点击事件,当点击对应的按钮时,会触发相应的方法来增加或减少书籍的购买数量。

最后,使用 {{totalPrice}} 来显示所有书籍的总价格。

我们首先看html部分,我们可以发现主要由2部分组成,table表和总价格。我们的表里面有六列,然后后序的步骤我们结合后面的js一起讲。

<script setup>
  import { reactive, computed } from "vue";
  const books = reactive(书籍信息数组)
  
  const totalPrice = computed(() => {
    let total = 0
    books.forEach(item => {
      total += item.price * item.count
    });
    return total
  })
  
  const addCount = (index) => {
    // console.log(index);
    books[index].count++
  }
  const decrementCount = (index) => {
    books[index].count--
  }
  
  </script>

这段代码是使用 Vue 3 的 <script setup> 语法编写的组件逻辑部分,它包括导入了 Vue 中的 reactivecomputed 函数,并且利用这两个函数创建了一个响应式的 books 对象和一个计算属性 totalPrice。其中 books 存储了书籍的信息数组,而 totalPrice 用于计算所有书籍的总价格。另外还定义了两个函数 addCountdecrementCount,用于增加和减少某本书籍的购买数量。这样的设计能够让视图自动响应数据的变化,从而实现了一个简单的购物车功能。

我们首先引入我们需要的reactive构造可以响应的变量,然后computed用来返回值,这个js里头可有大学问!首先我们看我们的增加和删除函数,都是绑定在了html的按钮里面,当我们点击时,我们可以根据所传入的下标找到这本书,并且将数量加1或者减1。但是当减为0时,我们就要将其设置为禁止按钮,这里我们直接采用v-bind去绑定属性缩写为:进行数量的判断。

我们再来讲解我们的计算总数部分computed,我们去遍历books的每一项返回最终的count累加值。并将其赋值给totalprice。

我们还通过v-for来循环生成了我们的表格。

  <style lang="css" scoped>

  
  table {
    margin: 0 auto;
    border: 1px solid #e9e9e9;
    border-collapse: collapse;
    border-spacing: 0;
  }
  
  th,
  td {
    padding: 8px 16px;
    border: 1px solid #e9e9e9;
  }
  
  .counter {
    margin: 0 5px;
  }
  </style>

然后是我们一些简单的css修饰。

Todos

我们首先 npm i todomvc-app-css,引入好用的css库。

  1. 最外层的 <section> 元素:

    <section class="todoapp">
    
    • 这是应用的根容器,包含了整个 Todo 应用的所有元素。
  2. 头部 <header> 元素:

    <header class="header">
      <h1>todos</h1>
      <input type="text" class="new-todo" placeholder="想干的事" @keyup.enter="addTodo">
    </header>
    
    • 这里定义了应用的头部部分。
    • <h1> 标签显示了应用的标题 "todos"。
    • <input> 输入框用于添加新的待办事项,@keyup.enter="addTodo" 指令表示当用户按下回车键时,会调用 addTodo 方法(这个方法应该在组件的逻辑部分定义)。
  3. 主要内容 <section class="main">

    <section class="main">
      <input type="checkbox" class="toggle-all" id="toggle-all">
      <label for="toggle-all">Mark all as complete</label>
    
    • 这里是主要的待办事项列表区域。
    • <input type="checkbox"> 复选框用于标记所有任务为完成状态。
    • <label for="toggle-all">Mark all as complete</label> 是复选框的标签。
  4. 待办事项列表 <ul> 元素:

    <ul class="todo-list">
      <li class="todo" v-for="todo in state.todos">
        <div class="view">
          <input type="checkbox" class="toggle" v-model="todo.completed">
          <label>{{todo.title}}</label>
          <button class="destroy"></button>
        </div>
      </li>
    </ul>
    
    • <ul class="todo-list"> 是一个无序列表,用于展示所有的待办事项。

    • 使用了 Vue 的 v-for 指令来遍历 state.todos 数组,并为每个待办事项创建一个 <li> 元素。

      • state.todos 应该是一个包含所有待办事项的数组对象,在组件的逻辑部分定义。
    • 每个待办事项项包含:

      • 一个复选框 <input type="checkbox" class="toggle" v-model="todo.completed">,通过 v-model 双向绑定到 todo.completed 属性,用于标记任务是否完成。
      • 一个 <label> 显示待办事项的标题 {{todo.title}}
      • 一个删除按钮 <button class="destroy"></button>,用于删除该待办事项(具体的删除逻辑需要在组件的逻辑部分定义)。
  5. 导入 reactive 函数

    import { reactive } from 'vue'
    
    • 从 Vue 中导入 reactive 函数,用于创建响应式状态对象。
  6. 定义 state 对象

    const state = reactive({
      todos: [
        { id: 1, title: '学习', completed: false },
        { id: 2, title: '吃饭', completed: true },
      ]
    })
    
    • 使用 reactive 函数创建一个响应式对象 state
    • state 对象包含一个 todos 数组,数组中有两个默认的待办事项对象,每个对象包含 idtitle 和 completed 属性。