三. Vue组件化
1. 认识组件化1.1 什么是组件化人面对复杂问题的处理方式 任何一个人处理信息的逻辑能力都是有限的,所以当面对一个非常复杂的问题时我们不太可能一次性搞定一大堆的内容。 但是我们人有一种天生的能力就是将问题进行拆解。如果将一个复杂的问题拆分成很多个可以处理的小问题再将其放在整体当中,你会发现大的问题也会迎刃而解。 组件化也是类似的思想 如果我们将一个页面中所有的处理逻辑全部放在一起,处理起来就会变得非常复杂,而且不利于后续的管理以及扩展。 但如果我们将一个页面拆分成一个个小的功能块,每个功能块完成属于自己这部分独立的功能,那么之后整个页面的管理和维护就变得非常容易了。 1.2 Vue组件化思想组件化是Vue.js中的重要思想 它提供了一种抽象,让我们可以开发出一个个独立可复用的小组件来构造我们的应用,任何的应用都会被抽象成一颗组件树 组件化思想的应用 有了组件化的思想,我们在之后的开发中就要充分的利用它 尽可能的将页面拆分成一个个小的、可复用的组件 这样让我们的代码更加方便组织和管理,并且扩展性也更强 2. 注册组件2.1 注册组件的基本步骤组件的使用分成三个步骤
三个步骤的含义
2.2 组件的作用域全局组件 当我们通过调用 局部组件 如果我们注册的组件是挂载在某个实例中,那么就是一个局部组件 2.3 父子组件在前面我们看到了组件树 组件和组件之间存在层级关系 而其中一种非常重要的关系就是父子组件的关系 我们来看通过代码如何组成的这种层级关系 父子组件错误用法:以子标签的形式在Vue实例中使用 因为当子组件注册到父组件的components时,Vue会编译好父组件的模块。 该模板的内容已经决定了父组件将要渲染的HTML(相当于父组件中已经有了子组件中的内容了)。
2.4 注册组件语法糖在上面注册组件的方式,可能会有些繁琐 Vue为了简化这个过程,提供了注册的语法糖 主要是省去了调用 语法糖注册全局组件和局部组件如下 3. 组件其他补充3.1 模板的分离写法刚才我们通过语法糖简化了Vue组件的注册过程,另外还有一个地方的写法比较麻烦,就是template模块写法 如果我们能将其中的HTML分离出来写,然后挂载到对应的组件上,必然结构会变得非常清晰 Vue提供了两种方案来定义HTML模块内容:
3.2 组件可以访问Vue的实例数据吗?组件是一个单独功能模块的封装 这个模块有属于自己的HTML模板,也应该有属性自己的数据data 组件中的数据是保存在哪里呢?顶层的Vue实例中吗?
3.3 组件数据的存放组件自己的数据存放在哪里呢? 组件对象也有一个data属性(当然也可以有methods等属性,下面我们有用到) 只是这个data属性必须是一个函数 而且这个函数返回一个对象,对象内部保存着数据 为什么data在组件中必须是一个函数呢? 首先,如果不是一个函数Vue直接就会报错 其次,原因是在于Vue让每个组件对象都返回一个新的对象。因为如果是同一个对象的,组件在多次使用后会相互影响 4. 父子组件通信4.1 父子组件通信理解之前我们提到了子组件是不能引用父组件或者Vue实例的数据的 但是,在开发中往往一些数据确实需要从上层传递到下层:
在下面的代码中,我直接将Vue实例当做父组件并且其中包含子组件来简化代码 真实的开发中,Vue实例和子组件的通信和父组件和子组件的通信过程是一样的 4.2 父组件向子组件传递数据 - props基本用法 在组件中,使用选项props来声明需要从父级接收到的数据 props的值有两种方式
我们先来看一个最简单的props传递 props数据验证 在前面我们的props选项是使用一个数组 除了数组之外我们也可以使用对象,当需要对props进行类型等验证时就需要对象写法了 验证支持如下数据类型
当我们有自定义构造函数时,验证也支持自定义的类型 4.4 子组件向父组件传递数据或事件 - $emit()自定义事件 props用于父组件向子组件传递数据,还有一种比较常见的是子组件传递数据或事件到父组件中我们应该如何处理呢?这个时候我们需要使用 什么时候需要自定义事件? 当子组件需要向父组件传递数据时,就要用到自定义事件了 我们之前学习的v-on不仅仅可以用于监听DOM事件,也可以用于组件间的自定义事件 自定义事件的流程 在子组件中,通过 在父组件中,通过 我们来看一个简单的例子:
4.5 父子传参与双向绑定结合的案例
4.6 父子组件的直接访问方式 - $children或$refs? /? $parent理解 有时候我们需要父组件直接访问子组件,子组件直接访问父组件,或者是子组件访问根组件
$children this.$children是一个数组类型,它包含所有子组件对象 我们这里通过一个遍历,取出所有子组件的message状态 $refs $children的缺陷 通过 但是当子组件过多,我们需要拿到其中一个时往往不能确定它的索引值,甚至还可能会发生变化 有时候我们想明确获取其中一个特定的组件,这个时候就可以使用 $refs的使用
首先我们通过 ref 给某一个子组件绑定一个特定的ID 其次通过 $parent 如果我们想在子组件中直接访问父组件,可以通过 注意 尽管在Vue开发中,我们允许通过$parent来访问父组件,但是在真实开发中尽量不要这样做 子组件应该尽量避免直接访问父组件的数据,因为这样耦合度太高了 另外更不好做的是通过$parent直接修改父组件的状态,那么父组件中的状态将变得飘忽不定,很不利于我的调试和维护 5. 非父子组件通信5.1 理解刚才我们讨论的都是父子组件间的通信,那如果是非父子关系呢? 非父子组件关系包括多个层级的组件,也包括兄弟组件的关系 在
在
5.2 中央事件总线5.3 Vuex状态管理(后面专门讲)6. 插槽slot6.1 编译作用域在真正学习插槽之前我们需要先理解一个概念: 官方对于编译的作用域解析比较简单,我们自己来通过一个例子来理解这个概念 我们来考虑下面的代码是否最终是可以渲染出来的:
答案:最终可以渲染出来,也就是使用的是Vue实例的属性。为什么呢?
6.2 为什么使用slotslot翻译为插槽 在生活中很多地方都有插槽,电脑的USB插槽,插板当中的电源插槽 插槽的目的是让我们原来的设备具备更多的扩展性 比如电脑的USB我们可以插入U盘、硬盘、手机、音响、键盘、鼠标等 组件的插槽 组件的插槽也是为了让我们封装的组件更加具有扩展性 让使用者可以决定组件内部的一些内容到底展示什么 例子:移动网站中的导航栏
6.3 如何在封装组件时正确使用slot如何去封装京东M站导航栏这类的组件呢? 它们也很多区别,但是也有很多共性 如果我们每一个单独去封装一个组件显然不合适:比如每个页面都返回,这部分内容我们就要重复去封装 但是如果我们封装成一个好像也不合理:有些左侧是菜单,有些是返回,有些中间是搜索,有些是文字等 如何封装合适呢?抽取共性,保留不同
6.4 slot基本使用了解了为什么用slot,我们再来谈谈如何使用slot?
我们通过一个简单的例子,来给子组件定义一个插槽
6.5 具名插槽slot当子组件的功能复杂时,子组件的插槽可能并非是一个 比如我们封装一个导航栏的子组件,可能就需要三个插槽,分别代表左边、中间、右边。、 那么,外面在给插槽插入内容时,如何区分插入的是哪一个呢? 这个时候,我们就需要给插槽起一个名字 如何使用具名插槽呢? 非常简单,只要给slot元素一个name属性即可
我们来给出一个案例: 这里我们先不对导航组件做非常复杂的封装,先了解具名插槽的用法。 6.6 作用域插槽作用域插槽是slot一个比较难理解的点,而且官方文档说的又有点不清晰。 这里,我们用一句话对其做一个总结,然后我们在后续的案例中来体会:父组件替换插槽的标签,但是内容由子组件来提供。 我们先提一个需求 子组件中包括一组数据,比如:pLanguages: ['JavaScript','Python','Swift','Go','C++'] 需要在多个界面进行展示:
内容在子组件,希望父组件告诉我们如何展示,怎么办呢
我们来看看子组件的定义: 在父组件使用我们的子组件时,从子组件中拿到数据 我们通过
再通过 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |