Vue学习杂记(二)——组件总结
引言:最近感觉写代码动力不足,觉得自己有点一直很憨的写代码了,因此决定好好学一下Vue,将之前没有掌握的一下关于Vue2.0的细节巩固一下。避免出现没听说过、没讲过的尴尬情况。可能会出系列文章,有些时候想写一些东西,但是笔记本不在身边。比较适合像我一样的主动(或者由于项目进度需要)上手框架,但是基础知识不够扎实的小白。
也曾模仿过基于Vue的框架写过组件,但是对于组件的理解一直不够全面,因此,今天解决这个问题。
一、为什么使用组件?
作为一名软件工程的铁憨憨,对于项目需求的易变性理解的尤其深刻。往往你写了一套代码,你发现这套代码可以用于其他的场景,只需要调整某些内容。因此CV便成为了快乐源泉,直接将那一套代码搬到多个页面去(这里说的搬不是那么纯粹,指的是主要代码一致)。之后需求变化了,需要你修改一下样式或者逻辑,这时就尴尬了,由于页面是CV的,这时你大概率需要修改好几个页面。你可能当时觉得Git上的代码量挺多的,但是,现在今天变一下需求,吗,今天变一下需求,改着改着就容易烦躁。
组件,完美的解决了这个问题。这才用的就是封装的思想,你可以利用Vue组件机制构建<dynamic-list></dynamic-list>
(动态列表组件),然后就能够再多个页面中快速插入代码了。如果修改,你只需要修改dynamic-list
d的组件源码就行。
二、组件如何使用?
简单贴一手代码:
<div id="app">
<child search-text="凌空暗羽"></child>
</div>
<script>
let app=new Vue({
el:'#app',
components:{
child:{
props:['searchText'],
template:'<div>输出昵称:{{searchText}}</div>'
}
}
})
</script>
Vue 中构建组件的方式有两种:
(1)在挂载点内部使用 components
和 template
属性来设置内容;
(2)使用Vue.components("child",{template:" "})
的形式;
Vue构建出来的子组件同样遵循插值语法,只是插值语法中对于数据的处理用的是函数的形式返回,比如,那上面的searchText来说,对应的赋值语法为:
components:{
child:{
data:function(){
return {
searchText:"凌空暗羽"
};
}
}
}
补充说明:这里的组件同样支持计算属性,同时如果想要获取父组件的传递过来的值,可以先使用 props['searchText']
得到传值变量,然后在template里面直接使用插值语法便可,最后,如果设计的组件存在大小写,那么需要将组件使用-连接,例如组件 dynamicList
即对应实例标签 <dynamic-list></dynamic-list>
。
另外组件同样可以实现数据的双向绑定:
这里遇到了一个问题,刚好解释了Vue中对于大小写的处理机制,对于变量,Vue不区分大小写,但是对于组件名称和props属性
,遇到大写时,Vue会将大写转化成 new-msg
的形式。
抛开这个问题,子组件的数据能够与父组件绑定,用过:
符号激发变量实现。
三、父子组件传值的解耦
耦合度同样是软件工程中经常提到的一个概念,可以大概理解成:用于描述两个对象之间的关联程度。在Vue2中,更加强调组件传值的解耦,也就是不希望出现像上面那种v-model的数据多边绑定,因为这样很容易出现子组件将父组件内容修改了的情况,不利于项目的维护:
优化方法就如同英文所说,可以存在两种方法一种是计算属性,另一种是在data里面设置变量获取父组件传递的值,都是通过间接获取父组件传值来防止修改父组件。
需要注意的是Vue中的父子组建通信传递的是对象或者数组时,由于JavaScript中的对象与数组是引用类型,可以跳过Vue通信规则的检测,造成子组件修改父组件的情形:
实例解释:这里给父组件绑定两个变量,一个是对象类型,一个是普通变量。通过this._props
修改子组件的值,发现对象能跳过检测同时修改了父组件,而普通变量会产生警告提示,解决方法,深拷贝:
四、组件通信
组件通信可以大致分成三类:父组件向子组件通信、子组件向父组件通信、跨级组件通信;
(1)父组件向子组件通信前面已经介绍了;
(2)子组件向父组件通信,主要是使用 $emit 与 $on
并结合中间函数通信,实例代码如下:
需要注意的是:this.emit
方法不能使用驼峰命名的函数,当然在如今的uni-app组件自定义中并无这个问题。
规范的通信主要是props 和$emit 方法,但是随着Vue项目的扩大,组件通信传化成了如下形式:
(1)基于子链和父链:$parent 和 $children,通过this.$parent
能够获取到当前组件的所有父级组件,由于渲染顺序可能不一致,因此不能够根据索引来获取组件,转化成使用this.$refs.name.data
的形式(name表示的是组件中ref属性的值,data即组件data里面的数据):
(2)中央bus通信机制: