Vue.js - 组件化编程

1. 前言

Vue.js是一个基于组件的Javascript框架,组件化编程是核心思想之一。通过组件化,Vue允许开发者将用户页面拆分成独立,可重用的部分,从而提升代码的可维护性,可读性以及可服用性。

本文主要讲解在Vue2中组件化编程模式

2. 组件的定义

组件是一个具有独立功能的Vue实例,具有自己的数据,模板,样式与逻辑。每个组件可以相互交互,接收输入(props),并可以产生输出(事件),从而形成一个灵活的用户界面

3. 组件化编程的结构

3.1 组件创建

Vue组件最常用的创建方式是使用Vue单文件组件,包含以下三个部分

  1. 模板(Template):定义组件的HTML结构

Vue规定,在组件的模板中我们需要创建一个父标签囊括所有的标签

  1. 脚本(Script):定义组件的逻辑和数据

  2. 样式(Style):定义组件的CSS样式

以下是一个完整Vue组件模板:

javascript 复制代码
<template>
    
</template>

<style>
    
</style>

<script>
    
</script>

3.2 Vue.app

使用Vue.app集成所有的子组件(components),是应用的核心,管理应用的状态和组件

javascript 复制代码
<template>
</template>

<style>
</style>

<script>
    export component from './...'
    export default{
    components:{} //注册组件
}    
</script>

3.3 main.js

应用的入口Javascript文件,管理应用的状态与组件。

创建Vue实例,定义路由,状态管理,以及全局组件和插件的配置

javascript 复制代码
// main.js
import Vue from 'vue';
import App from './App.vue';
import Greeting from './Greeting.vue'; // 导入组件

// 全局注册组件
Vue.component('Greeting', Greeting);

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

3.4 index.html

应用文件的入口文件,提供挂载点

javascript 复制代码
<!DOCTYPE html>
<html lang="">
  <head>
    <meta charset="UTF-8">
    <link rel="icon" href="/favicon.ico">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vite App</title>
  </head>
  <body>
    <div id="app"></div>
    <script type="module" src="/src/main.js"></script>
  </body>
</html>

4. 组件的注册

组件可以在全局或局部进行注册

- 全局注册

定义:全局注册是指在Vue应用的整个生命周期,组件都可以被任何地方的模板使用

javascript 复制代码
// main.js
import Vue from 'vue';
import App from './App.vue';
import Greeting from './Greeting.vue'; // 导入组件

// 全局注册组件
Vue.component('Greeting', Greeting);

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

优点:方便在多个组件中使用同一个组件,尤其是在大型应用中

缺点:如果有多个同名组件,全局注册可能会导致命名冲突

- 局部注册

定义:组件只可以在其父组件之中使用,其他组件无法访问该组件

在组件的components选项中进行注册

javascript 复制代码
<template>
    <div>
        <Greeting></Greeting>
    <div>
</template>

<style>
</style>

<script>
import Greeting from './Greeting.vue' 

export default{
    components:{
    Greeting;
}
}
</script>

5. 组件的通信

5.1 数据传递

在子组件中使用props定义子组件中相关属性,父组件通过数据代理模式传递父组件的数据或者方法至子组件

javascript 复制代码
//父组件
<ChildComponent :message="parentMessage" />

//子组件
export default{
    props:['message'],
}

5.2 事件传递

事件传递主要是通过this.$emit函数出发自定义事件,将数据传递给父组件

javascript 复制代码
this.$emit('事件名',数据)

将会触发该事件,并传递对应的数据

只需要在父组件上设定好对应的事件,以及事件触发之后执行的函数,数据传递至函数,子组件便将数据传递给父组件了。

子组件:

javascript 复制代码
<template>
    <button @click='sendData'>Click me</button>
</template>

<script>
    export default{
    methods:{sendData(){this.$emit('childEvent','Hello')}} //通过调用该方法触发事件
}
<script>

父组件:

javascript 复制代码
<template>
<child @childEvent='handle'></child>
</template>

<script>
    export default {
    components:{child}
    methods:{handle(message){console.log('这是子组件传来的数据',message)}}
}
</script>

5.3 插槽

插槽是一种非常重要的功能,用于实现组件的内容分发。插槽允许开发者在父组件中嵌套内容到子组件中,从而在不修改子组件代码的情况下灵活地定制其内容

5.3.1 默认插槽

子组件:

javascript 复制代码
<template>
    <div class='child'>
        <slot></slot>
    </div>
</template>

父组件:

javascript 复制代码
<template>
<child>
<p>This is slot</p>
</child>
</template>

<script>
    export default{
    components:{child}
}
</script>

5.3.2 具名插槽

具名插槽允许一个组件中定义多个插槽,每个插槽都拥有自己的名字,这样父组件可以选择性的传递内容到不同的插槽位置

子组件:

javascript 复制代码
<template>
  <div class="child">
    <header><slot name="header"></slot></header> <!-- 具名插槽 -->
    <main><slot></slot></main> <!-- 默认插槽 -->
    <footer><slot name="footer"></slot></footer> <!-- 具名插槽 -->
  </div>
</template>

父组件:

javascript 复制代码
<template>
  <div>
    <child-component>
      <template v-slot:header>
        <h1>This is the header content</h1>
      </template>

      <p>This is the default slot content.</p>

      <template v-slot:footer>
        <footer>Footer content goes here</footer>
      </template>
    </child-component>
  </div>
</template>

<script>
import ChildComponent from './ChildComponent.vue';

export default {
  components: {
    ChildComponent
  }
}
</script>

5.3.3 插槽作用域

插槽不仅仅是用来传递静态内容,还可以向插槽传递数据通过插槽作用域,父组件可以将数据传递到子组件中的插槽,子组件可以在插槽模板内使用这些数据

javascript 复制代码
<template>
  <div class="child">
    <slot :message="childMessage"></slot> <!-- 传递数据到插槽 -->
  </div>
</template>

<script>
export default {
  data() {
    return {
      childMessage: 'Hello from child!'
    }
  }
}
</script>

父组件:

javascript 复制代码
<template>
  <div>
    <child-component>
      <!-- 使用插槽作用域来访问子组件传递的内容 -->
      <template v-slot:default="slotProps">
        <p>{{ slotProps.message }}</p> <!-- 输出从子组件传递来的数据 -->
      </template>
    </child-component>
  </div>
</template>

<script>
import ChildComponent from './ChildComponent.vue';

export default {
  components: {
    ChildComponent
  }
}
</script>
相关推荐
非凡ghost9 小时前
FxSound:提升音频体验,让音乐更动听
前端·学习·音视频·生活·软件需求
w2sfot9 小时前
Passing Arguments as an Object in JavaScript
开发语言·javascript·ecmascript
烛阴9 小时前
【TS 设计模式完全指南】从零到一:掌握TypeScript建造者模式,让你的对象构建链式优雅
javascript·设计模式·typescript
郝学胜-神的一滴9 小时前
避免使用非const全局变量:C++中的最佳实践 (C++ Core Guidelines)
开发语言·c++·程序人生
吃饭最爱9 小时前
html的基础知识
前端·html
我没想到原来他们都是一堆坏人9 小时前
(未完待续...)如何编写一个用于构建python web项目镜像的dockerfile文件
java·前端·python
搞一搞汽车电子10 小时前
S32K3平台eMIOS 应用说明
开发语言·驱动开发·笔记·单片机·嵌入式硬件·汽车
前端Hardy10 小时前
HTML&CSS:有趣的漂流瓶
前端·javascript·css
前端Hardy10 小时前
HTML&CSS :惊艳 UI 必备!卡片堆叠动画
前端·javascript·css
无羡仙10 小时前
替代 Object.freeze 的精准只读模式
前端·javascript