在老項目中單獨引入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)
相關文章
相關標籤/搜索