当前位置: 首页 > news >正文

Vue 组件化开发

文章目录

  • 前言
  • 组件化开发
    • 底部菜单 TabMenu
  • 父子组件相互传数据
    • 父传子:自定义属性
    • 子传父:自定义事件
    • 父子组件互传案例
  • 插槽 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),运行:
在这里插入图片描述

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

底部菜单 TabMenu

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

  1. 导入需要的子组件(在script标签内)
import TabMenu from '@/components/TabMenu.vue';  //@相当于src

或者写成:

import TabMenu from '../components/TabMenu.vue';

当然需要在components 文件夹下新建 TabMenu 视图:
在这里插入图片描述
详细代码:

<!-- 定义组件的模板 -->
<template><div><!-- 底部选项卡 --><ul class="tab-menu"><!-- 首页选项 --><li @click="gotoIndex"><i class="fa fa-home"></i><p>首页</p></li><!-- 发现选项 --><li @click="gotoBusiness"><i class="fa fa-compass"></i><p>发现</p></li><!-- 订单选项 --><li @click="gotoMyOrders"><i class="fa fa-file-text-o"></i><p>订单</p></li><!-- 我的选项 --><li @click="gotoMy"><i class="fa fa-user-o"></i><p>我的</p></li></ul></div>
</template><script>
// 引入路由
import router from '@/router';export default {data() {return {}},methods: {// 跳转到首页gotoIndex() {router.push('/')},// 跳转到个人中心gotoMy() {// 判断是否登录let login = sessionStorage.getItem('login')if (login == null) {// 未登录则跳转到登录页router.push('/login')} else{// 已登录则跳转到个人中心页router.push('/my')}},// 跳转到发现页gotoBusiness() {router.push('/business')},// 跳转到我的订单页gotoMyOrders() {router.push('/myOrders')}},components: {},computed: {},watch: {},mounted() {},
}
</script><style scoped>/* 底部选项卡样式 */.tab-menu{width: 100vw; /* 设置选项卡宽度为屏幕宽度 */height: 14vw; /* 设置选项卡高度为14vw */background-color: #fff; /* 设置选项卡背景色为白色 */border-top: 0.2vw solid #ddd; /* 设置选项卡上边框为0.2vw宽的灰色实线 */display: flex; /* 设置选项卡为弹性布局 */justify-content: space-around; /* 设置选项卡内子元素沿主轴间距相等 */align-items: center; /* 设置选项卡内子元素沿侧轴居中对齐 */position: fixed; /* 设置选项卡为固定定位 */left: 0; /* 设置选项卡距离左侧为0 */bottom: 0; /* 设置选项卡距离底部为0 */}/* 选项样式 */.tab-menu li{display: flex; /* 设置选项为弹性布局 */flex-direction: column; /* 设置选项内子元素排列方向为垂直方向 */justify-content: center; /* 设置选项内子元素沿主轴居中对齐 */align-items: center; /* 设置选项内子元素沿侧轴居中对齐 */color: #999; /* 设置选项内子元素颜色为灰色 */}
</style>
  1. 在 components 的配置项中注册子组件
components: {TabMenu},
  1. 在template中以标记的语法使用子组件
<TabMenu></TabMenu>  

在这里插入图片描述
当然在命令行中运行上这句:npm i font-awesome

效果:
在这里插入图片描述

父子组件相互传数据

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

以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.lryc.cn/news/614771.html

相关文章:

  • 零基础小白如何使用QGIS制作研究区地形区位图教程
  • SQL聚合函数:SUM与COUNT的区别
  • 算法训练之字符串
  • 04--模板初阶(了解)
  • 常见数据结构介绍(顺序表,单链表,双链表,单向循环链表,双向循环链表、内核链表、栈、队列、二叉树)
  • VMware使用NAT模式,使本机与虚拟机在不同的网络,并且虚拟机可以上网
  • VSCode 禁用更新检查的方法
  • C++归并排序
  • Flutter开发 Switch、SwitchListTile的基本使用
  • 机器学习概念1
  • 关于 Rust 异步(无栈协程)的相关疑问
  • 书生浦语第五期-L1G3-LMDeploy 课程
  • AI入门学习--如何对RAG测试
  • 讲一讲@ImportResource
  • 触觉导航新突破:Contactile 触觉传感器推动机器人 “零示教” 实现复杂曲面作业
  • 如何解决pip安装报错ModuleNotFoundError: No module named ‘transformers’问题
  • 线程同步相关知识
  • 构建高可用架构:ZDNS GSLB 在多数据中心场景下的应用与 F5 替换实践
  • Linux网络--1、网络基础
  • Java零散知识点
  • Claude Code:智能代码审查工具实战案例分享
  • 阶段二测试
  • 华为网路设备学习-28(BGP协议 三)路由策略
  • Latex中公式部分输入正体的字母\mathrm{c}
  • v-model双向绑定指令
  • 【工作笔记】Docker Desktop一直转圈加载不出来然后报错
  • 数据结构---二叉树(概念、特点、分类、特性、读取顺序、例题)、gdb调试指令、时间复杂度(概念、大O符号法、分类)
  • CSS:BFC
  • 深入解析Linux信号处理机制
  • DeepSeek辅助编写的带缓存检查的数据库查询缓存系统