Vue进阶之单组件开发与组件通信

书接上篇,我们了解了如何快速创建一个脚手架,现在我们来学习如何基于vite创建属于自己的脚手架。在创建一个新的组件时,要在新建文件夹中打开终端创建一个基本的脚手架,可在脚手架中原有的文件中修改或在相应路径重新创建!

详细创建过程可点击“如何创建一个脚手架”查看

一、单组件开发

1、介绍

单文件组件 (即 .vue 文件) 是一种特殊的文件格式,使我们能够将一个 Vue 组件的模板、逻辑与样式封装在单个文件中。比如:

<template>
    <div class="header-comp">
    <h3>这是第一个组件程序</h3>
    </div>
  </template>
  
  <script>
  export default {
    name: 'Header'
  }
  </script>
  
  <style scoped>
  .header-comp{
    
    border: 3px solid red;
  }
  </style>

(1)在Header.vue文件里(在components目录中创建vue文件名为Header.vue),<template>写HTML结构,像展示商品列表组件;

(2)<script>export default导出一个对象,这个对象代表了该组件的相关配置和属性;其中name: 'Header'给组件指定了一个名称为Header这个名称在调试、递归组件等场景下可能会用到,方便在Vue应用中对组件进行识别和引用

(3)<style>写样式,加scoped表示这个样式只会作用于当前组件内部的元素,避免全局样式污染,让代码模块化、可维护,团队协作分工明确。

这段代码定义了一个简单的Vue组件,包含了组件的结构、基本属性配置以及样式设定,可在Vue项目中作为一个独立的功能模块被使用并展示相应的内容和样式。

2、单文件如何运行

Vite会根据main.js文件中挂载的根组件(通常是App.vue)来渲染页面。如果要查看单组件,需要在App.vue中使用你开发的单组件。如:

<template>
  <div>
    <Header />
  </div>
</template>

<script>
import Header from './components/Header.vue';

export default {
  name: 'App',
  components: {
    Header
  }
};
</script>

<style>

</style>

(1)在<template>中,利用<div>包裹整个页面的主要内容,其中包含一个<Header/>组件标签,表明当前的App组件中使用了名为Header的组件(要引用那个.vue文件就写该文件名)。

(2)在<script>中

  • 通过import语句从要引用的文件路径中引用组件(Header组件),使App组件可以使用Header组件。
  • 再通过export default导出一个对象,这个对象代表了App组件的配置信息。
  • name: 'App':给这个组件定义了一个名称为App,在调试工具或者进行组件递归引用等场景下,这个名称有助于识别组件。
  • components: { Header }:这里定义了一个名为components的对象属性,将引入的Header组件添加到其中,使得在模板部分可以直接使用<Header />这种简短的标签形式来调用该组件,如果没有在这里注册,在模板中使用组件就会报错。

拓展

自闭合标签(<Header />):这种写法更加简洁适用于组件没有内容插槽(即不需要在组件标签内部添加其他内容)的情况。

双标签(<Header></Header>):当组件定义了插槽需要在使用组件的地方往组件内部添加内容时,双标签形式就很有用。

打开浏览器访问项目对应的网址则出现以下内容。 

 这段代码完整地构建了一个简单的Vue组件,涵盖了组件的视觉呈现(通过 <template>)、逻辑定义(通过 <script>)以及样式设置(通过 <style>)三个重要方面,可在Vue项目中作为一个基础的功能单元进行集成和使用。

3、弹窗提示

通过简单的单组件开发我们可以发现,里面的部分内容与我们之前所学的知识相似,或许我们也可以用该特性创建组件的其他功能,以弹窗提示为例,我们创建一个组件,当点击按钮时会出现弹窗提示我们。

(1)与前面一样先创建一个.vue文件,命名为Nav,大致内容与前面的Header.vue文件相似,不同的是,我们要在div内创建一个button按钮,并绑定一个事件,通过v-on:click="alert_msg"指令,将按钮的点击动作与名为alert_msg的函数进行关联,当按钮被点击时,会触发相应的函数执行。

(2)在<script setup>中,定义一个函数,用于当被调用时弹出一个警告框

代码如下:

<template>
  <div class="nav-comp">
    <h3>这是第二个组件程序</h3>
    <button v-on:click="alert_msg">点击我</button>
  </div>
</template>

<script setup>
const alert_msg = () => {
  alert('按钮被点击')
}
</script>
<style scoped>
.nav-comp {
  border: 3px solid red;
}
</style>

App.vue的内容与调用Header文件一样,只需修改对应文件名和路径即可,注意路径不要写错,也可以直接添加Nav文件名,这样则会同时调用两个,这里我就只调用Nav文件

<template>
  <div>
    <Nav />
  </div>
</template>
<script>
import Nav from './components/Nav.vue'
export default {
  name: 'App',
  components: {
    Nav
  },
}
</script>
<style></style>

打开浏览器访问项目对应的网址则出现以下内容:

点击按钮后

二、父组件向子组件传递数据

在Vue框架中,父组件向子组件传递数据通常是通过使用props属性来实现的props是子组件用来接收来自父组件的数据的一个自定义属性。父组件通过在模板中绑定props到子组件标签上,将数据传递给子组件。子组件则在其props选项中声明接收的数据,并可以在其模板或计算属性中使用这些数据。

1、父组件的定义(App.vue)

(1)<template>

父组件需要在模板中使用子组件标签,这里使用了Header子组件,通过v-bind(简写:)将数据绑定到子组件的props属性上。如:将userName和userAge这两个数据分别绑定到子组件的propName和propAge属性上,实现了从父组件向子组件传递数据的操作。

<template>
  <div>
    <Header :propName="userName" :propAge="userAge" />
  </div>
</template>

(2)<script>

通过import语句引入了Header.vue这个子组件,以便在父组件的模板中使用它。然后定义了两个常量userName和userAge,并分别赋予了具体的值。这里的userName和userAge就是要传递给子组件的数据。

<script setup>
import Header from './components/Header.vue';
const userName = '李四';
const userAge = 25;
</script>

2、子组件(Header.vue)

(1)<template>

子组件的模板部分目前只是简单地展示了一个文本“我是页面头部(子组件)”,后续可以根据需求进一步扩展这里的展示内容,比如展示从父组件接收到的姓名和年龄等数据。

<template>
    <div>
        <h3>我是页面头部(子组件)</h3>
    </div>
</template>

(2)<script>

<script setup>
    const props = defineProps(
        ["propName", "propAge"]
    )
    console.log(props);
</script>
  • defineProps(["propName", "propAge"])是Vue 3中定义组件接收父组件传递属性的方式。它声明了这个子组件会接收来自父组件的propName和propAge两个属性。
  • const props = defineProps(["propName", "propAge"]);将接收到的属性赋值给props常量,方便后续在组件内使用这些属性。
  • console.log(props);这行代码会在浏览器控制台打印出接收到的属性对象,这样可以直观地看到父组件传递过来的数据内容,格式类似于{ "propName": "李四", "propAge": 25 },具体的值取决于父组件传递的数据。

(3)<style>与前面内容一样

  • <style scoped>
        div {
            width:25%;
            background-color: rgb(238, 156, 156);
            color: blanchedalmond;
        }
    </style>

    打开浏览器访问项目对应的网址则出现以下内容:

数据传递的注意事项

props传递的数据是单向下行的,即父组件的数据更新会流向子组件,但子组件不应直接修改props数据

如果需要在子组件中转换或使用props数据,可以使用计算属性或定义本地data属性

对于对象或数组类型的props,由于它们是通过引用传递的,子组件中对这些props的修改会影响父组件的状态

通过这种方式,Vue实现了组件间的数据流动和通信,使得父子组件之间的数据关系清晰易于管理

 、子组件向父组件传递事件

通过父组件向子组件传递数据的学习,我们已经知道了 Vue 是单向下行数据流, 子组件更改 props 中的数据不会触发父组件数据的改变, 但是由于响应式原理,父组件数据的改变会导致子组件 props 中值的改变。

那么我们怎么才能在子组件中改变父组件中的数据呢?

1、子组件(Header.vue)

(1)<template>

子组件通过emit触发自定义事件。  每个按钮都绑定了一个点击事件,分别是sendGetPersonData和sendAddPersonData,点击这些按钮将会触发相应的方法来执行特定操作,即向父组件发送数据。

<template>
    <div>
        <button @click="sendGetPersonData">发送getPerson数据</button>
        <button @click="sendAddPersonData">发送addPerson数据</button>
    </div>
</template>

扩展

在Vue.js里,$emit是Vue实例的一个方法。它的作用是在子组件中触发一个自定义事件,并且可以携带数据传递给父组件。就像是子组件在特定场景下(比如按钮点击、数据变化等)发出一个信号,父组件如果监听了这个信号,就能收到并做出相应的反应。 

(2)<script>

通过定义了两个可以向父组件发射的自定义事件,分别是getPerson和addPerson。当点击按钮时,会通过emit对象发送一个事件并同时传递一个数据对象给父组件

<script setup>
    const emits=defineEmits(["getPerson","addPerson"]);
    const sendGetPersonData=()=>{
        emits("getPerson",{name:"李雷",age:20});
    };
    const sendAddPersonData=()=>{
        emits("getPerson",{name:"韩梅梅",age:18});  
    }
</script>

 (3)<style scoped>

与前面一样

<style scoped>
    div{
        width: 50%;
        background-color: antiquewhite;
    }
</style>

2、父组件(App.vue)

(1)<template>

在App.vue的模板中,引入了Header.vue组件,并通过@符号监听Header组件发射的getPerson和addPerson自定义事件

<template>
<div>
    <Header @getPerson="handleGetPerson" @addPerson="handleAddPerson"/>

</div>
</template>

 (2)<script setup>

通过import语句引入了Header.vue组件,以便在App.vue中使用。通过箭头函数,当接收到该事件时会在控制台打印出接收到的事件以及相关的数据内容。

<script setup>
    import Header from './components/Header.vue';
    const handleGetPerson=(data)=>{
      console.log("接收到getPerson事件,数据为,",data);
      
    };
    const handleAddPerson=(data)=>{
      console.log("接收到addPerson事件,数据为,",data);
    }
</script>
<style></style>

主要目的是实现子组件Header.vue向父组件App.vue发送自定义事件及相关数据,父组件通过监听这些事件来处理接收到的数据。

打开浏览器访问项目对应的网址则出现以下内容:

点击第一个按钮时

点击第二个按钮时

四、跨组件通信

跨组件通信是指在一个应用中,不同组件之间进行数据传递或事件通知的过程。如:通过Vue的自定义事件机制,实现了下级组件向上级组件发送数据的跨组件通信功能。当点击下级组件中的按钮时,会将指定的数据发送给shang,App.vue接收到数据后会在控制台打印相关信息,并在页面上展示接收到的数据内容。

1、下级组件(Header.vue)

(1)<template>

设置一个按钮绑定了sendDataToParent,点击按钮将触发数据发送操作,目的是把数据发送给上级组件(App.vue)

<template>
    <div>
      <button @click="sendDataToParent">发送数据给上级组件</button>
    </div>
  </template>

(2)<script setup>

通过import { defineEmits } from 'vue'引入了Vue中用于定义可发射自定义事件的函数。再定义一个自定义事件,用于向父组件发送数据。通过emits对象发射事件,并同时传递一个数据对象给父组件。这样就完成了从下级组件(Header.vue)向上级组件(App.vue)发送数据的准备工作。

 <script setup>
  import { defineEmits } from 'vue';
  const emits = defineEmits(['getData']);
  const sendDataToParent = () => {
    emits('getData', { name: '张三', age: 25 });
  };
  </script>

2、上级组件(App.vue)

(1)<template>

首先引入Header.vue组件,通过@监听Header组件发射的自定义事件。通过v-if指令判断是否有值。如果有值(即接收到了来自子组件的数据),则展示接收到的数据内容

template>
  <div>
    <Header @getData="handleDataReceived" />
    <div v-if="receivedData">接收到的数据:姓名 - {{ receivedData.name }}, 年龄 - {{ receivedData.age }}</div>
  </div>
</template>

 (2)<script setup>

首先通过import语句引入了Header.vue组件,以便在App.vue中使用。通过ref创建一个响应式数据,用于存储从子组件接收到的数据。再使用箭头函数设置当接收到该事件时,会在控制台打印出接收到的事件以及相关的数据内容,然后将接收到的数据赋值给receivedData.value,以便在模板部分能够正确展示出来。

<script setup>
import Header from './components/Header.vue';
import { ref } from 'vue';

// 用于存储接收到的数据
const receivedData = ref(null);
// 处理从子组件接收到的数据
const handleDataReceived = (data) => {
  console.log('接收到来自子组件的数据:', data);
  receivedData.value = data;
};
</script>

打开浏览器访问项目对应的网址则出现以下内容:

点击按钮后

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Linux网络编程】第四弹---构建UDP服务器与字典翻译系统:源码结构与关键组件解析

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】【C详解】【Linux系统编程】【Linux网络编程】 目录 1、UdpServer.hpp 1.1、函数对象声明 1.2、Server类基本结构 1.3、构造函数 1.4、Start() 2、Dict.hpp…

数字IC后端设计实现之分段长clock tree经典案例

最近发现很多读者问到分段长clock tree的做法&#xff0c;小编今天给大家分享几个SoC芯片中复杂时钟结构设计的分段长clock tree的应用案例。希望对各位的学习和工作有所助益。 数字后端设计实现之时钟树综合实践篇 数字IC后端实现专家都具备哪些技能&#xff1f;&#xff08…

计算机毕业设计Spark+SpringBoot旅游推荐系统 旅游景点推荐 旅游可视化 旅游爬虫 景区客流量预测 旅游大数据 大数据毕业设计

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

EasyMedia播放rtsprtmp视频流

学习链接 MisterZhang/EasyMedia - gitee地址 EasyMedia转码rtsp视频流flv格式&#xff0c;hls格式&#xff0c;H5页面播放flv流视频 文章目录 学习链接介绍步骤easydarwin启动rtsp服务&#xff0c;ffmpeg推送摄像头&#xff08;模拟rtsp视频流&#xff09;nginx添加rtmp支持…

【Linux】开启你的Linux之旅:初学者指令指南

Linux相关知识点可以通过点击以下链接进行学习一起加油&#xff01; 在 Linux 开发中&#xff0c;GDB 调试器和 Git 版本控制工具是开发者必备的利器。GDB 帮助快速定位代码问题&#xff0c;Git 则提供高效的版本管理与协作支持。本指南将简明介绍两者的核心功能与使用技巧&…

SpringBoot-问题排查 Controller全局打印入参,返回值,响应时间,异常日志

问题: 想要打印每次请求的入参,返回值,响应时间,异常日志,如果给每个方法挨个添加打印日志非常麻烦 解决方案: 使用切面的方式将所有的Controller每个方法加入切入点使用环绕通知的方式可以在切入点执行前后执行切面,符合我们的需求在方法执行前后打印相关日志忽略LogIgnore注解…

mysql数据库varchar截断问题

用了这么多年mysql数据库&#xff0c;才发现varchar是可以截断的&#xff0c;而且是在我们线上数据库。个人觉得dba的这个设置是非常有问题的&#xff0c;用户往数据库里存东西&#xff0c;就是为了以后用的&#xff0c;截断了存放&#xff0c;数据不完整&#xff0c;就用不了了…

C++草原三剑客之一:继承

为王的诞生献上礼炮吧&#xff01; 目录 1 继承的概念及其定义 1.1 继承的概念 1.2 继承的定义 1.2.1 定义格式 1.2.2 继承方式以及继承基类成员访问方式的变化 1.3 继承类模板 2 基类和派生类之间的转换 3 继承中的作用域 3.1 隐藏规则 3.2 两道考察继承作用的相关…

Crash-SQLiteDiskIOException

目录 相关问题 日志信息 可能原因 问题排查 相关问题 蓝牙wifi无法使用 日志信息 可能原因 磁盘空间不足&#xff1a;当设备上的可用存储空间不足时&#xff0c;SQLite无法完成磁盘I/O操作&#xff0c;从而导致SQLiteDiskIOException。 数据库文件损坏&#xff1a;如果数…

6.824/6.5840 Lab 1: Lab 3: Raft

漆昼中温柔的不像话 静守着他的遗憾啊 旧的摇椅吱吱呀呀停不下 风卷走了满院的落叶落花 ——暮色回响 完整代码见&#xff1a; https://github.com/SnowLegend-star/6.824 在完成Lab之前&#xff0c;务必把论文多读几遍&#xff0c;力求完全理解Leader选举、log日志等过程。 …

【C++动态规划 BFS 博弈】3283. 吃掉所有兵需要的最多移动次数|2473

本文涉及知识点 C动态规划 CBFS算法 数学 博弈 LeetCode3283. 吃掉所有兵需要的最多移动次数 给你一个 50 x 50 的国际象棋棋盘&#xff0c;棋盘上有 一个 马和一些兵。给你两个整数 kx 和 ky &#xff0c;其中 (kx, ky) 表示马所在的位置&#xff0c;同时还有一个二维数组 …

6.824/6.5840 Lab 2: Key/Value Server

故事里能毁坏的只有风景 谁也摧毁不了我们的梦境 弦月旁的流星划过了天际 我许下 的愿望 该向谁 去说明 ——我是如此相信 完整代码见&#xff1a; https://github.com/SnowLegend-star/6.824 还是那句话&#xff0c;尽量只是参考思路而不是照抄 先阅读几遍实验说明的Introd…

Linux-异步IO和存储映射IO

异步IO 在 I/O 多路复用中&#xff0c;进程通过系统调用 select()或 poll()来主动查询文件描述符上是否可以执行 I/O 操作。而在异步 I/O 中&#xff0c;当文件描述符上可以执行 I/O 操作时&#xff0c;进程可以请求内核为自己发送一个信号。之后进程就可以执行任何其它的任务…

R 语言科研绘图第 1 期 --- 折线图-基础

在发表科研论文的过程中&#xff0c;科研绘图是必不可少的&#xff0c;一张好看的图形会是文章很大的加分项。 为了便于使用&#xff0c;本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中&#xff0c;获取方式&#xff1a; R 语言科研绘图模板 --- sciRplothttps://mp.…

企业中数据防泄漏如何防范?有哪些防泄密措施?

企业数据不仅是业务运营的核心&#xff0c;也是企业竞争力的关键所在。 然而&#xff0c;随着信息技术的快速发展&#xff0c;数据泄露的风险也随之增加。 数据一旦泄露&#xff0c;不仅可能导致企业经济损失&#xff0c;还可能损害企业声誉&#xff0c;甚至引发法律纠纷。 …

汽车控制软件下载移动管家手机控车一键启动app

移动管家手机控制汽车系统是一款实现车辆远程智能控制的应用程序‌。通过下载并安装特定的APP&#xff0c;用户可以轻松实现以下功能&#xff1a;‌远程启动与熄火‌&#xff1a;无论身处何地&#xff0c;只要有网络&#xff0c;即可远程启动或熄火车辆&#xff0c;提前预冷或预…

基于事件驱动构建 AI 原生应用

作者&#xff1a;寒斜 AI 应用在商业化服务的阶段会面临诸多挑战&#xff0c;比如更快的服务交付速度&#xff0c;更实时、精准的结果以及更人性化的体验等&#xff0c;传统架构限制于同步交互&#xff0c;无法满足上述需求&#xff0c;本篇文章给大家分享一下如何基于事件驱动…

如何查看阿里云ddos供给量

要查看阿里云上的 DDoS 攻击量&#xff0c;你可以通过阿里云的 云盾 DDoS 防护 服务来进行监控和查看攻击数据。阿里云提供了详细的流量监控、攻击日志以及攻击趋势分析工具&#xff0c;帮助用户实时了解 DDoS 攻击的情况。以下是九河云总结的查看 DDoS 攻击量的步骤&#xff1…

华为HarmonyOS 让应用快速拥有账号能力 - 获取用户手机号

场景介绍 当应用对获取的手机号时效性要求不高时&#xff0c;可使用Account Kit提供的手机号授权与快速验证能力&#xff0c;向用户发起手机号授权申请&#xff0c;经用户同意授权后&#xff0c;获取到手机号并为用户提供相应服务。以下只针对Account kit提供的手机号授权与快…

React 的学习记录一:与 Vue 的相同点和区别

目录 一、学习目标 二、学习内容1️⃣——React的特点 1.组件化设计 2.单向数据流 3.声明式 UI 4.虚拟 DOM 5.Hooks 6.JSX 7.React Native 三、React与vue的比较总结 四、总结 一、学习目标 时间&#xff1a;两周 内容&#xff1a; React的特点React的入门React的…