组件 (Component) 是 Vue.js 最强大的功能之一。组件可以扩展 HTML 元素,封装可重用的代码。在较高层面上,组件是自定义元素,Vue.js 的编译器为它添加特殊功能。在有些情况下,组件也可以表现为用 is 特性进行了扩展的原生 HTML 元素。所有的 Vue 组件同时也都是 Vue 的实例,所以可接受相同的选项对象 (除了一些根级特有的选项) 并提供相同的生命周期钩子。(摘自官网,说的挺好直接抄了)
下一章开始,会封装几个具体的常用组件(alert/model/search)。
关于组件学习的知识点:
1.利用template参数替换自定义标签内容
2.利用props传递数据(父传子)
3.props验证(补充内容)
4.data字段详解
5.用this.$emit传递数据(子传父)
6.单项数据流(补充内容)
7.利用slot分发数据,创建自定义dom
8.作用域问题
1.利用template参数替换自定义标签内容
在学习组件之前,首先需要用Vue.component(tagName, options)方法注册一个全局组件(当然你也可以在Vue实例里的Compnent对象里放组件,个人觉得这个功能有点鸡肋,因为组件本身的意义就是公用的,放到全局里方便使用)。
第一个参数TagName是组件的名称,可以理解为H5新增的自定义标签。(当然你也可以称为声明式标签,因为他的命名一般都是有意义的,如sel-tmp,指的是选项卡)。
第二个参数是选项,跟Vue实例里的参数差不多,具体会一个一个说明,下面的demo里用到了template,是最基本的参数之一,他会替换自定义标签里的内容。
vue.js学习--组件and组件间通信
可以看到自定义标签整个被替换成了template里的内容,该自定义标签不会存在于dom文档流。
2.利用props传递数据(父传子)
上面的demo里,Vue实例包含了
vue.js学习--组件and组件间通信
效果跟1中的相同。关于数据传递,有一个不知是bug还是我不懂的地方:
dom里绑定数据的时候请用烤串命名法 v-bind:receive-list
函数内请用驼峰命名法 props:["receiveList"]
3.props验证(补充内容)
关于props参数:props 可以是数组或对象,用于接收来自父组件的数据。props 可以是简单的数组,或者使用对象作为替代,对象允许配置高级选项,如类型检测、自定义校验和设置默认值。
为什么要有props验证?
可以将props理解为子级提供给父级的一个输入口,如果父级输入的内容有误,比如在输入金额的输入框里,输入了中文,这个时候,子级就应该报错。然而父级并不一定知道子级需要什么内容(很有可能是某程序员负责写某一个组件,另一个程序员在某个模块中加一个这个组件,双方没有说明沟通),所以vue.js提供了props验证来防止这种情况发生。
props:{
"receiveList":{
//type:Number, //验证类型
//default:"",//默认值,如年龄可默认为一岁,性别默认为男等
//required:true or false,//传参是否必填
validator:function(value){
console.log(value);//value = 父级传过来的值
//return true or false;
//比如来验证一下父级传过来的arr.lenght是否大于0,最好先判断传过来的是不是数组
return value.length>=4?true:false;
}
}
},
事实上,如果传过来的数据有误,vue只会在控制台报错,并不会阻塞程序执行。所以验不验证对不看控制台的人来说是没啥意义的。(暗示某些测试测不出来的bug)
4.data字段详解
上一章对于vue实例里的data字段埋了一个坑,这里来填一下。
首先作为组件,可能会在一个页面多次用到,下面我通过实现一个功能来讲一下data里的坑。
功能:鼠标点击输入框,实现下拉框的显示和隐藏
实现:需要在data里添加一个ifShow字段来控制模板
template:
''+
'' +
''+
''+
'' +
''+
'
'+
'',
//data需要用函数返回值,避免多个组件公用一个data对象
data:function(){
return {
ifShow:false,
}
},
在vue.component里,data不能是对象的形式,会直接报错。
可以用函数返回值的形式,避免组件间公用同一数据而相互影响。
5.用this.$emit传递数据(子传父)
刚才的组件再划分一下,将输入框和下拉框分开,让下拉框单独出来作为一个组件(纯粹为了方便讲解)
现在,下拉框变成了子级,父级则是由下拉框组件+输入框,要把下拉框的内容传递给父级,使用了实例中的$emit触发自定义事件,并将参数传给父级。看代码注释:
vue.js学习--组件学习
如此,完成了子级向父级传递数据。
6.单项数据流(补充内容)
单项数据流是个神马东西?官网里并没有有关于这项东西的说明,我个人也还没完全摸透这块东西。
首先来解释一下这个名词(用自己语言组织一下)
在组件中,利用props父级向子级传递数据后,子级内部对数据进行了处理,如改变数据的某个值,这时候控制台就会报错(又是一个只报错不影响结果的破玩意儿)。
解决方案:在子级作用域中,将接收的值存入私有的data 或者 computed里,就可以操作(他只是不报错而已)。
来说一下我没搞明白的地方,就是已经标出来的“改变数据”四个字。如,我对上面父级传过来的地名数组进行处理,会发生以下两种情况,
methods:{
postData:function(item){
//this.nameArr=["北京","上海","杭州","广州"];//如果这样写,会报错,因为修改了整个数组
//this.nameArr.push("广州");//这样写就不会报错,而且能push数据进去
this.$emit("receive",item);
}
}
两种修改数据的方法都能执行,只是前者会报错,后者不报错,有兴趣的自己试试。
7和8的内容放到下一章讲吧,在研究研究...