likes
comments
collection
share

vue的组件化开发?一个小demo就带你掌握!

作者站长头像
站长
· 阅读数 25

什么是组件化思想

组件化思想来源于软件工程中的模块化和封装原则,让开发者能够将复杂的用户界面分解细化成一块块可复用的、独立的组件。每个组件负责一块功能,组件之间相互独立,并通过特定方式进行沟通联系,从而实现高内聚、低耦合。

demo需求

在同一个页面中,点击不同按钮展示不同的信息:当我点击“购物车”,下方展示我的购物清单;当我点击“todos”,下方展示我的待办事项。

分析可知整个项目应该拆解成三个模块:导航头、购物车信息和todos信息。考虑到代码的优雅性和复用性,我们应该将购物车信息和todos信息分别写成两个组件,而导航头的两个按钮始终在该页面上显示并为这两个组件共用,所以两个按钮就放在在根组件上。

代码实现

(本文案例只为展现组件化的使用方法,在实际应用中应当考虑模块的复用性和项目的可维护性,酌情组件化)

项目目录

components中写入购物车和todos的vue文件,App.vue为根组件

组件引入

① Shopping.vue和Todos.vue两个子组件暂时先简写成下面的形式以表明是两个不同子组件,详细代码内容先省略

<!-- Shopping.vue中 -->
<template>
    <div>shopping</div>
</template>
<!-- Todos.vue中 -->
<template>
    <div>todos</div>    
</template>

② 在根组件App.vue中引入和使用Shopping.vue和Todos.vue两个文件:

import Shopping from './components/Shopping.vue' 从指定路径导入Shopping.vue子组件,并定义为一个变量名Shopping; import Todos from './components/Todos.vue同理;

并在HTML结构中使用两个组件标签<Shopping><Todos>,它们将被替换为对应的组件实例。

<template>
    <div class="app">
        <button class="btn">购物车</button>
        <button class="btn">todos</button>

        <Shopping></Shopping>

        <Todos></Todos>
    </div>
</template>

<script setup>
  import Shopping from './components/Shopping.vue'  // 引入组件
  import Todos from './components/Todos.vue'
</script>

<style lang="css" scoped>
  .app {
      text-align: center;
  }
  .btn {
      font-size: 20px;
      width: 100px;
      height: 40px;
      margin: 20px;
      border: 1px solid pink;
  }
</style>

此时效果如下:

vue的组件化开发?一个小demo就带你掌握!

由于使用了 <script setup>,这两个组件会自动在模板中局部注册,无需再显式调用 defineComponent 或者使用 export default。这意味着在模板中可以直接使用 <Shopping><Todos> 标签,而无需任何额外的注册步骤。

组件切换

两个组件切换显示,即浏览器分时渲染这两个组件:为两个按钮都绑定点击事件,点击按钮时都触发同一个函数,但传参不同,以此来对应不同组件在界面上的显示。

<template>
  <div class="app">
      <button class="btn" @click="changeTab(1)">购物车</button>
      <button class="btn" @click="changeTab(2)">todos</button>
      
      <Shopping v-if="tabIndex === 1"></Shopping>

      <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>

此时效果如下: vue的组件化开发?一个小demo就带你掌握!

两个子组件具体代码

Shopping.vue

<template>
    <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>
  </template>
  
  <script setup>
    import { reactive,computed } from 'vue';
    const books = reactive([
        {
          id: 1,
          name: '《算法导论》',
          date: '2006-9',
          price: 85.00,
          count: 1
        },
        {
          id: 2,
          name: '《UNIX编程艺术》',
          date: '2006-2',
          price: 59.00,
          count: 1
        },
        {
          id: 3,
          name: '《编程珠玑》',
          date: '2008-10',
          price: 39.00,
          count: 1
        },
        {
          id: 4,
          name: '《代码大全》',
          date: '2006-3',
          price: 128.00,
          count: 1
        },
      ]
    )

    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) => {
        // if(books[index].count >= 1)
            books[index].count--;
    }

  </script>
  
  <style lang="css" scoped>
    .shopping {
    }
    table {
        margin: 0 auto;
        border: 1px solid pink;
        border-collapse: collapse;  
        border-spacing: 0;
    }

    th,td {
        padding: 8px 16px;
        border: 1px solid pink;
    }
    .counter {
        margin: 0 5px;
    }
  </style>
  

Todos.vue

<template>
    <section class="todoapp">
        <header class="header">
            <h1>todos</h1>
            <input type="text" class="new-todo" placeholder="想做的事" @keyup.enter="addTodo">
        </header>

        <section class="main">
            <input type="checkbox" class="toggle-all">
            <label for="toggle-all">Mark all as complete</label>

            <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>
        </section>

    </section>    
</template>
  
  <script setup>
  import { reactive } from 'vue'

  const state = reactive({
    todos: [
        {id: 1, title: '吃饭', completed: false},
        {id: 2, title: '睡觉', completed: true},
        {id: 3, title: '打豆豆', completed: false}
    ]
  })
</script>
  
<style lang="css" scoped> 
</style>
  

总结

在 Vue 中,一个组件通常包含以下部分:

  1. 模板(Template) :定义了组件的 HTML 结构,可以使用 Vue 的模板语法来绑定数据和事件。
  2. 脚本(Script) :包含了组件的业务逻辑,包括数据、方法、计算属性、监听器等。
  3. 样式(Styles) :组件的 CSS 样式,可以是普通的 CSS 或者是作用域受限的 scoped styles。

任何应用都可以被拆分成一棵组件树,便于代码组织和扩展。

转载自:https://juejin.cn/post/7394369246242111515
评论
请登录