天天看點

vue slot scope使用_Vue的一些小技巧,可以收藏用到的時候特别爽

vue slot scope使用_Vue的一些小技巧,可以收藏用到的時候特别爽

給 props 屬性設定多個類型

這個技巧在開發元件的時候用的較多,為了更大的容錯性考慮,同時代碼也更加人性化:

export default { props: { width: { type: [String, Number], default: '100px' } // 或者這樣 // width: [String, Number] }}           

比如一個 上暴露了一個 width 屬性,我們既可以傳 100px,也可以傳 100 :

{{ computedWidth }}           

使用:

阻止 預設送出行為

有時候我們在用餓了麼元件 在文本框中鍵入 enter 快捷鍵的時候會預設觸發頁面重新整理。我們可以加入如下代碼解決其預設行為:

...           

使用 元件

Element 官方是沒有明确提供這個元件的,但是其源碼 中确實存在。關于如何使用我寫了一個Demo,你可以狠狠的戳這裡檢視示例,本文不再贅述。

根據業務合并 el-table 中的行和列

最近在做項目的時候遇到一個需求:同一個賬号ID下有多個被配置設定的角色時并列顯示角色資訊。于是就想到了 el-table 提供的合并方法 :span-method。但它對背景資料格式是有要求的:

  • 如果背景傳回的資料是數組裡面嵌套數組的話,你就需要把裡面的數組按順序也拿到外面了
// 假如背景傳回的資料是下面這樣的{ data: [ { id: 1, appkey: 1, name: 'a', list: [{ id: 11, appkey: 1, name: 'a-1'}, {id: 12, appkey: 1, name: 'a-2'}] } { id: 2, appkey: 2, name: 'b', list: [{ id: 21, appkey: 2, name: 'b-1'}, {id: 22, appkey: 2, name: 'b-2'}] } ]}// 整理過後的格式應該是這樣的{ data: [ { id: 1, appkey: 1, name: 'a' }, { id: 11, appkey: 1, name: 'a-1' }, { id: 12, appkey: 1, name: 'a-2' }, { id: 2, appkey: 2, name: 'b' }, { id: 21, appkey: 2, name: 'b-1' }, { id: 22, appkey: 2, name: 'b-2' } ]}           

下面是具體的處理流程:

...            

單檔案樣式提取

如果 a.vue 和 b.vue 都用到了下面的樣式:

.btn { color: silver}// 省略很長的樣式...           

可以考慮把樣式提取到 styleName.scss/css 中,例如:

./components/common.scss

.btn { color: silver}// 省略很長的樣式           

然後再在兩檔案中引入,即:

...           

是不是省了很多代碼呢?快去試試吧!

解決 vue-template-admin 單檔案中背景圖檔生産打包後路徑404問題

  • 找到 build/utils.js
  • 然後找到 generateLoaders 方法
  • 在 if(options.extract){...} 中修改,即:
if (options.extract) { // 解決其打包背景圖檔路徑問題 loaders.push({ loader: MiniCssExtractPlugin.loader, options: { publicPath: '../../' } })} else { ...}           

記住,千萬别再你的 css 中這樣寫:

background: url("/new/static/images/assets/loginbackground.png");複制代碼           

因為 new 檔案夾是背景同學幫你配置的,随時都有可能被修改,一個地方還好,多個地方改起來就蛋疼了。

data 初始化

因為 props 要比 data 先完成初始化,是以我們可以利用這一點給 data 初始化一些資料進去,看代碼:

export default { data () { return { buttonSize: this.size } }, props: { size: String }}           

除了以上,子元件的 data 函數也可以有參數,且該參數是目前執行個體對象。所有我們可以利用這一點做一些自己的判斷。如,改寫上面的代碼:

export default { data (vm) { return { buttonSize: vm.size } }, props: { size: String }}           

template

我們在做 v-if 判斷的時候,可以把判斷條件放在 template 元件上,最終的渲染結果将不包含 元素。

...

...

v-for 也同樣适用。

Lifecycle hook

生命周期鈎子可以是一個數組類型,且數組中的函數會依次執行。

export default { ... created: [ function one () { console.log(1) }, function two () { console.log(2) } ] ...}           

沒什麼用,知道就行了。事實上生命周期鈎子還可以作用于 DOM 元素上,利用這一點,我們可以用父元件中的方法來初始化子元件的生命周期鈎子:

I'm child!

其他鈎子雷同,不再贅述。

v-for

在用 v-for 周遊數組的時候,我們一般都會錯誤的這樣去做,舉個栗子:

v-for 和 v-if 放在同一個元素上使用:

{{ user.name }}

由于 v-for 和 v-if 放在同一個元素上使用會帶來一些性能上的影響,官方給出的建議是在計算屬性上過濾之後再進行周遊。是以平時開發不推薦一起使用,知道有這回事即可,不至于面試時不知道。 關于為什麼不推薦放在一起使用,參見 避免-v-if-和-v-for-用在一起。

混合

如果好多元件都共用到一些像 props、data、methods 等,可以單獨抽出來放到 mixins 混合器中。比如,在使用者管理清單中使用。

分頁混合器:

// paging-mixin.vueexport default { props: { pageSize: 1, pageLength: 10, currentPage: 1 total: 20 }, methods: { /** * 上一頁 */ prevPage (page) { ... }, /** * 下一頁 */ nextPage (page) { ... } /** * 跳轉到目前頁 */ currentPage (page) { ... } }}           

Users.vue:

不用每個頁面都寫一遍 props 和 methods 了。

render 函數

下面是一段簡單的 template 模闆代碼:

title

this is content

我們用渲染函數來重寫上面的代碼:

export default { render (h) { let _c = h return _c('div',  { class: 'box'},  [_c('h2', {}, 'title'), 'this is content']) }}           

事實上,Vue 會把模闆(template)編譯成渲染函數(render),你可以通過一個線上工具 實時檢視編譯結果。上面的 template 模闆會被編譯成如下渲染函數:

let render = function () { return _c('div', {staticClass:"box"}, [_c('h2', [_v("title")]), _v("this is content")])}           

是不是很像? 正如官方說的,渲染函數比 template 更接近編譯器。如果用一個流程圖來解釋的話,大概是這個樣子:

template ↓預編譯工具(vue-loader + vue-template-compile) ↓ render ↓resolve vnode           

具體參見 Vue聲明周期圖示。

渲染函數用處:

  • 開發元件庫,Element 源碼用的都是 render
  • 封裝一些高階元件。元件裡面嵌套元件就是高階元件,前提是要滿足元件三要素:props、event、slot
  • 用于處理一些複雜的邏輯判斷。如果我們一個元件裡面有很多 v-if 判斷的話,用模闆就顯得不合适了,這個時候可以用渲染函數來輕松處理

errorCaptured

捕獲一個來自子孫元件的錯誤時被調用。有時候當我們想收集錯誤日志,卻不想把錯誤暴露到浏覽器控制台的時候,這很有用。下面是個例子:

Child.vue

Parent.vue

關于 errorCaptured 更多說明,請移步官網-> 。

v-once

通過 v-once 建立低開銷的靜态元件。渲染普通的 HTML 元素在 Vue 中是非常快速的,但有的時候你可能有一個元件,這個元件包含了大量靜态内容。在這種情況下,你可以在根元素上添加 v-once 特性以確定這些内容隻計算一次然後緩存起來,就像這樣:

使用者協定

... a lot of static content ...

隻渲染元素群組件一次。随後的重新渲染,元素/元件及其所有的子節點将被視為靜态内容并跳過。這可以用于優化更新性能。關于 v-once 更多介紹,請移步官網->。

slot-scope

作用域插槽。[email protected] 版本以前叫 scope,之後的版本用 slot-scope 将其代替。除了 scope 隻可以用于 元素,其它和 slot-scope 都相同。

用過 Element 元件的同學都知道,當我們在使用 的時候會看到如下代碼:

[email protected] 的版本:

編輯删除           

但在 2.0 之後的版本替換成了 slot-scope。

[email protected]:

編輯删除           

說白了,slot-scope 相當于函數的回調,我把結果給你,你想怎麼處理就怎麼處理,一切随你:

function getUserById (url, data, callback) { $.ajax({ url, data, success: function (result) { callback(result) } })}// 使用getUserById('/users', { id: 1 }, function (response) { // 拿到資料并開始處理自己的頁面邏輯})           

下面我們來簡單模拟下 元件内部是怎麼使用 slot-scope 的,看代碼:

模拟的 元件:

// 定義模闆let template = `            
  • {{ item.name }}

`Vue.component('el-table', { template, props: { data: Array, default: [] }})

在你需要的地方使用 元件:

HTML:

{{ scope.row.name }} {{ scope.row.name }}

JavaScript:

new Vue({ el: '#app', data: { userData: [ {id: 1, name: '張三', isActived: false}, {id: 2, name: '李四', isActived: false}, {id: 1, name: '王五', isActived: true}, {id: 1, name: '趙六', isActived: false}, ] }})           

CSS:

.red { color: red}複制代碼           

你可以狠狠的戳這裡檢視上面的效果!最後,我們再使用 render 函數來重構上面的代碼:

JavaScript:

// `` 元件Vue.component('el-table', { name: 'ElTable', render: function (h) { return h('div', {  class: 'el-table' }, this.$slots.default) }, props: { data: Array }})// ``Vue.component('el-table-column', { name: 'ElTableColumn', render: function (h) { // 定義一個存放 li 元素的數組 let lis = [],  // 擷取父元件中的 data 數組 data = this.$parent.data // 周遊數組,也就是上面的 `v-for`,生成 `` 标簽 // `this.$scopedSlots.default` 擷取的就是上面 slot-scope 作用于插槽的部分, // 并把 `{ row: item }` 傳給上面的 `scope` 變量 data.forEach((item, index) => { let liEl = h('li', { key: item.id }, [ this.$scopedSlots.default({ row: item }) ]) // 把生成的 li 标簽存到數組 lis.push(liEl) }) return h('ul', { class: 'el-table-column' }, lis) }})           

在你的頁面這樣來使用:

HTMl:

{{ scope.row.name }} {{ scope.row.name }}

JavaScript:

new Vue({ el: '#app', data: { list: [ { id: 1, name: '張三', actived: false }, { id: 1, name: '李四', actived: false }, { id: 1, name: '王五', actived: true }, { id: 1, name: '趙六', actived: false }, ] }})           

繼續閱讀