Vue 组件化开发

news2024/11/23 21:33:35

文章目录

  • 前言
  • 组件化开发
  • 父子组件相互传数据
    • 父传子:自定义属性
    • 子传父:自定义事件
    • 父子组件互传案例
  • 插槽 slot
    • 多个插槽
  • 总结
    • 组件化开发总结
    • Vue组件的基本组成
    • 子组件使用的三个步骤
    • 父子组件相互传递数据


前言

提示:这里可以添加本文要记录的大概内容:

Vue.js 是一种现代化的前端框架,可以用于构建可复用的组件化应用程序。Vue.js 提供了一种基于组件的架构,使得开发人员可以将应用程序分解为多个可重用的组件。

Vue.js 组件是一个可复用的代码模块,可以在 Vue.js 应用程序中使用。组件包括 HTML 模板、JavaScript 代码和 CSS 样式,并且可以包含其他组件。

Vue.js 组件化开发的主要优势包括:

  1. 模块化:Vue.js 组件使得应用程序变得更易于管理和维护,可以将应用程序分解为多个小模块,每个模块都有自己的功能和样式。

  2. 可重用性:组件化开发使得开发人员可以编写可重用的代码片段,可以在不同的项目中使用,并且可以在同一应用程序中多次使用。

  3. 维护性:组件化开发使得代码更加模块化,更易于维护和测试。

  4. 性能:在 Vue.js 中使用组件可以提高应用程序的性能,因为它可以在需要时延迟加载组件。

总之,Vue.js 组件化开发是一种高效的方式,可以帮助开发人员构建可维护和可重用的应用程序。


提示:以下是本篇文章正文内容,下面案例可供参考

组件化开发

首先Ctrl+c 停止上面项目访问,新建一个项目
cd ..:返回上一级
在这里插入图片描述

接下来就是把【创建Vue-Cli工程】的过程再来一遍:
完整过程:

  1. 新建文件夹【vue create 小写名字】vue create component 。component(组件化开发)
  2. 选择最后一个Manually select features
  3. 空格去掉倒数第三个( * ) Linter / Formatter
  4. 默认选择3.x
  5. 选择倒数第二个In package.json
  6. 不保存n

出现Successfully代表创建成功
在这里插入图片描述
打开项目,进行一些默认操作:

①、用脚手架创建项目时,把脚手架生成的代码删除掉
在这里插入图片描述
②、删除App.vue内所有代码,随后输入vue选择第一个
在这里插入图片描述

在template标签中加代码:

    <h1>{{ title }}</h1>

在script标签中的data函数的返回对象加代码:

title:'我是根组件'

打开终端输入:npm run serve,就可以运行了
在这里插入图片描述
components文件夹下新建个子组件TabMenu.vue,名字是驼峰式命名

生成基本结构,输入vue回车,加点代码与样式,这里可以随便写,主要是展示子组件的使用
在这里插入图片描述
在这里插入图片描述
现在一个根组件(App.vue),一个子组件(TabMenu.vue),运行:
在这里插入图片描述

那么如何在根组件中使用子组件呢?

以App.vue根组件,TabMenu.vue子组件为例:

  1. 导入需要的子组件(在script标签内)
import TabMenu from '@/components/TabMenu.vue';  //@相当于src
  1. 在components的配置项中注册子组件
components: {TabMenu},
  1. 在template中以标记的语法使用子组件
<TabMenu></TabMenu>  

父子组件相互传数据

在父子组件中如何让他俩可以相互发数据?

以App.vue根组件,Data.vue子组件为例:

父传子:自定义属性

先写先接受数据的一方

  1. 父给子传数据,先给子组件里面增加一个新个配置项props,自定义属性的意思

components文件中新建子组件Data.vue(script标签内)
vue生成基本结构后,增加props配置项

  // 数组形式,里面自定义名字
  props: ['test']
  1. 在template标签内加上插值语法把上面的自定义名字加上去
<template>
  <div>
    <h1>数据子组件</h1>
    <h1>这是父组件传递给我的数据:{{ test }}</h1>
  </div>
</template>
  1. 父组件中再导入该子组件(在script标签内)
import Data from '@/components/Data.vue'
  1. 在components的配置项中注册子组件
  components: {TabMenu,Data}, //TabMenu是另一个子组件,多个子组件用逗号隔开
  1. 在template中以标记的语法使用子组件
<Data></Data>

父组件App.vue中完整代码:

<template>
  <div>
    <h1>{{ title }}</h1>
    <!-- 3.在template中以标记的语法使用子组件 -->
    <TabMenu></TabMenu>
    <Data></Data>
  </div>
</template>

<script>
// 1.导入需要的子组件
import TabMenu from '@/components/TabMenu.vue';  
import Data from '@/components/Data.vue'
export default {
  data () {
    return {
      title:'我是根组件'
    }
  },
  methods: {

  },
  //2.在components的配置项中注册子组件
  components: {TabMenu,Data},  //TabMenu是另一个子组件,多个子组件用逗号隔开
  computed: {},
  watch: {},
  mounted () {}
}
</script>
<style scoped>
</style>

输出效果:
在这里插入图片描述
但是现在里面还没有数据,因为在Data.vue中test是自定义属性

  1. 接下来在父组件中加入自定义属性
<Data test="你好啊"></Data>

在这里插入图片描述

如果说要在子组件里再定义一个属性,父组件再传一个,只需要在相应位置加上属性后用逗号隔开即可

子组件中:
在这里插入图片描述
在这里插入图片描述
父组件中:
在这里插入图片描述

子传父:自定义事件

recive():接收子给父传上来的数据,有参,代表传来的数据

在父组件中:

  1. 自定义一个事件,这里取名abc
    <Data test="你好啊" test1="世界" @abc = "recive"></Data>
  1. 在methods配置项中定义recive()函数方法
  methods: {
    recive(d){
      // d:代表子给父发的数据
      this.title = d   //更改title值
    }
  },

子组件中:

  1. 在子组件中编写一个函数,加入一个事件:
    在这里插入图片描述

  2. 给v-model的属性tes在data函数的return里面配置一下

  3. methods内加上send方法

    send(){
        this.$emit('abc',this.text)
        //this.$emit('在父组件中配置的事件名字',this.发送给父组件的数据)
    }

在这里插入图片描述
最后输出:
在这里插入图片描述

父子组件互传案例

一个App父组件
两个子组件:一个添加待办事项组件、一个待办列表组件

如果之前有项目在终端开着先Ctrl+c关掉
然后新建一个待办项目:vue create todo,然后依次回车选择配置选项
然后进入到 todo 项目中,删掉HelloWorld.vue文件 和 App.vue中所有代码(输入vue重新生成)

在components文件夹中创建新子组件AddItem.vue 和 List.vue

在父组件中使用子组件:

  1. 导入需要的子组件
  2. 在components的配置项中注册子组件
  3. 在template中以标记的语法使用子组件

目前为止父组件中代码:

<template>
  <div>
    <h1>待办事项</h1>
    <!-- 3.使用 -->
    <AddItem></AddItem>
    <List></List>
  </div>
</template>

<script>
// 1. 导入
import AddItem from '@/components/AddItem.vue';
import List from '@/components/List.vue';
export default {
  data () {
    return {

    }
  },
  methods: {

  },
  // 2.注册
  components: {AddItem,List},
  computed: {},
  watch: {},
  mounted () {}
}
</script>
<style scoped>
</style>

接下来先把List待办列表弄出来再写待办事项,也就是写个父给子的数据传递
增加自定义的属性,使用 v-for 指令对 todolist 进行循环渲染,将 todolist 中的每个元素都显示为一个有序列表中的一条,{{ item }} 则是将前面 item 变量名插入到模板中进行渲染。

由于本组件需要从父组件中接收一个名为 todolist 的属性,所以使用 props 选项来声明了一个具名的 todolist 属性

最后加了点CSS样式

下面是完整的 List.vue 代码

<template>
  <div>
    <ul>
      <!-- 使用 v-for 指令遍历传入的 todolist 数据,生成 li 列表项 -->
      <li v-for="(item, index) in todolist" :key="index">{{ item }}</li>
                                    <!-- 2.使用插值语法把上面的自定义名字加上去 -->
    </ul>
  </div>
</template>

<script>
export default {
  // 1.定义一个 props 属性,接收父组件传递的 todolist 数据 (自定义的属性)
  props: ['todolist']
}
</script>

<style scoped>
/* 为 ul 列表设置样式 */
ul {
  list-style: none; /* 取消列表项的默认样式 */
  margin: 0; /* 去除外边距 */
  padding: 0; /* 去除内边距 */
  display: flex; /* 将列表项设为弹性项目 */
  flex-wrap: wrap; /* 当空间不足时,自动换行 */
}

/* 为 li 列表项设置样式 */
li {
  font-size: 1.2rem; /* 设置字体大小 */
  color: #333; /* 设置字体颜色 */
  background-color: #f5f5f5; /* 设置背景颜色 */
  border-radius: 5px; /* 设置圆角 */
  margin: 0.5rem; /* 设置外边距 */
  padding: 1rem; /* 设置内边距 */
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1), 0 0 12px rgba(0, 0, 0, 0.1); /* 设置阴影 */
  text-align: center; /* 设置文本居中 */
  transition: transform 0.2s cubic-bezier(0, 0, 0.2, 1), box-shadow 0.2s cubic-bezier(0, 0, 0.2, 1); /* 设置过渡效果 */
}

/* 当鼠标悬停在 li 列表项上时的样式 */
li:hover {
  transform: translateY(-5px);
  box-shadow: 0 12px 24px rgba(0, 0, 0, 0.2), 0 0 12px rgba(0, 0, 0, 0.2);
}
</style>

第一步:在父组件data中把待办事项的数据定义出来

  data () {
    return {
      items: ['学习','做事','赚钱']
      // a.把items数据传给list组件去用,用属性todolist去传
    }
  },

第二步:用list组件动态绑定items数据

<List :todolist="items"></List>

最后父组件中完整代码

<template>
  <div>
    <h1>待办事项</h1>
    <!-- 3.使用 -->
    <AddItem></AddItem>
    <!-- b.list组件 加上冒号是动态绑定items数据-->
    <List :todolist="items"></List>
  </div>
</template>

<script>
// 1. 导入
import AddItem from '@/components/AddItem.vue';
import List from '@/components/List.vue';
export default {
  data () {
    return {
      items: ['学习','做事','赚钱']
      // a.把items数据传给list组件去用,用属性todolist去传
    }
  },
  methods: {

  },
  // 2.注册
  components: {AddItem,List},
  computed: {},
  watch: {},
  mounted () {}
}
</script>
<style scoped>
</style>

现在打开终端进入该项目路径下启动该项目:npm run serve
启动后运行
在这里插入图片描述
接下来是子给父传数据
第一步:加上自定义事件
第二步:放在methods,接受要带参数

<!-- 第一步:自定义事件 -->
<AddItem @item="recive"></AddItem> 
...
//中间代码胜率
...
  methods: {
    // 第二步:放在methods,接受的话要带参数
    recive(d){
      this.items.unshift(d)  
    }
  },

父组件中完整代码是:

<template>
  <div>
    <h1>待办事项</h1>
    <!-- 3.使用 -->
    <!-- 第一步:自定义事件 -->
    <AddItem @item="recive"></AddItem> 
    <!-- b.list组件 加上冒号是动态绑定items数据-->
    <List :todolist="items"></List>
  </div>
</template>

<script>
// 1. 导入
import AddItem from '@/components/AddItem.vue';
import List from '@/components/List.vue';
export default {
  data () {
    return {
      items: ['学习','做事','赚钱']
      // a.把items数据传给list组件去用,用属性todolist去传
    }
  },
  methods: {
    // 第二步:放在methods,接受的话要带参数
    recive(d){
      this.items.unshift(d)  
    }
  },
  // 2.注册
  components: {AddItem,List},
  computed: {},
  watch: {},
  mounted () {}
}
</script>
<style scoped>
</style>

下一步到子组件AddItem.vue里面

1:在里面加一个输入框和按钮

    <input type="text" v-model="item">
    <button @click="send">添加</button>

2:data里面配数据

  data () {
    return {
      item: ''
    }
  },

3:在methods里把数据发送给父组件

  methods: {
    send(){
      this.$emit('item,this.item')
    }
  },

然后在给css内加点样式

最后AddItem.vue完整代码

<template>
  <div class="input-container"> <!-- 输入框容器 -->
    <input type="text" v-model="item" placeholder="输入待办事项" class="input-field"> <!-- 输入框 -->
    <button @click="send" class="add-btn">添加</button> <!-- 添加按钮 -->
  </div>
</template>

<script>
export default {
  data () {
    return {
      item: '' // 输入框绑定的数据
    }
  },
  methods: {
    send(){
      this.$emit('item',this.item) // 发出事件,传递输入框数据
    }
  },
}
</script>

<style scoped>
.input-container { /* 输入框容器样式 */
  display: flex; /* flex 布局 */
  align-items: center; /* 垂直居中 */
  margin-bottom: 20px; /* 底部外边距 */
}

.input-field { /* 输入框样式 */
  border: none; /* 取消边框 */
  border-bottom: 2px solid #aaa; /* 底部边框 */
  padding: 0.5rem; /* 内边距 */
  margin-right: 1rem; /* 右外边距 */
  font-size: 1rem; /* 字体大小 */
  font-family: Arial, sans-serif; /* 字体样式 */
  width: 300px; /* 宽度 */
}

.add-btn { /* 添加按钮样式 */
  background-color: #20A3FF; /* 背景颜色 */
  border: none; /* 取消边框 */
  color: white; /* 字体颜色 */
  padding: 0.5rem; /* 内边距 */
  border-radius: 5px; /* 圆角 */
  cursor: pointer; /* 鼠标样式 */
  transition: all 0.3s ease; /* 过渡效果 */
  box-shadow: 0 2px 3px rgba(0, 0, 0, 0.3); /* 阴影 */
}

.add-btn:hover { /* 鼠标悬停样式 */
  background-color: #2186e2;
  transform: translateY(-2px); /* 上移 */
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.3); /* 增加阴影 */
}

.input-field:focus { /* 输入框获得焦点时的样式 */
  outline: none; /* 取消选中时的边框 */
  border-bottom: 2px solid #2186e2; /* 底部边框颜色更改 */
}
</style>

输出效果:
请添加图片描述

插槽 slot

新建子组件Slot.vue,用vue生成格式后在HTML位置输入

<template>
  <div>
    <h1>我是插槽子组件</h1>
    <!-- 插槽位置 -->
    <slot></slot>
  </div>
</template>

在父组件App.vue中在相应位置进行导入、注册、使用(可以新建一个项目,看起来更直观)

import Slot from '@/components/Slot.vue';

  components: {Slot},

    <Slot>
      <h1>你好</h1>
      <!-- 将会显示在子组件的Slot插槽位置上 -->
    </Slot>

运行项目:
在这里插入图片描述

多个插槽

通过名字区分

比如在子组件中再加一个slot标签加个名字

<slot name="a"></slot>

在父组件中加上template v-slot:a

    <Slot>
      <!-- 将会显示在子组件的Slot插槽位置上 -->
      <h1>你好</h1>
      <!-- 通过名字单独指令子组件的Slot插槽位置 -->
      <template v-slot:a>
        <h2>hello</h2>
      </template>
    </Slot>

另外在css位置加了点样式(可以忽略)
在这里插入图片描述

总结

组件化开发总结

Vue组件的基本组成

  1. template——模版 html代码
  2. script——脚本 vue配置对象中的各种配置项
  3. style——样式 css代码

子组件使用的三个步骤

  1. 在父组件中导入所需子组件
  2. 在父组件的配置对象中的components配置项中注册子组件
  3. 在父组件的template中以标记的语法使用子组件

父子组件相互传递数据

  1. 父传子
    a.在子组件配置对象中增加props配置项(自定义属性)
    b.在父组件使用子组件时通过自定义的属性名传数据

  2. 子传父
    a.在父组件中增加自定义事件,并编写接受数据的方法 【@item=“recive”】
    b.在子组件中增加一个发送数据的方法,调用this.$emit(‘自定义的事件名’,发送的数据)

那么如何在根组件中使用子组件呢?

以App.vue根组件,TabMenu.vue子组件为例:

  1. 导入需要的子组件(在script标签内)
import TabMenu from '@/components/TabMenu.vue';  //@相当于src
  1. 在components的配置项中注册子组件
components: {TabMenu},
  1. 在template中以标记的语法使用子组件
<TabMenu></TabMenu>  

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/745902.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

jenkins 创建项目的ci

一.创建视图 1.点击加号 选择列表视图 2.输入名称&#xff0c;点击确定 二.创建任务 1.点击到你新建的视图之后&#xff0c;再点击文本中的创建一个新的任务。 2.进入创建页面后首先填写描述 三.选择丢弃旧的构建 保持构建的天数是指&#xff1a;是指保留多少天内的构建 …

【基于FPGA的芯片设计】RISC-V的20条指令CPU设计

实验板卡&#xff1a;xc7a100tlc sg324-2L&#xff0c;共20个开关 实验要求&#xff1a;

【C#】并行编程实战:同步原语(1)

在第4章中讨论了并行编程的潜在问题&#xff0c;其中之一就是同步开销。当将工作分解为多个工作项并由任务处理时&#xff0c;就需要同步每个线程的结果。线程局部存储和分区局部存储&#xff0c;某种程度上可以解决同步问题。但是&#xff0c;当数据共享时&#xff0c;就需要用…

Chrome内建DNS导致的解析错误修复

Index Chrome内建DNSDisable Async DNS resolver Chrome内建DNS 实际上 , Chrome在使用自己的DNS来进行域名的解析 , 这导致有时候一些域名解析会出现错误 , 导致访问速度变慢 , 例如 blog.csdn.net 使用谷歌的 8.8.8.8 dns解析就会 , 解析到香港的ip上去 , 导致访问速度变慢 …

群晖NAS:docker查询注册表失败解决方案 docker安装网心云、mysql等

群晖NAS&#xff1a;docker查询注册表失败解决方案 差不多2023年4月底开始的&#xff0c;docker内不能直接搜索注册表。据说是有人在库里放了一些有意思的东西&#xff0c;被和谐掉了&#xff0c;所以也别指望什么时候能解封。 网上很多案例&#xff0c;都不能用。还有奇葩的…

史上最细接口测试详解,接口测试从0到1实施,一篇打通...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、接口测试描述定…

【C语言】-- 死循环了怎么办?

#include <stdio.h> int main() {int i 0;int arr[] {1,2,3,4,5,6,7,8,9,10};for(i0; i<12; i){arr[i] 0;printf("hello\n");}return 0; } 阅读上面这个代码&#xff0c;我们会认为这不就是简单的数组访问越界么。那么这段代码就应该会报错&#xff0c;…

macOS Sonoma 14beta 3 (23A5286i)第二个更新「附黑/白苹果镜像下载」

系统镜像下载&#xff1a; 系统介绍 黑果魏叔 7 月12 日消息&#xff0c;苹果今天发布 macOS Sonoma 14.0 Beta 3&#xff08;内部版本号&#xff1a;23A5286i&#xff09;第二个更新。 目前尚不清楚苹果为什么要发布 macOS Sonoma Beta 3 的第二个版本&#xff0c;但它可能…

外包干了2年,我裸辞了...

我25岁&#xff0c;中级测试&#xff0c;外包&#xff0c;薪资13.5k&#xff0c;人在上海。内卷什么的就不说了&#xff0c;而且人在外包那些高级精英年薪大几十的咱也接触不到&#xff0c;就说说外包吧。 假设以我为界限&#xff0c;25岁一线城市13.5k&#xff0c;那22-24大部…

CUDA11.1、cuDNN8.6.0、Tensorrt8.5.3,ubuntu20.04安装过程记录

CUD11.1 下载地址&#xff1a;CUDA Toolkit Archive | NVIDIA Developer 安装&#xff1a; wget https://developer.download.nvidia.com/compute/cuda/11.1.1/local_installers/cuda_11.1.1_455.32.00_linux.run sudo sh cuda_11.1.1_455.32.00_linux.run 对于不是sudo用户&…

CRYPTO-36D-飞鸽传书

0x00 前言 CTF 加解密合集&#xff1a;CTF 加解密合集 0x01 题目 TVdJd09HRm1NamMyWkdKak56VTVNekkzTVdZMFpXVTJNVFl5T0Rrek1qUWxNRUZsTW1GbE0yRXlNelV3TnpRell6VXhObU5rWVRReE1qUTVPV0poTTJKbE9TVXdRV0prWlRVeVkySXpNV1JsTXpObE5EWXlORFZsTURWbVltUmlaRFptWWpJMEpUQkJaVEl6…

Jmeter性能测试插件jpgc的安装

目录 一、获取插件包 1.访问官网获取 2.百度网盘下载 二、安装路径 三、安装插件 1.重启Jmeter 2.进入Plugins Manager 3.jpgc插件安装 4.安装完成后检查 总结&#xff1a; 一、获取插件包 1.访问官网获取 官网地址&#xff1a; ​ 2.百度网盘下载 链接&#xff1…

LiveGBS 国标平台作为下级GB28181级联到海康大华宇视华为等第三方国标平台的操作步骤说明

LiveGBS 国标平台作为下级GB28181级联到海康大华宇视华为等第三方国标平台的操作步骤说明 1、什么是GB/T28181级联2、搭建GB28181国标流媒体平台3、获取上级平台接入信息3.1、如何提供信息给上级3.2、上级国标平台如何添加下级域3.2、接入LiveGBS示例 4、配置国标级联4.1、国标…

Go语言对json处理总结

实际业务开发中&#xff0c;json处理很常见&#xff0c;本文总结一下go语言对json的处理。 目录 1.encoding/json 包 1.1 Marshal 函数 &#xff08;1&#xff09;原始字段名 &#xff08;2&#xff09;字段重命名 1.2 Unmarshal函数 &#xff08;1&#xff09;原始字段…

ELK-日志服务【logstash-安装与使用】

目录 【1】安装logstash logstash input 插件的作用与使用方式 【2】input --> stdin插件&#xff1a;从标准输入读取数据&#xff0c;从标准输出中输出内容 【3】input -- > file插件&#xff1a;从文件中读取数据 【4】input -- > beat插件&#xff1a;从filebe…

目标检测学习

目录 1、目标定位 2、特征点检测 3、目标检测 4、滑动窗口的卷积实现 5、Bounding Box 预测&#xff08;Bounding box predictions&#xff09; 6、交并化 7、非极大值抑制 8、Anchor Boxes 9、YOLO算法 1、目标定位 2、特征点检测 如何检测特征点&#xff08;以人的部…

基于linux下的高并发服务器开发(第一章)- 静态库的制作1.4

01 / 什么是库 库文件是计算机上的一类文件&#xff0c;可以简单的把库文件看成一种代码仓库&#xff0c;它提供给使用者一些可以直接拿来用的变量、函数或类库是特殊的一种程序&#xff0c;编写库的程序和编写一般的程序区别不大&#xff0c;只是库不能单独运行。库文件有两种…

如何选择适合外贸公司的企业邮箱?推荐哪些优质企业邮箱服务?

为外贸公司选择合适的企业邮箱是企业成功经营的关键。强大、安全、直观的企业邮箱能够满足不同平台上不同用户的需求&#xff0c;这是确保数据和消息与客户和合作伙伴准确沟通的关键。以下是外贸公司在选择企业邮箱时应考虑的一些规范: 1、安全 在考虑企业邮箱时&#xff0c;安…

如何下载centOS镜像

我们在操作虚拟机的时候都有一个选择镜像&#xff0c; 这里我们可以去对应的官网去下载即可&#xff0c;下面就是网址 Download (centos.org) 就会出现许多地址 我们只需要随便选一个地址即可&#xff08;前提它能用&#xff09;&#xff0c; 到了下图即可点击下载&#xff0c;…

通信算法之179: 单载波频域均衡系统的帧结构2

一。帧结构 &#xff08;2&#xff09; &#xff08;3&#xff09;