目录
组件封装
parseTime函数
debounce 函数
页面使用
【扩展】vue 函数式组件
函数式组件特点:
函数式组件的优点:
【扩展】vue中的render函数
一、初步认识render函数
二、为什么使用render函数
三、render函数的解析
这段代码是一个封装的分页表格组件。它使用了Vue.js框架,并结合了Element UI中的el-table和el-pagination组件来实现。该组件接受一系列属性作为数据源,包括列表数据(list)、表格列(columns)、操作按钮列(operates)、总数(total)、分页参数(pagination)等。
在模板中,使用el-table组件来展示表格数据,使用el-pagination组件来实现分页功能。el-table-column用来定义每列的样式和展示内容。组件中还包括其他的一些方法和事件处理函数,如handleSizeChange用于切换每页显示的数量,handleIndexChange用于切换页码,handleSelectionChange处理多行选中等。
此外,还定义了一些样式规则来美化表格的显示效果,如设置表头颜色、调整列的样式、设置操作按钮组的布局、设置筛选弹窗和表格操作弹窗的样式等。
最后,使用了scss来编写样式表,通过设置类名来控制样式的展示。
在标签中,定义了一个表格组件,包括表格本身,列定义,按钮操作组,和分页控件。
在标签中,导入了必要的依赖,并定义了组件的属性(props)、数据(data)、生命周期钩子(activated、beforeDestroy、deactivated、created、mounted)和方法(methods)。
props
属性用于接受从父组件传递进来的数据,如数据列表 list
、列定义 columns
、按钮操作 operates
、总数 total
、分页参数 pagination
等。
data
数据属性包括一些内部状态,如表格高度 height
、监听窗口调整大小的回调函数 $_resizeHandler
、当前页码 pageIndex
、表格分页信息 tableCurrentPagination
、多行选中数据 multipleSelection
等。
在生命周期钩子中,组件监听窗口大小调整事件,自动调整表格高度,并在适当的生命周期中初始化和销毁事件监听器。
methods
包括一系列方法,如计算表头宽度的方法 headSpanFit
、初始化事件监听器的方法 initListener
、销毁事件监听器的方法 destroyListener
、调整表格高度的方法 resize
、处理每页显示数量变化的方法 handleSizeChange
、处理页码变化的方法 handleIndexChange
、处理多行选中的方法 handleSelectionChange
等。
最后,在标签中定义了一些样式,包括表格样式、分页样式、按钮样式、筛选和操作弹窗样式等。
{{ scope.row[column.prop] === 0
? 0
: scope.row[column.prop] || "--" }}
{{
btn.label }}
// 日期格式化
export function parseTime(time, pattern) {
if (arguments.length === 0 || !time) {
return null
}
const format = pattern || '{y}-{m}-{d} {h}:{i}:{s}'
let date
if (typeof time === 'object') {
date = time
} else {
if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) {
time = parseInt(time)
} else if (typeof time === 'string') {
time = time.replace(new RegExp(/-/gm), '/').replace('T', ' ').replace(new RegExp(/\.[\d]{3}/gm), '');
}
if ((typeof time === 'number') && (time.toString().length === 10)) {
time = time * 1000
}
date = new Date(time)
}
const formatObj = {
y: date.getFullYear(),
m: date.getMonth() + 1,
d: date.getDate(),
h: date.getHours(),
i: date.getMinutes(),
s: date.getSeconds(),
a: date.getDay()
}
const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
let value = formatObj[key]
// Note: getDay() returns 0 on Sunday
if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value] }
if (result.length > 0 && value < 10) {
value = '0' + value
}
return value || 0
})
return time_str
}
export function debounce(func, wait, immediate) {
let timeout, args, context, timestamp, result
const later = function() {
// 据上一次触发时间间隔
const last = +new Date() - timestamp
// 上次被包装函数被调用时间间隔 last 小于设定时间间隔 wait
if (last < wait && last > 0) {
timeout = setTimeout(later, wait - last)
} else {
timeout = null
// 如果设定为immediate===true,因为开始边界已经调用过了此处无需调用
if (!immediate) {
result = func.apply(context, args)
if (!timeout) context = args = null
}
}
}
return function(...args) {
context = this
timestamp = +new Date()
const callNow = immediate && !timeout
// 如果延时不存在,重新设定延时
if (!timeout) timeout = setTimeout(later, wait)
if (callNow) {
result = func.apply(context, args)
context = args = null
}
return result
}
}
prop
的函我们将这样的组件标记为functional
:
this
上下文 {
functional: true,
// Props 是可选的
props: {
// ...
},
// 为了弥补缺少的实例
// 提供第二个参数作为上下文
render: function (createElement, context) {
// ...
}
}
props
: 提供所有prop
的对象children:VNode
子节点的数组slots
: 一个函数,返回了包含所有插槽的对象scoptedSlots
:(2.6.0) 一个暴露传入的作用域插槽的对象,也以函数形式暴露普通插槽data
:传递个组件的整个数据对象,作为createElement
的第二个参数传入组件parent
:对父组件的引用listeners
:(2.3.0+) 一个包含了:所有父组件为当前组件祖册的事件监听器对象,是data.on
的一个别名injections
:(2.3.0+) 如果使用了inject
选项,则改对象包含了:应当被注入的属性;
import Vue from 'vue'
import App from './App'
Vue.config.productionTip = false
new Vue({
el: '#app',
render: h => h(App)
})
在使用脚手架创建vue项目的过程,我们很容易看到render这个函数,相对于其他标签,我们对于render还是比较陌生的,因此写下这篇文章你我共同理解。
VUE推荐在绝大多数情况下使用template来创建我们的HTML。然而在一些场景中,我们真的需要JavaScript的完全编程的能力,这就是render函数,它比template更接近编译器。(这是官方的话)
简单来说,我们为什么要使用render函数呢?? 便是因为我们最经常使用的一个引入。
import Vue from "vue";
这一个引入你看似没有任何问题,但问题恰恰就是出在这。在不同版本的vue中,有vue.js和vue.runtime.xxx.js这两种js文件。其中
(1)vue.js是完整版的vue,包含核心功能+模板解析器。
(2)vue.runtime.xxx.js是运行版vue,只包含核心功能,没有模板解析器。
VUE开发者为了让我们打包的文件能尽可能小一点,在上述引入的是运行版vue。因为vue.runtime.xxx.js没有模板解析器,所以不能使用template配置项,这时候就需要使用render函数去接收到的createElement函数去指定具体内容,创建html模板。
render 函数即渲染函数,它是个函数,它的参数 createElement 也是个函数。
上边的代码中 render: h => h(App) ,这是 ES6的箭头函数的写法,可以把 h 当作 createElement 的别名。所以这段代码其实相当于
render: function (createElement) {
return createElement(App)
}
这个函数的作用就是生成一个 VNode节点,render 函数得到这个 VNode 节点之后,返回给 Vue.js 的 mount 函数,渲染成真实 DOM 节点,并挂载到根节点上。
createElement 函数的返回值是 VNode(即:虚拟节点)
createElement 函数的3个参数
new Vue({
el: '#app',
render:function (createElement) {
//1.普通用法
// createElement(标签,{属性},[内容])
return createElement("h2",{class:"box"},['hello',createElement("button",["按钮"])])
}
})
同时createElement也可以传进去一个组件,因此
render: h => h(App)
等同于
render:function (createElement) {
return createElement(App)
}