【vue2】组件基础与组件传值(父子组件传值)

news2024/11/16 17:48:12

1d43f75f092a4050a8ce31e2d85f6868.gif

🥳博       主:初映CY的前说(前端领域)

🌞个人信条:想要变成得到,中间还有做到!

🤘本文核心:组件基础概念与全局|局部组件的写法、组件之间传值(父传子、子传父)


目录

一、组件基础

1.组件初印象

2.组件组成

3.组件的分类与使用

全局|局部组件案例:

【额外补充】

二、组件传值

1.父传子

2.子传父

父子组件案例:


一、组件基础

1.组件初印象

1.概念:

组件是把页面上可重用的部分封装成组件,方便项目的开发的维护

2.本质:

组件是有HTML结构,css样式,js业务逻辑的HTML自定义标签(下面详解)

上述这个描述可能存在一点点抽象,vue组件这个描述与我们之前学过的div用大盒子装载是一个意思的。我们拿官网的图来给兄弟姐妹们讲解:

上述我们之前一般是用三个大的div(Header、Main、Aside)来封装我们的页面的再细分下去其他模块结构,现在我们用vue组件表示来就是再Root这个根组件中用引入对应的组件标签就可以了

比如上述结构可以用标签这样写:

<Root>

<Header></Header>

<Main><Article></Article><Article></Article></Main>

<Aside><Item></Item><Item></Item><Item></Item></Aside>

</Root>

记住组件的本质:组件是有HTML结构,css样式,js业务逻辑的HTML自定义标签

这样是不是对组件有点感觉了呢!那我们来看看我们的组件是怎么组成的

2.组件组成

一个组件(.vue文件)由三个标签组成:

小提示 : 快速生成组件三大部分的快捷键:<vue>

  • <template></template>标签,这里写组件的html结构
  • <script></script>标签,这里写组件的js代码
  • <style></style>标签,这里写组件的css代码

接下来我们来看个实际的例子

(小提示:按下<可快速生成一个.vue后缀的结构)

 下面这张图兄弟姐妹们仔细看,对我们学vue很重要呦

组件 = (页面)盒子 = (html)自定义标签(HTML+CSS+JS) = (代码).vue文件 = (内存)vue实例

3.组件的分类与使用

我们的组件分为两种:①局部组件 ②全局组件

1.局部组件

就是在当前的.vue后缀文件中生效,出了当前.vue后缀的文件就失效。

下面我们来看看我们怎么使用我们的组件:

三大步:①导入 ②注册 ③使用

1.导入局部组件 : 在scrip标签中导入

​    		import 组件名 from '组件路径'

2.挂载组件 : 在export default里面写一个属性components

​    	export default {

​      		components: {

​        		"标签名": 组件名
​      		}
​    	}

3.使用组件 : 像标签一样使用即可,组件可以理解为一个自定义标签

<组件名></组件名>

全局|局部组件案例:

下面我创建两个.vue文件

1.App.vue

<template>
  <!-- 1.组件html代码,组件默认会把template里面的根元素作为挂载点因此下面不需要写el -->
  <!-- 为什么组件data必须是一个函数 :因为组件是需要复用的,如果组件data是一个对象,那么组件在复用的时候就会使用相同的对象地址。一旦在一个地方被修改,其他的也会跟着修改。
        如果组件data是一个函数,组件在每一次复用的时候就会调用这个函数得到一个全新的对象,这样就可以做到在复用的时候每个组件之间的数据都是独立的,互不影响。 -->
  <div>
    <h1>我是App.vue</h1>
    <!-- 1.组件的使用 -->
    <MyPens></MyPens>

  </div>
</template>

<script>
// 1.组件业务js导入

import MyPens from '@/components/MyPens.vue'


export default {
  // 2.组件的注册
  components: {MyPens},
  // 存放vue的实例对象
  data() {
    return {
      // 在这里写data数据.必须是函数!!!,{}本质是new出来了一个
    }
  },
  methods: {},
  computed: {},
}
</script>

<style>
/* 3.组件的样式 */

</style>

2.MyPens.vue

<template>
<div> 
存放HTML结构,不写标签就会报错
<hr>
{{ msg }}
</div>
<!-- 
  1.组件中的最外层父元素只能有一个,不能添加两个平级父元素
  正确:  <div> <div></div> <div>
  错误:   <div></div> <div></div> -->
</template>

<script>
// 2.js代码,写组件js业务逻辑
export default {
    //之前vue实例的代码写在这里:可以放data,methods,计算属性、侦听器等
    //注意哟,组件里面的data是一个函数,返回值就是之前vue实例中的data对象
    data(){
        return{
            msg:'我是初映CY,我是放在MyPens中的'
        }
    },
}
</script>

<style>
/* 3.css:写组件样式 */
</style>

上述我们写了两个.vue分别为App.vue与MyPens.vue,我们在App.vue中引入我们MyPens.vue中的文件。

2.全局组件

使用方法与局部组件一样,唯一区别就是该组件的注册是在main

1.组件分类:

1.局部组件    2.全局组件

1.局部组件:

注册方法与局部组件注册一致,但是注册不在需要的.vue文件中注册,而是在main.js文件中注册

main.js(核心代码如下)

import MyButton from "@/components/MyButton.vue"//文件路径
Vue.component('MyButton',MyButton)//注册全局

 下面我们引入下我们的<MyButton><MyButton>组件到别的文件中

 我们引入了<MyButton><MyButton>到App与MyPens文件中,我们打开App.vue 

 可以看到我们的全局组件引入成功啦,以上就是全局与局部组件的使用方法。


【额外补充】

①浏览器默认打开加载App.vue文件

问题引入:为什么我们浏览器打开的默认是App.vue的文件呢?其实是因为我们在main.js中确定了App.vue是跟根文件入口,我们项目打开默认走的就是App.vue

这是我们的main.js文件现在的情况:

 当我们修改了框起来的配置之后的样子:

 当我们按照这个配置重新运行的时候页面加载的是:(在终端使用命令npm run serve)

可以发现我们成功的将页面的默认加载文件给更改了,改成了MyPens.vue。

②提高子组件css样式的权重

问题引入:当我们的子组件与父(根组件)有重名的的时候,我们是优先加载哪一个的css样式呢?

当我们MyPens.vue与App.vue都有个大div类名为color,并且我们都设置了相同的css样式:

同类名:

同css样式:

 我们在浏览器中查看效果:

发现了我们子与父发生了同名的css样式,我们优先加载的是父(根)组件的。但是我们需要子属性的咋办?使用scoped属性即可

可见当我们在子组件中加载了scoped属性之后,我们子组件的样式就不会被覆盖掉,而是子显示子组件的样式,父显示父组件的样式。


二、组件传值

1.父传子

父传:

父中用v-bind来传数据

如:(v-bind:"属性名" =属性值      该指令可简写为:属性名="属性值")

<子组件> 

:arr="list"//这两种写法均可,推荐使用这种
 v-bind:id="item.id"

</子组件> 

子收:

子组件中声明props来接收

props写的有两种:

①不声明数据类型写法(不推荐使用)

props:["属性名","属性名"]

 如:

props:["name","price","id"]

注意点:是用数组包裹属性名

②声明数据类型写法(推荐使用)

   对象名: {

      type: 数据类型, //注意前面需要加:解析不然是字符串类型

      default: xxx, //默认值,可以不用写默认值

    },

 如: 

  props: {
    price: {
      type: Number, //注意前面需要加:解析不然是字符串类型
      default: 100, //默认值
        }
    }

2.子传父

子传:

 this.$emit('方法名', 传递的数据)

  如:

this.$emit('price', this.id)

注意点:方法名的书写需要引号

父收:

<子组件>

        @子组件定义的方法名='新方法名'

</子组件>

如:

我们在父组件中导入组件并且讲方法名命名为dochange

    <myGoods
      @price="doChange"
    ></myGoods>

在methods:{}中重新定义我们的方法dochange(此处是子组件传递过来的数据),这样我们父子传值就完成了。

  methods: {
    // 接收MyGoods传来的值 3.根据定义事件来写属于我们的方法
    doChange(id) {
      //看子文件中传入的事件对象
      console.log(id)
      this.list.forEach((element) => {
        if (element.id === id) {
          element.price--
        }
      })
    },
  },

父子组件案例:

子组件MyGoods.vue

<template>
  <div class="box">
    <!-- 2.获取data中的值 -->
    <p>商品名称:{{ name }}</p>
    <p>商品价格:{{ price }}</p>
    <p>商品编号:{{ id }}</p>
    <button @click="doClick">点我来一🔪</button>
  </div>
</template>

<script>
export default {
  // 1.父传子(单项数据流):子组件中声明props,会平铺到数据中
  // props:["name","price","id"]
  // 上述写法不可传指定类型值,因此我们优化下写法:
  props: {
    name: String,
    price: {
      type: Number, //注意前面需要加:解析不然是字符串类型
      default: 100, //默认值
    },
    id: {
      type: [String, Number],
      required: true, //必传
    },
  },
  methods: {
    // 2.&emit:子传父 自定义事件
    doClick() {
      // price是我们自定义的方法,this.id是传入的实参
      this.$emit('price', this.id)
      // this.price-- //子组件与父组件绑定了,当只在子组件修改的时候,与父组件不同步因此会报错。一般处理数据都是子传父
      // console.log(this.price);
    },
  },
}
</script>

<style scoped>
div {
  border: 2px solid rgb(6, 58, 199);
}
</style>

父组件MyGoods.vue

<template>
  <div>
    <h1>我是父组件</h1>
    <!-- 3.使用组件 -->
    <myGoods
      v-for="item in list"
      :key="item.id"
      :name="item.name"
      :price="item.price"
      :id="item.id"
      @price="doChange"
    ></myGoods>
  </div>
</template>

<script>
// 1.导入组件
import MyGoods from '@/components/MyGoods.vue'
export default {
  components: { MyGoods },
  //2. 注册事件
  data() {
    return {
      list: [
        {
          name: '苹果手机',
          price: 8888,
          id: 1,
        },
        {
          name: '小米手机',
          price: 5888,
          id: 2,
        },
        {
          name: '华为手机',
          price: 7888,
          id: 3,
        },
      ],
    }
  },
  methods: {
    // 接收MyGoods传来的值 3.根据定义事件来写属于我们的方法
    doChange(id) {
      //看子文件中传入的事件对象
      console.log(id)
      this.list.forEach((element) => {
        if (element.id === id) {
          element.price--
        }
      })
    },
  },
}
</script>

<style>
div {
  border: 2px solid rgb(234, 226, 12);
}
</style>

好了兄弟姐妹们,先看下实际的效果:


可以看到我们的传值是完全OK的,父组件App.vue里面的数据与我们子文件MyGoods里面的数据是一摸一样的。可得知这两者数据相同并且得到了修改。

下面我们来尝试下,我们父传子之后,我们子不传递给父的情况:

这张图就灵活的显示了当我们在子组件中不传递数据给我们的父组件时,我们只是在我们的页面修改数据,这样就出现了一个小小的BUG,我们页面显示的(子组件数据)与我们App.vue中的数据并不是同步更新的,且当我们点击 来一刀 的时候右上交也会有报错提示。所以可以得出一个结论:当我们需要修改父中的数据我们需要传递过去给父改,我们的props是单项传输之读取的,需要$emit()传过去。

各位兄弟姐妹们,感谢你看到了这里!如果代码注释有不清晰的地方,欢迎大家留言,我会解答喔

下篇文章将讲解【组件进阶与插槽】的用法,本专栏将持续更新~~~~~~

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

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

相关文章

rcfile和orcfile

一、数据存储要考虑哪些方面 数据加载时间 Facebook数仓每天存储的数据量超过20TB&#xff0c;数据加载既有磁盘I/O又有网络传输&#xff0c;时间占用大 快速的数据查询 低的空间占用 数据压缩/数据编码 适合多种查询模式 如果所有人都查相同的字段&#xff0c;那么就可以针…

QT添加使用图片与UI资源

QT添加使用图片与UI资源1 QT添加使用图片资源1.1 添加新文件1.2 添加QT - QT Resources File 【UI资源文件】1.3 命名资源包名称 并 添加到项目文件1.4 .pro 文件发生变化 art.qrc1.5 点击qrc文件&#xff0c;添加现有文件 - 添加进去的图片文件可以进行正常引用。1.6 修改样式…

分布式任务处理xxljob

7.1 分布式任务处理 7.1.1 什么是分布式任务调度 视频上传成功需要对视频的格式进行处理&#xff0c;如何用Java程序对视频进行处理呢&#xff1f;这里有一个关键的需求就是当视频比较多的时候我们如何可以高效处理。 如何去高效处理一批任务呢&#xff1f; 1、多线程 多线…

通过Docker启动DB2,并在Spring Boot整合DB2

1 简介 DB2是IBM的一款优秀的关系型数据库&#xff0c;简单学习一下。 2 Docker安装DB2 为了快速启动&#xff0c;直接使用Docker来安装DB2。先下载镜像如下&#xff1a; docker pull ibmcom/db2:11.5.0.0 启动数据库如下&#xff1a; docker run -itd \--name mydb2 \--…

Allegro如何导入和导出Pin Delay操作指导

Allegro如何导入和导出Pin Delay操作指导 在做PCB设计等长设计的时候,Pin Delay是个非常重要的数据,关系到信号的长度,Allegro支持把Pin Delay数据导入到PCB中,并且还支持导出,如下图 具体操作如下 导入Pin Delay,选择File选择Import

图论基础: 邻接矩阵与邻接表(c++实现)

文章目录邻接矩阵邻接表邻接矩阵 邻接矩阵&#xff08;Adjacency Matrix&#xff09;是表示顶点之间相邻关系的矩阵。 设G(顶点&#xff0c;边)&#xff1a;G(V,E)是一个图。其中V{v1,v2,…,vn} [1] 。G的邻接矩阵是一个具有下列性质的n阶方阵&#xff1a; 无向图的邻接矩阵…

手眼标定,9点标定过程及其运算

在工业领域常常会遇到将相机安装在机器手中&#xff0c;由相机快速引导机器手进行工作的方式。其中9点标定的作用是将图像的坐标转化为机器手的坐标。 9点标定的作用意义&#xff1a; 1.计算像素当量&#xff0c;通过9点标定后的计算&#xff0c;可以得出一个由像素值转化为机器…

水平分表、分库和垂直分表、分库和公共表的代码实现和讲解

文章目录一、环境准备二、水平分表1.概念2.代码三、水平分库1.概念2.代码四、垂直分表1.概念2.代码五、垂直分库1.概念2.代码六、公共表1.概念2.代码一、环境准备 操作系统&#xff1a;Win10数据库&#xff1a;MySQL5.7JDK&#xff1a;64位 jdk1.8.0_202应用框架&#xff1a;s…

DOS和DDOS攻击和防御(ATTACK)

目录 一、DOS攻击和DDOS攻击的区别 第一、我们可以从他们两个的英文全称上来看初步的区别 第二、攻击方法不同 二、DOS和DDOS攻击的实现方式 1.DOS攻击 1、SYN Flood(是DOS和DDOS攻击方式之一) 2、UDP洪水攻击 3、Ping洪流攻击 4、teardrop攻击 5、Land攻击 6、Smurf攻击 7、Fr…

【 uniapp - 黑马优购 | 登录与支付 1】登录组件布局实现、用户信息布局与渲染

个人名片&#xff1a; &#x1f43c;作者简介&#xff1a;一名大二在校生&#xff0c;讨厌编程&#x1f38b; &#x1f43b;‍❄️个人主页&#x1f947;&#xff1a;小新爱学习. &#x1f43c;个人WeChat&#xff1a;见文末 &#x1f54a;️系列专栏&#xff1a;&#x1f5bc;…

设计模式-原型模式

设计模式-原型模式一 官方定义二 案例演示解决方案一 - 一般实现方式实现过程案例分析解决方案二使用场景实现过程一实现过程 二案例分析三 浅拷贝和深拷贝浅拷贝问题演示实现过程案例分析解决方案-----深拷贝实现方式一&#xff1a;重写clone()方法扩展思考一 官方定义 原型模…

在VMware 虚拟机(Win7)中还原真机Ghost备份的Win10系统

要求&#xff1a; 将真机Ghost备份的Win10系统还原到VMware安装的虚拟机&#xff08;Win7&#xff09;上 真机&#xff08;物理机&#xff09;&#xff1a;win10pro_pure_20220709.GHO &#xff08;备份的GHO文件&#xff09;&#xff1b;安装模式&#xff1a;Win10UEFIGPT 虚…

HashMap源码学习:红黑树原理详解

前言 JDK1.8后的HashMap引入了红黑树&#xff0c;在学习HashMap源码之前&#xff0c;了解了红黑树原理&#xff0c;及其如何通过代码进行实现后&#xff0c;在整体的看HashMap的源码就会简单很多。 概述 红黑树的特性 根节点必须是黑色节点。节点是红色或黑色。所有叶子都是…

Redis原理

Redis内部使用的是文件事件处理器file event handler,它是单线程的,所以Redis叫做单线程模型。它采用IO多路复用机制同时监听多个socket,将产生事件的socket压入内存队列中,事件分派器根据socket上的事件类型来选择对应的事件处理器进行处理。文件事件处理器包含4个部分:多…

【Java寒假打卡】Java基础-线程池

【Java寒假打卡】Java基础-线程池概述基本使用Executors创建指定上限的线程对象线程池-ThreadPoolExecutorvolatile概述 基本使用 package com.hfut.edu.test12;import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors;public class test1 {publ…

java+springboot笔记2023003

java的版本发布&#xff1a; 编译型语言是指使用专门的编译器&#xff0c;针对特定平台&#xff08;操作系统&#xff09; 将某种高级语言源代码一次性“翻译”成可被该平台硬件执行的机器码&#xff08;包括机器指令和操作数&#xff09;&#xff0c;并包装成该平台所能识别的…

Linux下更新curl版本

一、前景 由于低版本的curl存在一定的漏洞&#xff0c;会对我们的服务器安全造成问题&#xff0c;所以&#xff0c;我们需要将curl由低版本安装到高版本。 二、步骤 1、首先检测服务器安装的curl版本 curl --version 2、查看服务器安装的curl的安装包 rpm -qa curl 3、卸载…

基于springboot+mybatis+mysql+jsp房屋租赁管理系统(含论文)

基于springbootmybatismysqljsp房屋租赁管理系统&#xff08;含论文&#xff09;一、系统介绍二、所用技术三、功能展示三、其它系统四、获取源码一、系统介绍 包括管理员、房东、租客三种角色&#xff0c;外加游客(未登录情况) 出租类型包含整租和合租 权限 游客 < 租客 …

适合编程初学者的开源项目:小游戏2048(鸿蒙ArkTS版)

目标 为编程初学者打造入门学习项目&#xff0c;使用各种主流编程语言来实现。 2048游戏规则 一共16个单元格&#xff0c;初始时由2或者4构成。 1、手指向一个方向滑动&#xff0c;所有格子会向那个方向运动。 2、相同数字的两个格子&#xff0c;相遇时数字会相加。 3、每次…

用 JavaScript 写一个新年倒计时

目录前言&#xff1a;主题&#xff1a;运行结果&#xff1a;对应素材&#xff1a;代码实现思路&#xff1a;运行代码&#xff1a;春节的由来&#xff1a;总结&#xff1a;前言&#xff1a; 在春节即将到来&#xff0c;钟声即将响起&#xff0c;焰火即将燃起的日子里&#xff0c…