在工作中承担一部分前端工作,主要使用Vue + Element UI。

随着版本迭代,需求增加,页面往往变得更加臃肿,不易维护。学习子组件的封装和抽取,能更好适应需求。

为什么需要子组件

  • 可复用

    将重复出现的元素封装成组件,可以灵活运用到各个页面中,避免重复劳动。
  • 易维护

    每个组件相当于独立的功能组件。独立的组件结构可以让其他开发者快速定位到每个页面元素所对应的事件方法、样式表,并在修改该组件时不影响其他页面的功能。

组件的使用方法

子组件的定义方法和每一个Vue组件相同,使用时需要先注册,分为全局注册和局部注册两种。

全局&局部?

对于全局通用的组件,可以将其注册为全局的。在项目中更常用的是局部注册,全局注册固然方便,但会使组件的依赖结构不够清晰,可能带来的更高的维护成本。

Vue官网教程中给出如下建议:

全局注册往往是不够理想的。比如,如果你使用一个像 webpack 这样的构建系统,全局注册所有的组件意味着即便你已经不再使用一个组件了,它仍然会被包含在你最终的构建结果中。这造成了用户下载的 JavaScript 的无谓的增加。

局部注册需要在每个使用到的地方都引用一次,父组件引用之后,子组件必须再次引用才能使用。

父子如何通信

组件之间相对独立,不共享变量,重中之重就是:如何传递信息?

我列出一些我目前接触到的常用数据传递方法:

  • 使用路由参数传递:在A组件中向路由中写入,在B组件通过$route.query.param获取
  • 存储在session Storage中或使用Vuex,存储常用共有变量

    ……

    组件之间构成父子关系,必然是结构和数据上存在依赖关系,当不能跳转路由或需要使用多个子组件时,上述方法不奏效了,所幸的是,Vue提供了一套现成的方法,可以总结为:
  • 父传子用props
  • 子传父用emit
  • 双向绑定,compute+sync

props

父向子传递的信息,往往是子组件的初始化数据。假如将子组件看作一个类,在父组件中使用该类的实例,props有点类的构造参数。

props的写法也与构造函数形参类似,可以规定传参类型、是否必传等。

props: {
// 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)
propA: Number,
// 多个可能的类型
propB: [String, Number],
}

$emit

emit函数支持子组件调用父组件函数,并支持传数据作为父组件接受调用函数时的传参。

  • 使用场景示例

    子组件完成动作后,调用父组件的刷新列表方法:
// 子组件中
this.$emit("queryList") // 父组件中
//刷新列表方法
queryList(){
}

使用$emit特性,很容易实现将子组件的值传递给父组件,并能控制父组件的动作。

双向绑定

更常见的需求是需要父组件和子组件的值实现同步,比如:

  • 在父组件点击打开按钮,希望能控制子组件打开,在子组件内部点击关闭后,希望父组件的开关也被同步到关闭。
  • 在父组件打开表单后,在子组件内填写,希望父组件知道子组件填了什么,实时同步在子组件的操作。

Vue规定了父子组件之间数据单向流动,不建议直接修改父组件传入的prop变量。所以为了实现双向绑定,我们需要:

1、在子组件中定义对应的变量B,拷贝父组件传入的初始值A

2、实时监测变量B,当B发生变化时,使用$emit,传递B的值给父组件

3、在父组件中定义接收值的更新函数,接收到新的值后,将值赋给A


实现第1、2点,compute完美满足需求。

为实现第三点,Vue提供了.sync语法糖,避免每次都要写一个更新函数,默认的函数名是update。

在明确了步骤后,我们很容易就能写出代码。需要稍微留意的是,子组件中变量B的命名最好与变量A对称,这样一看就是一对,代码更加清晰易懂。

例如:

A叫openDialog,B叫dialogOpened

A叫selectOption,B叫optionSelected

父组件中:
//父组件引用
<my-dialog :showDialog.sync="showDialog" ></my-dialog >

子组件中:

// 子组件
props: {
// 是否展示弹窗
showDialog: Boolean,
} ....
// 在代码中修改dialogShowed的值 computed: {
dialogShowed: {
get() {
return this.showDialog;
}, set(val) {
this.$emit("update:showDialog", val);
}
}
}

总结

以上就是目前所总结到的抽取子组件的小经验~熟悉了这种模式之后,实现起来还是挺容易的。

Vue基础:子组件抽取与父子组件通信的更多相关文章

  1. vue+elementUI项目,父组件向子组件传值,子组件向父组件传值,父子组件互相传值。

    vue+elementUI项目,父组件向子组件传值,子组件向父组件传值,父子组件互相传值. vue 父组件与子组件相互通信 一.父组件给子组件传值 props 实现父组件向子组件传值. 1父组件里: ...

  2. vue 基础-->进阶 教程(2): 指令、组件

    第二章 建议学习时间4小时  课程共3章 前面的nodejs教程并没有停止更新,因为node项目需要用vue来实现界面部分,所以先插入一个vue教程,以免不会的同学不能很好的完成项目. 本教程,将从零 ...

  3. vue父子组件及非父子组件通信

    1.父组件传递数据给子组件 父组件数据如何传递给子组件呢?可以通过props属性来实现 父组件: <parent> <child :child-msg="msg" ...

  4. Vue父子组件及非父子组件如何通信

    1.父组件传递数据给子组件 父组件数据如何传递给子组件呢?可以通过props属性来实现 父组件: 子组件通过props来接收数据: 方式1: 方式2 : 方式3: 这样呢,就实现了父组件向子组件传递数 ...

  5. vue2.0父子组件以及非父子组件如何通信

    1.父组件传递数据给子组件 父组件数据如何传递给子组件呢?可以通过props属性来实现 父组件: <parent> <child :child-msg="msg" ...

  6. vue2.0父子组件以及非父子组件通信传参详解

    1.父组件传递数据给子组件 父组件数据如何传递给子组件呢?可以通过props属性来实现 父组件: <parent> <child :child-msg="msg" ...

  7. Vue父子,子父,非父子组件之间传值

    Vue组件基础 纯属随笔记录,具体详细教程,请查阅vue.js网站 子组件给父组件传值: <body> <div id="app"> <my-app& ...

  8. Vue学习之组件切换及父子组件小结(八)

    一.组件切换: 1.v-if与v-else方式: <!DOCTYPE html> <html lang="en"> <head> <met ...

  9. 简述在Vue脚手架中,组件以及父子组件(非父子组件)之间的传值

    1.组件的定义 组成: template:包裹HTML模板片段(反映了数据与最终呈现给用户视图之间的映射关系) 只支持单个template标签: 支持lang配置多种模板语法: script:配置Vu ...

随机推荐

  1. SocksCap64应用程序通过SOCKS代理

    一.下载SocksCap64 https://pan.baidu.com/s/1B671kT9R6Zb6ch1mc4Kb2Q 提取码:hai3 一个是免安装版本,一个是安装版本,选一个即可. 下面以免 ...

  2. 图论--最短路-- Dijkstra模板(目前见到的最好用的)

    之前的我那个板子,老是卡内存,不知道为什么,我看别人过的那个题都是结构体,我就开始对自己板子做了修改,然后他奶奶的就过了,而且速度也提高了,内存也小了.(自从用了这个板子,隔壁小孩馋哭了)也不知道为啥 ...

  3. redis系列之5----redis实战(redis与spring整合,分布式锁实现)

    本文是redis学习系列的第五篇,点击下面链接可回看系列文章 <redis简介以及linux上的安装> <详细讲解redis数据结构(内存模型)以及常用命令> <redi ...

  4. Jmeter系列(9)- jmeter插件入门篇

    如果你想从头学习Jmeter,可以看看这个系列的文章哦 https://www.cnblogs.com/poloyy/category/1746599.html 前言 jmeter4.0以上,如现在最 ...

  5. Java 经典面试题:聊一聊 JUC 下的 CopyOnWriteArrayList

    ArrayList 是我们常用的工具类之一,但是在多线程的情况下,ArrayList 作为共享变量时,并不是线程安全的.主要有以下两个原因: 1. ArrayList 自身的 elementData. ...

  6. D. Misha, Grisha and Underground 树链剖分

    D. Misha, Grisha and Underground 这个题目算一个树链剖分的裸题,但是这个时间复杂度注意优化. 这个题目可以选择树剖+线段树,时间复杂度有点高,比较这个本身就有n*log ...

  7. spring内嵌jetty容器,实现main方法启动web项目

    Jetty 是一个开源的servlet容器,它为基于Java的web容器,例如JSP和servlet提供运行环境.Jetty是使用Java语言编写的,它的API以一组JAR包的形式发布.开发人员可以将 ...

  8. 王颖奇 20171010129《面向对象程序设计(java)》第十五周学习总结

    实验十五  GUI编程练习与应用程序部署 实验时间 2018-12-6 学习总结: 理论部分: ◼ JAR文件◼ 应用程序首选项存储◼ Java Web Start JAR文件: 1.Java程序的打 ...

  9. ubuntu文件系统修改( for arm)

    系统:ubuntu14.04 镜像:ubuntu-rootfs.img for aarch64 创建一个文件夹 ubuntu-mount mkdir ubuntu-mount 将ubuntu-root ...

  10. apply call bind的用法与实现

    概念 apply call 和bind 允许为不同的对象分配和调用属于一个对象的函数/方法.同时它们可以改变函数内 this 的指向. 区别 apply 和 call 接收的参数形式不同 apply ...