slot:插槽内容分发,使用作用域插槽让slot也可以获得组件内部方法,让用户自定义的内容页能调用组件内部方法,比如popover弹出框中用户想自己加个按钮手动调用关闭。
event: 组件事件。从用户角度考虑,比如datepicker组件中用户想在日期面板被打开或这关闭的时候进行操作。这种一般用在交互类UI组件。
举个例子
复杂组件datepicker开发思路
1、在原有的popover组件上开发
点击一个元素A(输入框)后可以弹出元素B(日期面板)
2、生成日期面板
生成7*6=42个日期,6行是为了确保一个月都能在面板上完整显示。这里计算最方便的做法是用时间戳,计算出这个月第一天时间戳和这一天周几,就可以一次性计算出这42个日期。不用算上个月下个月分三段算,这样的问题是还要考虑边界情况,如刚好出现上一年下一年等,麻烦容易出bug。这42个日期我们在computed用visibleDays表示。
visibleDays () { let { year, month } = this.display let defaultObj = new Date(year, month, 28) var curMonthFirstDay = helper.getMonthFirstDay(defaultObj) var curMonthFirstDayDay = helper.getDay(curMonthFirstDay) === 0 ? 7 : helper.getDay(curMonthFirstDay) let x = curMonthFirstDayDay - 1 // 前面需要补多少位 var arr = [] for (let i = 0; i < 42; i++) { arr.push(new Date(curMonthFirstDay.getTime() + (-x + i) * 3600 * 24 * 1000)) } return arr },
3、props接受value, 类型是date
日期面板上的日期渲染的时候加上一个计算的class, 分别加上'today','selected-date','available','prev-month','next-month',进行样式上的区分
4、实现选中日期
告诉父组件修改数据意图让父组件修改传入的props,对应使用我们组件的时候使用, 这里的基础知识是组件上的v-model是个语法糖,v-model="x"会被解析成:value="a" @input="a=$event"。同时面板上输入框显示的数据也要跟着变化,所以这里用计算属性,如在computed中用formattedValue表示。
formattedValue: { return this.value instanceof Date ? helper.getFormatDate(this.value) : '' }
5、实现点击上一年/月,下一年/月
我们需要知道当前展示的是哪一年哪一个月,这个数据是组件内部维护的,所以在data申明一个display对象
display: { year: (this.value && this.value.getFullYear()) || new Date().getFullYear(), month: (this.value && this.value.getMonth()) || new Date().getMonth() }
点击的时候即修改display对象的year/month,因为visibleDays也是计算属性,依赖display对象,所以点击上一年/月,下一年/月,渲染的日期也跟着变。
6、实现选择年