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

Vue基础入门讲义(四)-组件化

在这里插入图片描述

文章目录

    • 1.引言
    • 2.定义全局组件
    • 3.组件的复用
    • 4.局部注册
    • 5.组件通信
      • 5.1.父向子传递props
      • 5.2.传递复杂数据
      • 5.3.子向父的通信

1.引言

在大型应用开发的时候,页面可以划分成很多部分。往往不同的页面,也会有相同的部分。例如可能会有相同的头部导航。

但是如果每个页面都独自开发,这无疑增加了开发的成本。所以会把页面的不同部分拆分成独立的组件,然后在不同页面就可以共享这些组件,避免重复开发。

2.定义全局组件

通过Vue的component方法来定义一个全局组件。

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>vuejs测试</title>
</head>
<body><div id="app"><!--使用定义好的全局组件--><counter></counter>
</div>
<script src="node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">//定义组件const counter = {template: "<button @click='num++'>你点击了{{num}}次;我记住了</button>",data() {return {num: 0}}};//全局注册组件;参数1:组件名称,参数2:组件Vue.component("counter", counter);var app = new Vue({el: "#app"});</script>
</body>
</html>
  • 组件其实也是一个Vue实例,因此它在定义时也会接收:data、methods、生命周期函数等
  • 不同的是组件不会与页面的元素绑定,否则就无法复用了,因此没有el属性。
  • 但是组件渲染需要html模板,所以增加了template属性,值就是HTML模板
  • 全局组件定义完毕,任何vue实例都可以直接在HTML中通过组件名称来使用组件了
  • data的定义方式比较特殊,必须是一个函数。

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

3.组件的复用

定义好的组件,可以任意复用多次:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>vuejs测试</title>
</head>
<body><div id="app"><!--使用定义好的全局组件--><counter></counter><counter></counter><counter></counter>
</div>
<script src="node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">//定义组件const counter = {template: "<button @click='num++'>你点击了{{num}}次;我记住了</button>",data() {return {num: 0}}};//全局注册组件;参数1:组件名称,参数2:组件Vue.component("counter", counter);var app = new Vue({el: "#app"});</script>
</body>
</html>

在这里插入图片描述
你会发现每个组件互不干扰,都有自己的num值。怎么实现的?

组件的data属性必须是函数!

当定义这个 <counter> 组件时,它的data 并不是像这样直接提供一个对象:

data: {num: 0
}

取而代之的是,一个组件的 data 选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝:

data: function () {return {num: 0}
}

如果 Vue 没有这条规则,点击一个按钮就会影响到其它所有实例!

4.局部注册

一旦全局注册,就意味着即便以后你不再使用这个组件,它依然会随着Vue的加载而加载。

因此,对于一些并不频繁使用的组件,会采用局部注册。

在外部定义一个对象,结构与创建组件时传递的第二个参数一致:

然后在Vue中使用它:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>vuejs测试</title>
</head>
<body>
<div id="app"><!--使用定义好的全局组件--><counter></counter><counter></counter><counter></counter>
</div>
<script src="node_modules/vue/dist/vue.js"></script>
<script>//定义组件const counter = {template: "<button @click='num++'>你点击了{{num}}次;我记住了</button>",data() {return {num: 0}}};//全局注册组件;参数1:组件名称,参数2:组件//Vue.component("counter", counter);var app = new Vue({el: "#app",//局部注册组件components: {counter: counter}});
</script>
</body>
</html>
  • components就是当前vue对象子组件集合。

    • 其key就是子组件名称
    • 其值就是组件对象的属性
  • 效果与刚才的全局注册是类似的,不同的是,这个counter组件只能在当前的Vue实例中使用

5.组件通信

通常一个单页应用会以一棵嵌套的组件树的形式来组织:
在这里插入图片描述

  • 页面首先分成了顶部导航、左侧内容区、右侧边栏三部分
  • 左侧内容区又分为上下两个组件
  • 右侧边栏中又包含了3个子组件

各个组件之间以嵌套的关系组合在一起,那么这个时候不可避免的会有组件间通信的需求。

5.1.父向子传递props

比如有一个子组件:

	Vue.component("introduce",{// 直接使用props接收到的属性来渲染页面template:'<h3>{{title}}</h3>',props:[title] // 通过props来接收一个父组件传递的属性
})
  • 这个子组件中要使用title属性渲染页面,但是自己并没有title属性
  • 通过props来接收父组件属性,名为title

父组件使用子组件,同时传递title属性:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>vuejs测试</title>
</head>
<body>
<div id="app"><!--使用定义好的全局组件--><introduce :title="msg"></introduce>
</div>
<script src="node_modules/vue/dist/vue.js"></script>
<script>//定义组件const introduce = {//使用props属性title的值渲染模版template: "<h2>{{title}}</h2>",//定义接收来自父组件的属性props: ["title"]};//全局注册组件;参数1:组件名称,参数2:组件Vue.component("introduce", introduce);var app = new Vue({el: "#app",data: {msg: "父组件中的msg属性的内容"}});
</script>
</body>
</html>

效果:

在这里插入图片描述

5.2.传递复杂数据

定义一个子组件:

    const myList = {template: '\<ul>\<li v-for="item in items" :key="item.id">{{item.id}} : {{item.name}}</li>\</ul>\',props: { // 通过props来接收父组件传递来的属性items: {// 这里定义items属性type: Array,// 要求必须是Array类型default: [] // 如果父组件没有传,那么给定默认值是[]}}};
  • 这个子组件可以对 items 进行迭代,并输出到页面。
  • 但是组件中并未定义items属性。
  • 通过props来定义需要从父组件中接收的属性
    • items:是要接收的属性名称
      • type:限定父组件传递来的必须是数组,否则报错;type的值可以是Array或者Object(传递对象的
        时候使用)
      • default:默认值,
default,如果是对象则需要写成方法的方式返回默认值。如:
default(){return {"xxx":"默认值"};
}

页面内容:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>vuejs测试</title>
</head>
<body>
<div id="app"><h2>学习的课程有:</h2><!-- 接受来自父组件的属性值,使用v-bind指向父组件的属性lessons;注意使用my-list --><my-list :items="lessons"></my-list>
</div>
<script src="node_modules/vue/dist/vue.js"></script>
<script>//定义组件const myList = {//可以使用双引号、单引号或者如下使用的 ` 飘号template: `<ul><li v-for="item in items" :key="item.id">{{item.id}}--{{item.name}}</li></ul>`,//定义接收来自父组件的属性props: {//定义模版中使用的属性items: {//必须为数组类型type: Array,//默认为空数组default: []}}};var app = new Vue({el: "#app",data: {msg: "父组件中的msg属性的内容",lessons: [{"id": 1, "name": "Java"},{"id": 2, "name": "PHP"},{"id": 3, "name": "前端"}]},//注册组件components: {//如果组件key和value一致可以简写如下myList}});
</script>
</body>
</html>

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

5.3.子向父的通信

来看这样的一个案例:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>vuejs测试</title>
</head>
<body>
<div id="app"><h2>num = {{num}}</h2><!--使用定义好的全局组件--><counter :snum="num"></counter>
</div>
<script src="node_modules/vue/dist/vue.js"></script>
<script>//定义组件const counter = {//组件只能是一个元素里面包裹其他元素;如下面,一个div包含两个按钮template: `<div><button @click="snum++">+</button><button @click="snum--">-</button></div>`,props: ["snum"]};//全局注册组件;参数1:组件名称,参数2:组件Vue.component("counter", counter);var app = new Vue({el: "#app",data: {num: 0}});
</script>
</body>
</html>
  • 子组件接收父组件的num属性
  • 子组件定义点击按钮,点击后对num进行加或减操作

尝试运行,好像没问题,点击按钮试试:
在这里插入图片描述
子组件接收到父组件属性后,默认是不允许修改的。怎么办?
既然只有父组件能修改,那么加和减的操作一定是放在父组件:

var app = new Vue({el: "#app",data: {num: 0},methods: {//父组件中定义操作num的方法numPlus() {this.num++;},numReduce() {this.num--;}}});

但是,点击按钮是在子组件中,那就是说需要子组件来调用父组件的函数,怎么做?
可以通过v-on指令将父组件的函数绑定到子组件上

<div id="app"><h2>num = {{num}}</h2><!--使用定义好的全局组件--><counter @plus="numPlus" @reduce="numReduce" :snum="num"></counter>
</div>

然后,当子组件中按钮被点击时,调用绑定的函数:

//定义组件const counter = {//组件只能是一个元素里面包裹其他元素;如下面,一个div包含两个按钮template: `<div><button @click="incrNum">+</button><button @click="decrNum">-</button></div>`,props: ["snum"],methods: {//点击模板中使用的方法incrNum() {return this.$emit("plus");},decrNum() {return this.$emit("reduce");}}};

完成页面如下:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>vuejs测试</title>
</head>
<body>
<div id="app"><h2>num = {{num}}</h2><!--使用定义好的全局组件--><counter @plus="numPlus" @reduce="numReduce" :snum="num"></counter>
</div>
<script src="node_modules/vue/dist/vue.js"></script>
<script>//定义组件const counter = {
//组件只能是一个元素里面包裹其他元素;如下面,一个div包含两个按钮template: `
<div>
<button @click="incrNum">+</button>
<button @click="decrNum">-</button>
</div>
`,props: ["snum"],methods: {
//点击模板中使用的方法incrNum() {return this.$emit("plus");},decrNum() {return this.$emit("reduce");}}};//全局注册组件;参数1:组件名称,参数2:组件Vue.component("counter", counter);var app = new Vue({el: "#app",data: {num: 0},methods: {
//父组件中定义操作num的方法numPlus() {this.num++;},numReduce() {this.num--;}}});
</script>
</body>
</html>
  • vue提供了一个内置的this.$emit函数,用来调用父组件绑定的函数

效果:
在这里插入图片描述
子组件不能直接修改父组件传递参数的引用或者基本类型参数值。

相关文章:

Vue基础入门讲义(四)-组件化

文章目录1.引言2.定义全局组件3.组件的复用4.局部注册5.组件通信5.1.父向子传递props5.2.传递复杂数据5.3.子向父的通信1.引言 在大型应用开发的时候&#xff0c;页面可以划分成很多部分。往往不同的页面&#xff0c;也会有相同的部分。例如可能会有相同的头部导航。 但是如果…...

Android onLayout布局流程解析

组件布局流程结论 1.&#xff09;layout流程始于ViewRootImpl的performLayout()方法&#xff0c;该方法会调用根View&#xff08;DecorView&#xff09;的layout()方法进行布局&#xff0c;因为DecorView是ViewGroup(FrameLayout),所以layout流程来到了ViewGroup&#xff08;其…...

浅分析BIG-建筑展示系统

一、主页&#xff08;主要界面&#xff09;重点疑点&#xff08;需要解决&#xff09;1.云平台实时同步。是否可以电脑与hololens2同步或链接&#xff1f;并可以传输信息提醒&#xff1f;一级界面&#xff08;启动界面&#xff09;1.交互式启动激活效果&#xff08;触发按钮旋转…...

模电基础(1) 半导体基础知识

基本内容&#xff1a; 1.本征半导体的基本介绍结构&#xff1b; 2.杂质半导体&#xff1b; 3.PN结的形成&#xff1b; 4.PN结的性质。 1.本征半导体 半导体&#xff1a;导电性能介于绝缘体和导体之间的物质。 本征半导体是纯净的晶体结构的半导体。 纯净→无杂质晶体结构→稳…...

阅读笔记:TF - IDF 原理

今天查阅 TF-IDF 资料&#xff0c;发现百度百科里面提供了一个例子&#xff0c;解释的很清楚&#xff0c;记下来备用。 原文链接&#xff1a;https://baike.baidu.com/item/tf-idf/8816134?fraladdin 例子&#xff1a;在某个一共有一千词的网页中 “原子能”、“的” 和 “应…...

【C语言】float 关键字

&#x1f6a9;write in front&#x1f6a9; &#x1f50e;大家好&#xff0c;我是謓泽&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流&#x1f50e; &#x1f3c5;2021|2022年度博客之星物联网与嵌入式开发TOP5|TOP4…...

Linux 网络编程(实现多路IO转接服务器)

1.select函数实现多路IO转接服务器select函数原型&#xff1a;包含在头文件<sys/time.h>&#xff0c;<sys/types.h>和<unistd.h>int select(int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds, struct timeval *timeout);作用&#xff1a;确定…...

DC-4 靶场学习

信息搜集&#xff1a; 首先获取靶场ip&#xff0c;和之前一样。 arp-scan -l nmap -sP 192.168.28.0/24然后访问。 发现需要登录。 漏洞分析: 直接用bp爆破&#xff0c;爆破出来密码为happy&#xff0c;登录。 发现执行了命令&#xff0c;抓包。 修改命令可以执行&#xff…...

QML组件

一个QML文件定义了一个独立的、顶级的QML组件。 一个QML组件就是一个模板&#xff0c;被QML运行环境解释来创建一个带有一些预定义行为的对象。 一个独立的QML组件可以运行多次来禅城多个对象&#xff0c;每个对象都可以称为该组件的实例。 例子&#xff1a; 在项目中添加一…...

canvas 学习指南

canvas 学习指南 创建一个 canvas <! DOCTYPE html><html xmlns"http://www.w3.org/1999/xhtml"><head><title></title><meta charset"utf-8" /><script type"text/javascript">window.onload fun…...

【华为OD机试2023】开心消消乐 C++

【华为OD机试2023】开心消消乐 C++ 前言 如果您在准备华为的面试,期间有想了解的可以私信我,我会尽可能帮您解答,也可以给您一些建议! 本文解法非最优解(即非性能最优),不能保证通过率。 Tips1:机试为ACM 模式 你的代码需要处理输入输出,input/cin接收输入、print/cou…...

学历?能力?

一个面试官愿意看一张有形的总结报告&#xff0c;还是愿意相信看不到的人品&#xff1f;...

使用ECharts打造一个数据可视化面板

使用ECharts打造一个数据可视化面板1. 使用技术2. 案例适配方案3. 基础设置4. header 布局5. mainbox 主体模块6. 公共面板模块 panel7. 柱形图 bar 模块&#xff08;布局&#xff09;8. 中间布局9. ECharts 介绍10. ECharts 体验11. ECharts 基础配置12. 柱状图图表&#xff0…...

【论文简述】PVSNet: Pixelwise Visibility-Aware Multi-ViewStereo Network(arxiv 2020)

一、论文简述 1. 第一作者&#xff1a;Qingshan Xu 2. 发表年份&#xff1a;2020 3. 发表期刊&#xff1a;arxiv 4. 关键词&#xff1a;MVS、3D重建、可见性、代价体、训练策略 5. 探索动机&#xff1a;ETH3D基准测试提供的图像包含强烈的视图变化&#xff0c;这就要求MVS…...

CSS隐藏元素的几种方式以及display、visibility、opacity的区别

CSS隐藏元素的方式首先最通用且最易想到的方法肯定是display、visibility和opacity这三种了display:none设置元素不可见并且连盒模型也不生成&#xff0c;一般用于不占空间的隐藏元素。display属性规定元素应该生成的框的类型&#xff0c;当其值为“none”时可以规定元素不生成…...

【Java|golang】1487. 保证文件名唯一---golang中string方法的坑

给你一个长度为 n 的字符串数组 names 。你将会在文件系统中创建 n 个文件夹&#xff1a;在第 i 分钟&#xff0c;新建名为 names[i] 的文件夹。 由于两个文件 不能 共享相同的文件名&#xff0c;因此如果新建文件夹使用的文件名已经被占用&#xff0c;系统会以 (k) 的形式为新…...

flstudio21水果language选项中文设置方法教程

编曲是通过DAW&#xff08;数字音频工作站软件&#xff09;完成的&#xff0c;也就是我们常说的宿主软件。现在有很多优秀的宿主软件&#xff0c;例如Cubase、Studio One、FL Studio等。 FL Studio是一款功能强大的音乐制作软件&#xff0c;也被称为FruityLoops。目前已经推出…...

Ubuntu中安装StaMPS

Ubuntu中安装StaMPS0 StaMPS简介1 首先安装好MATLAB&#xff0c;安装一些依赖工具包2 安装StaMPS2.1 下载StaMPS安装包2.2 安装2.3 配置环境2.4 matlab中的路径设置0 StaMPS简介 官网&#xff1a;https://homepages.see.leeds.ac.uk/~earahoo/stamps/ A software package to e…...

Spring Security 实现自定义登录和认证(1)

1 SpringSecurity 1.1 导入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId> </dependency>1.2 编写配置类 在spring最新版中禁用了WebSecurityConfigurerAdapter…...

Linux 进程:辨析wait与waitpid

目录一、wait二、waitpid(1)参数&#xff1a;pid(2)参数&#xff1a;status(3)参数&#xff1a;options(4)返回值wait 与 waitpid 这两个函数的作用是&#xff1a;等待子进程退出&#xff0c;在子进程退出后释放子进程资源&#xff0c;防止子进程变成僵尸进程。但准确的说&…...

深入解析STM32 SysTick定时器:从原理到时间片轮询实战

1. SysTick定时器的前世今生 第一次接触STM32的开发板时&#xff0c;我就被这个叫做SysTick的神秘定时器吸引了。当时我正为如何实现精确延时发愁&#xff0c;GPIO翻转测试显示软件延时误差高达30%&#xff0c;直到一位资深工程师提醒我&#xff1a;"内核里就藏着个高精度…...

从变砖到重生:红魔全系9008深度救砖指南与实战解析

1. 什么是9008模式&#xff1f;为什么能救砖&#xff1f; 当你发现红魔手机卡在开机界面、反复重启甚至完全黑屏时&#xff0c;大概率是遇到了传说中的"变砖"。这时候高通芯片隐藏的9008模式就是最后的救命稻草。简单来说&#xff0c;9008模式相当于电脑的BIOS界面&…...

Wangle客户端开发实战:从零开始构建高效网络应用

Wangle客户端开发实战&#xff1a;从零开始构建高效网络应用 【免费下载链接】wangle Wangle is a framework providing a set of common client/server abstractions for building services in a consistent, modular, and composable way. 项目地址: https://gitcode.com/g…...

Java后端如何优雅地封装第三方API调用逻辑以对接美团外卖霸王餐接口

Java后端如何优雅地封装第三方API调用逻辑以对接美团外卖霸王餐接口 在Java后端开发中&#xff0c;对接第三方API&#xff08;如美团外卖霸王餐接口&#xff09;是常见的需求。直接在业务代码中拼接URL、处理JSON、写HTTP请求不仅导致代码臃肿&#xff0c;还难以维护和测试。 本…...

SpringBoot3.3.1+Elasticsearch8.13.4日期转换踩坑实录:LocalDateTime保存为时间戳的完整方案

SpringBoot3.3.1与Elasticsearch8.13.4时间类型转换实战&#xff1a;从踩坑到优雅解决 最近在升级技术栈到SpringBoot3.3.1时&#xff0c;发现与Elasticsearch8.13.4的集成出现了一个棘手的问题&#xff1a;LocalDateTime类型在保存和查询时表现异常。这让我花了整整两天时间排…...

Z-Image-Turbo在艺术创作中的实战:将文字灵感转化为超写实画作

Z-Image-Turbo在艺术创作中的实战&#xff1a;将文字灵感转化为超写实画作 你是否曾经有过绝妙的创意画面&#xff0c;却苦于无法将其具现化&#xff1f;Z-Image-Turbo极速云端创作室正是为解决这一痛点而生。这个基于先进AI技术的文生图工具&#xff0c;能够将你的文字描述在…...

别再只会看原理图了!用Multisim仿真带你深入理解运放的“虚短虚断”与反馈

用Multisim仿真破解运放"虚短虚断"的底层逻辑 在电子电路设计中&#xff0c;运算放大器就像一位沉默的魔术师&#xff0c;用"虚短"和"虚断"两个基本概念演绎着各种精妙的信号处理戏法。但很多工程师在学习阶段只是机械记忆这两个术语&#xff0c…...

在树莓派4B上编译运行Speedtest-CLI:手把手解决curl和expat库的交叉编译难题

树莓派4B实战&#xff1a;从零构建Speedtest-CLI测速工具全流程指南 1. 环境准备与工具链配置 在树莓派4B上构建Speedtest-CLI测速工具&#xff0c;首先需要搭建完整的交叉编译环境。不同于x86平台的直接编译&#xff0c;ARM架构下的开发需要特别注意工具链的选择和配置。 必备…...

30 分钟搞定答辩 PPT!Paperxie AI 生成器:拯救论文人的「熬夜克星」

paperxie-免费查重复率aigc检测/开题报告/毕业论文/智能排版/文献综述/AIPPThttps://www.paperxie.cn/ppt/createhttps://www.paperxie.cn/ppt/create 一、答辩 PPT 惨案现场&#xff1a;你是不是也在为这四件事崩溃&#xff1f; 论文查重通过的那一刻&#xff0c;你以为终于能…...

石油勘探中的地震波“翻译官”:如何读懂时距曲线图里的地下秘密?

石油勘探中的地震波“翻译官”&#xff1a;如何读懂时距曲线图里的地下秘密&#xff1f; 站在戈壁滩的勘探营地&#xff0c;望着屏幕上那些看似杂乱的波形曲线&#xff0c;刚入行的地质工程师小李皱起了眉头。"这些弯弯曲曲的线条&#xff0c;到底在诉说什么样的地下故事&…...