把实例的基础属性过了一遍,现在来看事件以及之前很少接触的动画过渡效果。
组件
组件的本质是什么,从JS代码和Vue的角度来说,就是一个规定好属性和值写法的对象,和新创建Vue实例传入的对象没有本质上的区别。
当然与直接生成Vue实例相比,组件还是有属于自己的特点,那就是不同的属性及其作用。就单个组件来说,最大的变化是template
属性,也就是组件要渲染的HTML部分。
此外data变成了一个函数,返回了一个对象,这是因为组件需要复用,如果指定为具体值,则各个组件都会共享基础数据,就比较可怕了。
还有一个重要的就是props
,表示父组件传入的数据。
props
props的属性有类型,是否required,默认值,这个都已经知道了。新了解的是还可以有一个叫做validator
名称的方法,用于验证这个属性是否OK。返回true就说明OK。:
<div id="app"> <list :price="3"></list> <list :price="-33"></list> </div> <script> Vue.component('list', { template: '<div>Price is {{price}}</div>', props: { price:{ type:Number, default:0, validator(val){ return val >= 0; } } } }); new Vue({ el: '#app' }); </script>
这个运行起来,Vue会提示:
vue.js:634 [Vue warn]: Invalid prop: custom validator check failed for prop "price". found in ---> <List> <Root>
注意这个方法只能是这个名称,不能修改名称。
slot
之前已经知道普通插槽,具名插槽和作用域插槽。现在slot和作用域插槽都要废弃,引入了v-slot
指令,只能作用于<template>
元素。
2.6之后的Vue的组件大改了,用一个例子看明白:
<div id="app"> <myslots> <template v-slot:default>父组件插入默认插槽</template> <template v-slot:saner>父组件插入具名插槽</template> <template v-slot:scope="cony">{{cony.innerobject.name}}</template> </myslots> </div> <script> Vue.component('myslots', { template: '<div><p><slot>不具名插槽默认内容</slot></p>' + '<p><slot name="saner">具名插槽默认内容</slot></p>' + '<p></p><slot name="scope" :innerobject="person">绑定子组件属性的插槽</slot></div>', data: function () { return { person: { name: 'jenny' } } } }); new Vue({ el: '#app' }); </script>
主要就是v-slot指令要搭配template来使用,作用域的使用方法很简单,父的绑定名称.子的属性名.实际属性即可。
自定义事件
自定义事件$emit
已经知道了,现在要了解一下可以用其他方式在父组件上添加和取消事件监听器:
<div id="app"> <events ref="tar"></events> <button @click="cancel">取消事件绑定</button> </div> <script> Vue.component('events', { template: '<div><button @click="event1">反复触发事件</button><button @click="event2">一次事件</button></div>', methods:{ event1:function () { this.$emit('repeat') }, event2:function () { this.$emit('once') } } }); new Vue({ el: '#app', methods: { handle1:function () { console.log("反复事件触发了") }, handle2:function () { console.log('一次事件触发了') }, cancel:function () { this.$refs.tar.$off('repeat',this.handle1) this.$refs.tar.$off('once',this.handle2) } }, mounted: function () { this.$refs.tar.$on('repeat',this.handle1) this.$refs.tar.$once('once',this.handle2) } }); </script>
如果先按了下边的取消事件绑定按钮,再点击按钮,就没有处理事件的函数了。
子组件上没有进行绑定props的属性
如果在子组件上设置了没有绑定props的普通HTML属性,这些属性会被放到子组件的外层元素上去。如果父组件设置的属性和子组件模板内的属性相同,父组件的设置会覆盖子组件。看例子:
<div id="app"> <custom-button type="submit">Click me!</custom-button> </div> <script> const CustomButton = { template: '<button type="button"><slot></slot></button>' }; new Vue({ el: '#app', components: { CustomButton } }); </script>
这时候实际渲染出来的按钮的属性是submit。大部分属性会覆盖,但是class
和style
属性则会叠加,所以有时候可以方便的通过父组件去控制样式。
看完了Vue js快跑,我发现倒是之前Vue实例的一些使用有很多知识点没搞要求,因为Vue实例看的是国人的书。关于Vuex和Router,是跟着老外的视频看的,却发现都学的比较全。
不得不感叹看书还真得官方文档+老外的书一起看,看国人写的书还是要慎重啊。