在老项目中单独引入vue.js,使用自定义指令

传统项目,作一个表格渲染,然而数据过多,传统方式费时费力,便引入vue和elelment  ui,因为表格须要渲染的数据过多一个表格上千条,致使切换tab更新表格时缓慢,体验太差,因而作了自定义指令,v-loadmore下拉加载更多,先上代码、javascript

<div id="detailTable2" style="display: none; margin: 0; padding: 0; height: 0;color:#fff;">
<template>
<el-table v-bind:data="deatilTable" v-loadmore="loadMore" border style="width: 100%" height="400">
<el-table-column prop="DataDateStr" label="时间" align="center" width="314"></el-table-column>
<el-table-column prop="DataValue1" label="00分" align="center" width="250"></el-table-column>
<el-table-column prop="DataValue2" label="15分" align="center" width="250"></el-table-column>
<el-table-column prop="DataValue3" label="30分" align="center" width="250"></el-table-column>
<el-table-column prop="DataValue4" label="45分" align="center" width="250"></el-table-column>
</el-table>
</template>
</div>html

 

function renderDetailTable(HistoryDetailTableInfos, detailTem) {
//加载表数据
var Main = {
methods: {
dateFormat: function (row, column) { //时间格式化
var date = row[column.property];
if (date == undefined) {
return "";
}
return formatMonthDate(date);
},
dateFormatYMD: function (row, column) { //时间格式化
var date = row[column.property];
if (date == undefined) {
return "";
}
return formatMonthDateYMD(date);
},
loadMore:function() {
if (this.page >= HistoryDetailTableInfos.length) {
return;
}
this.page += 20;
this.deatilTable=HistoryDetailTableInfos.slice(0, this.page)


}
},
data: function () {
return {
deatilTable: HistoryDetailTableInfos.slice(0,20),
page:20
}
}
};vue

//加载表数据(divtemplate模板需从新加载)
$("#detailTableLoad").html($(detailTem).html());
var Ctor = Vue.extend(Main);
Vue.directive('loadmore', {
bind(el, binding) {
const selectWrap = el.querySelector('.el-table__body-wrapper')
selectWrap.addEventListener('scroll', function () {
let sign = 0
const scrollDistance = this.scrollHeight - this.scrollTop - this.clientHeight
if (scrollDistance <= sign) {
binding.value()
}
})
}
})
new Ctor().$mount('#detailTableScroll');
}java

使用Vue.directive自定义指令须要了解node

钩子函数

一个指令定义对象能够提供以下几个钩子函数 (均为可选):express

  • bind:只调用一次,指令第一次绑定到元素时调用。在这里能够进行一次性的初始化设置。
  • inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不必定已被插入文档中)。
  • update:所在组件的 VNode 更新时调用,可是可能发生在其子 VNode 更新以前。指令的值可能发生了改变,也可能没有。可是你能够经过比较更新先后的值来忽略没必要要的模板更新 (详细的钩子函数参数见下)。
  • componentUpdated:指令所在组件的 VNode 及其子 VNode 所有更新后调用。
  • unbind:只调用一次,指令与元素解绑时调用。

接下来咱们来看一下钩子函数的参数 (即 elbindingvnode 和 oldVnode)。api

钩子函数参数

指令钩子函数会被传入如下参数:app

  • el:指令所绑定的元素,能够用来直接操做 DOM 。
  • binding:一个对象,包含如下属性:ide

    • name:指令名,不包括 v- 前缀。
    • value:指令的绑定值,例如:v-my-directive="1 + 1" 中,绑定值为 2
    • oldValue:指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。不管值是否改变均可用。
    • expression:字符串形式的指令表达式。例如 v-my-directive="1 + 1" 中,表达式为 "1 + 1"
    • arg:传给指令的参数,可选。例如 v-my-directive:foo 中,参数为 "foo"
    • modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar 中,修饰符对象为 { foo: true, bar: true }
  • vnodeVue 编译生成的虚拟节点。移步 VNode API 来了解更多详情。
  • oldVnode:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。

特别说明函数

若是指令须要多个值,能够传入一个 JavaScript 对象字面量。记住,指令函数可以接受全部合法的 JavaScript 表达式。

<div v-demo="{ color: 'white', text: 'hello!' }"></div>
Vue.directive('demo', function (el, binding) {
  console.log(binding.value.color) // => "white"
  console.log(binding.value.text)  // => "hello!"
})


因此上面的v-loadmore="loadMore"传入的是一个方法
loadMore

而binding.value=this.loadMore,则
binding.value()=this.loadMore(),因此在给el下class为.el-table__body-wrapper的DOM绑定监听滚动事件,滚动到底部,执行this.loadMore(),从而达到下拉加载更多的效果,也使切换表格不用一次加载过多数据致使显示缓慢,优化用户体验。


再看看

Vue.extend

Vue.extend 属于 Vue 的全局 API,在实际业务开发中咱们不多使用,由于相比经常使用的 Vue.component 写法使用 extend 步骤要更加繁琐一些。可是在一些独立组件开发场景中,Vue.extend + $mount 这对组合是咱们须要去关注的。

官方文档

学习开始以前咱们先来看一下官方文档是怎么描述的。

Vue.extend( options )

  • 参数

    • {Object} options
  • 用法

    使用基础 Vue 构造器,建立一个“子类”。参数是一个包含组件选项的对象。

    data 选项是特例,须要注意 - 在 Vue.extend() 中它必须是函数

    <div id="mount-point"></div>
    // 建立构造器 var Profile = Vue.extend({ template: '<p>{{firstName}} {{lastName}} aka {{alias}}</p>', data: function () { return { firstName: 'Walter', lastName: 'White', alias: 'Heisenberg' } } }) // 建立 Profile 实例,并挂载到一个元素上。 new Profile().$mount('#mount-point')

    结果以下:

    <p>Walter White aka Heisenberg</p>
  • 参考组件

能够看到,extend 建立的是 Vue 构造器,而不是咱们平时常写的组件实例,因此不能够经过 new Vue({ components: testExtend }) 来直接使用,须要经过 new Profile().$mount('#mount-point') 来挂载到指定的元素上。

为何使用 extend

在 vue 项目中,咱们有了初始化的根实例后,全部页面基本上都是经过 router 来管理,组件也是经过 import 来进行局部注册,因此组件的建立咱们不须要去关注,相比 extend 要更省心一点点。可是这样作会有几个缺点:

  1. 组件模板都是事先定义好的,若是我要从接口动态渲染组件怎么办?
  2. 全部内容都是在 #app 下渲染,注册组件都是在当前位置渲染。若是我要实现一个相似于 window.alert() 提示组件要求像调用 JS 函数同样调用它,该怎么办?

这时候,Vue.extend + vm.$mount 组合就派上用场了。

简单示例

咱们照着官方文档来建立一个示例:

import Vue from 'vue' const testComponent = Vue.extend({ template: '<div>{{ text }}</div>', data: function () { return { text: 'extend test' } } })

而后咱们将它手动渲染:

const extendComponent = new testComponent().$mount()

这时候,咱们就将组件渲染挂载到 body 节点上了。

咱们能够经过 $el 属性来访问 extendComponent 组件实例:




参考连接http://www.javashuo.com/article/p-yoholnxv-dv.htmldocument.body.appendChild(extendComponent.$el)
相关文章
相关标签/搜索