组件化开发

简介: 从基础到实战,我们一环都不要少!

首先我们来看非单文件开发的方式

案例一 : 语法篇

在 App.vue 中,定义了一个包含多个子组件的父组件。该组件包含模板、JavaScript 代码和样式,它们被分散在不同的文件中:

App.vue:

<template>
  <div class="app">
    <h1>{
  { title }}</h1>
    <my-header></my-header>
    <my-content></my-content>
    <my-footer></my-footer>
  </div>
</template>

<script src="./App.js"></script>

<style scoped>
  .app {
    
    background-color: #f0f0f0;
  }
</style>

App.js:

import MyHeader from './MyHeader.js';
import MyContent from './MyContent.js';
import MyFooter from './MyFooter.js';

export default {
   
  name: 'App',
  components: {
   
    MyHeader,
    MyContent,
    MyFooter,
  },
  data() {
   
    return {
   
      title: 'My App',
    };
  },
};

MyHeader.js:

export default {
   
  name: 'MyHeader',
  template: `
    <div class="header">
      <h2>{
    { headerTitle }}</h2>
    </div>
  `,
  data() {
   
    return {
   
      headerTitle: 'My Header',
    };
  },
};

MyContent.js:

export default {
   
  name: 'MyContent',
  template: `
    <div class="content">
      <p>{
    { contentText }}</p>
    </div>
  `,
  data() {
   
    return {
   
      contentText: 'Hello, world!',
    };
  },
};

MyFooter.js:

export default {
   
  name: 'MyFooter',
  template: `
    <div class="footer">
      <p>{
    { footerText }}</p>
    </div>
  `,
  data() {
   
    return {
   
      footerText: 'My Footer',
    };
  },
};

在上面的代码中,我们将 App 组件的模板、JavaScript 代码和样式拆分到不同的文件中。这样做会使组件的结构混乱,并且代码的维护困难度会增加。同时,由于样式没有 scoped 属性,可能会存在样式泄漏到其他组件中的问题。此外,每个组件都需要单独进行导入和注册,增加了代码的复杂性和冗余。

相比之下,使用单文件组件可以将组件的相关代码和样式整合到一个文件中,使得组件更结构化、清晰和易于维护。

案例二 : 缺点篇

以下是一个更复杂的非单文件开发示例,展示了其潜在的一些弊端:

App.vue:

<template>
  <div class="app">
    <h1>{
  { title }}</h1>
    <my-header></my-header>
    <my-content></my-content>
    <my-footer></my-footer>
  </div>
</template>

<script>
import MyHeader from './components/MyHeader.js';
import MyContent from './components/MyContent.js';
import MyFooter from './components/MyFooter.js';

export default {
    
  name: 'App',
  components: {
    
    MyHeader,
    MyContent,
    MyFooter,
  },
  data() {
    
    return {
    
      title: 'My App',
    };
  },
};
</script>

<style scoped>
.app {
    
  background-color: #f0f0f0;
}
</style>

components/MyHeader.js:

<template>
  <div class="header">
    <h2>{
   {
    headerTitle }}</h2>
    <my-logo></my-logo>
  </div>
</template>

<script>
import MyLogo from '../shared/MyLogo.js';

export default {
   
  name: 'MyHeader',
  components: {
   
    MyLogo,
  },
  data() {
   
    return {
   
      headerTitle: 'My Header',
    };
  },
};
</script>

<style>
.header {
   
  padding: 20px;
  background-color: #ccc;
}
</style>

components/MyContent.js:

<template>
  <section class="content">
    <h3>{
   {
    contentTitle }}</h3>
    <p>{
   {
    contentText }}</p>
    <my-comments></my-comments>
  </section>
</template>

<script>
import MyComments from '../shared/MyComments.js';

export default {
   
  name: 'MyContent',
  components: {
   
    MyComments,
  },
  data() {
   
    return {
   
      contentTitle: 'My Content',
      contentText: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
    };
  },
};
</script>

<style>
.content {
   
  padding: 20px;
  background-color: #fff;
}
</style>

components/MyFooter.js:

<template>
  <footer class="footer">
    <p>{
   {
    footerText }}</p>
    <my-social-icons></my-social-icons>
  </footer>
</template>

<script>
import MySocialIcons from '../shared/MySocialIcons.js';

export default {
   
  name: 'MyFooter',
  components: {
   
    MySocialIcons,
  },
  data() {
   
    return {
   
      footerText: 'My Footer',
    };
  },
};
</script>

<style>
.footer {
   
  padding: 20px;
  background-color: #f0f0f0;
}
</style>

我们创建了一个更复杂的应用程序,并将其拆分为多个组件。每个组件的模板、JavaScript 代码和样式都被分散到不同的文件中,并且存在多层的组件嵌套结构

这种非单文件开发方式存在几个潜在的问题:

  • 文件路径混乱:随着组件数量的增加,文件结构可能变得混乱,开发者需要花费更多时间来查找和管理文件路径。

  • 依赖管理困难:在组件中导入其他组件时,需要考虑正确的相对路径,并确保文件引用的准确性。

  • 构建配置复杂:使用非单文件开发时,构建工具需要配置以支持将拆分的组件文件正确地合并和编译为最终的应用程序。

  • 代码重复和冗余:每个组件都需要单独导入和注册,这可能导致代码的重复和冗余。

  • 维护困难:当应用程序变得更加复杂时,非单文件开发方式可能导致组件关系和代码之间的交互变得困难,增加了项目的维护成本和难度。

综上所述,尽管非单文件开发在某些情况下是可行的,但它可能存在一些潜在的问题,特别是在大型项目和复杂组件结构的情况下。因此,单文件组件是更推荐的 Vue.js 开发实践方式,可以提供更清晰、结构化和易于维护的代码。

接着我们来到单文件组件开发

来一个经典的ToDoList案例

组件是 Vue.js 中最基本和最重要的概念之一,它提供了一种抽象和封装的方式,让我们可以将一个页面拆分成多个相互独立的功能块,每个功能块即为一个组件。在实际开发中,组件可以是任何大小的、自定义的HTML元素。

假设我们需要创建一个 TodoList 应用,每个 Todo 项都包含一个标题和一个完成状态。我们可以将每个 Todo 项作为一个组件,然后通过组合多个 Todo 组件实现整个 TodoList 应用。

创建 Todo 组件

<!-- Todo.vue -->
<template>
  <div class="todo">
    <h3>{
  { title }}</h3>
    <label>
      <input type="checkbox" :checked="completed" @change="$emit('toggle')">
      完成
    </label>
  </div>
</template>

<script>
export default {
    
  props: {
    
    title: String,
    completed: Boolean,
  },
};
</script>

<style scoped>
.todo {
    
  margin-bottom: 10px;
}
</style>

在这个组件中,我们定义了一个 title 属性和一个 completed 属性,分别表示 Todo 的标题和完成状态。在模板中,我们使用了标准的 HTML 元素和指令来渲染组件的外观和交互逻辑。注意到我们使用了父组件传递过来的属性值 title 和 completed 来动态绑定组件的内容。

创建 TodoList 组件

<!-- TodoList.vue -->
<template>
  <div class="todo-list">
    <h2>Todo List</h2>
    <div class="todos">
      <todo v-for="(todo, index) in todos" :key="index" :title="todo.title" :completed="todo.completed" @toggle="toggle(index)"></todo>
    </div>
    <div class="add-todo">
      <input type="text" v-model="newTodoTitle">
      <button @click="addTodo">添加</button>
    </div>
  </div>
</template>

<script>
import Todo from "./Todo.vue";

export default {
    
  components: {
    
    Todo,
  },
  data() {
    
    return {
    
      newTodoTitle: "",
      todos: [
        {
     title: "学习Vue", completed: false },
        {
     title: "写代码", completed: true },
      ],
    };
  },
  methods: {
    
    addTodo() {
    
      this.todos.push({
     title: this.newTodoTitle, completed: false });
      this.newTodoTitle = "";
    },
    toggle(index) {
    
      this.todos[index].completed = !this.todos[index].completed;
    },
  },
};
</script>

<style scoped>
.todo-list {
    
  margin: 20px;
}

.todos {
    
  margin-bottom: 10px;
}
</style>

在这个组件中,我们使用了上面定义的 Todo 组件来渲染 TodoList 应用中的所有 Todo 项。在数据中,我们定义了一个 todos 数组来存储所有 Todo 项的信息。在模板中,我们使用了 v-for 指令遍历 todos 数组,并动态绑定每个 Todo 项的属性值。同时,我们还定义了一个输入框和一个按钮,用于添加新的 Todo 项。在方法中,我们实现了添加新 Todo 项和切换 Todo 完成状态的功能。

创建根组件

<!-- App.vue -->
<template>
  <div class="app">
    <todo-list></todo-list>
  </div>
</template>

<script>
import TodoList from "./TodoList.vue";

export default {
    
  components: {
    
    TodoList,
  },
};
</script>

<style scoped>
.app {
    
  margin: 20px;
}
</style>

在这个根组件中,我们只需要渲染最顶层的组件 TodoList 即可。

通过上面的代码示例,我们可以看到,在 Vue2 中,组件化编程的核心思想是将一个页面拆分成多个相互独立的功能块,每个功能块即为一个组件。在实际开发中,组件可以是任何大小的、自定义的HTML元素,而且可以方便地复用和组合。

全局组件在vue2开发时的使用

在单文件组件开发中,合理使用全局组件可以提高代码的复用性和可维护性。

全局组件可以在多个 Vue 实例中使用,在不同的单文件组件或页面中都可以方便地引用和调用。因此,在以下情况下,我们可以考虑使用全局组件:

当某个组件在多个地方需要使用时,将其注册为全局组件,可以避免在每个使用该组件的地方都单独引用和注册。

当多个单文件组件之间需要共享相同的逻辑或数据时,可以将其抽象成一个全局组件,以减少代码重复度。

但是在使用全局组件时,也需要注意以下事项:

  • 全局组件将会在全局注册,如果有多个组件具有相同名称,会出现组件覆盖的情况。因此,需要避免命名冲突。

  • 全局组件会增加应用程序的复杂度,而且在大型应用程序中过多的全局组件也会影响性能。因此,需要合理使用全局组件,避免过多的组件注册。

下面是一个全局组件的例子,以MyButton为例,先在main.js中注册:

import Vue from 'vue'
import App from './App.vue'
import MyButton from './components/MyButton.vue'

Vue.component('MyButton', MyButton)

new Vue({
   
  render: h => h(App),
}).$mount('#app')

在App.vue中使用:

<template>
  <div>
    <MyButton text="点击我"></MyButton>
  </div>
</template>

在其他组件也可以直接引用:

<template>
  <div>
    <MyButton text="确认" @click="submit"></MyButton>
  </div>
</template>

通过这种方式,我们可以使用全局组件使得组件复用更加容易,代码的可维护性也会提高。

案例三:全局组件实现小而巧的功能

首先,在src/components文件夹中创建一个名为Modal.vue的单文件组件,用于显示弹框内容:

<template>
  <div v-if="show" class="modal">
    <div class="modal-content">
      <slot></slot>
    </div>
  </div>
</template>

<script>
export default {
    
  data() {
    
    return {
    
      show: false,
    };
  },
  methods: {
    
    showModal() {
    
      this.show = true;
    },
    hideModal() {
    
      this.show = false;
    },
  },
};
</script>

<style scoped>
.modal {
    
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
}

.modal-content {
    
  background-color: #fff;
  padding: 20px;
}
</style>

然后,在main.js中注册并创建全局组件:

import Vue from 'vue'
import App from './App.vue'
import Modal from './components/Modal.vue'

Vue.component('Modal', Modal)

new Vue({
   
  render: h => h(App),
}).$mount('#app')

接下来,你可以在任何一个组件中使用全局的弹框组件,并调用其方法来显示弹框:

<template>
  <div>
    <button @click="showModal">显示弹框</button>
    <Modal ref="modal">
      <h2>我是弹框的内容</h2>
      <p>这是一个全局的弹框组件</p>
      <button @click="hideModal">关闭弹框</button>
    </Modal>
  </div>
</template>

<script>
export default {
    
  methods: {
    
    showModal() {
    
      this.$refs.modal.showModal();
    },
    hideModal() {
    
      this.$refs.modal.hideModal();
    },
  },
};
</script>

这样,通过全局组件实现的弹框功能可以在整个应用程序中使用,方便地显示和隐藏弹框内容。

目录
相关文章
|
8月前
|
JavaScript 开发者
组件化开发
组件化开发
|
2月前
|
前端开发 JavaScript 物联网
组件化设计适用于哪些场景
【10月更文挑战第22天】组件化设计适用于哪些场景
|
2月前
|
前端开发 JavaScript UED
什么是组件化设计
【10月更文挑战第22天】什么是组件化设计
|
3月前
|
前端开发 安全 测试技术
前端组件化有什么优势?
【10月更文挑战第4天】
60 1
|
3月前
|
前端开发 JavaScript 开发者
深入解析前端开发中的模块化与组件化实践
【10月更文挑战第5天】深入解析前端开发中的模块化与组件化实践
38 1
|
6月前
|
JavaScript API
组件化
【7月更文挑战第13天】 Vue.js组件化是将UI拆分成独立、复用组件的过程,涉及模板、逻辑和样式。通过Vue.extend()创建构造器,然后全局或局部注册组件。使用`&lt;my-cpn&gt;`在模板中插入组件。单文件组件(.vue)结合模板、脚本和样式。父子组件间通过props和$emit通信,提升代码维护性和复用性。Vue.js的组件化开发既高效又灵活。
45 4
|
8月前
|
JavaScript 前端开发
面试题:组件化和模块化的理解
面试题:组件化和模块化的理解
72 0
|
8月前
|
前端开发 JavaScript
前端组件化开发
前端组件化开发
145 0
|
小程序 开发者
小程序组件化开发
随着小程序的普及,越来越多的开发者开始使用小程序进行开发,而小程序的组件化开发已经成为了一种标配的开发模式。本文将深入介绍小程序组件化开发的相关知识,包括组件的定义、生命周期、通信和使用等方面,帮助大家更好地理解和使用小程序的组件化开发模式。组件是小程序中的一个重要概念,它能够将页面分解成独立的、可复用的部分,以便于开发和维护,组件可以包含一些特定的功能和样式,同时也能够接受外部的数据和事件。在小程序中,组件是通过Component构造函数来定义的。propertiesdata和methods。
157 0
|
开发框架 前端开发 JavaScript
前端工程化组件化开发框架之React的状态管理
在前端工程化组件化开发框架中,React是一个非常流行的开源库。React可以帮助开发者快速构建具有可重用性和可维护性的组件,并且提供了完善的组件管理和状态管理机制。
119 0