Vue提供了一個functional
的布爾值選項,設置爲true
可使組件無狀態和無實例,也就是沒有data
和this
上下文。這樣用render
函數返回虛擬節點能夠更容易渲染,由於函數化組件只是一個函數,渲染開銷要小不少。html
使用函數化組件時,Render函數提供了第二個參數context
來提供臨時上下文。組件須要的data
、prop
、slots
、children
、parent
都是經過這個上下文來傳遞。好比this.level
要改寫爲context.props.level
,this.$slots.default
改變爲context.children
。vue
用函數化組件展現一個根據數據智能選擇不一樣組件的場景:數組
<p data-height="365" data-theme-id="0" data-slug-hash="mKRKGm" data-default-tab="html,result" data-user="whjin" data-embed-version="2" data-pen-title="Vue-函數化組件-根據數據選擇組件" class="codepen">See the Pen Vue-函數化組件-根據數據選擇組件 by whjin (@whjin) on CodePen.</p>
<script async src="https://static.codepen.io/ass...;></script>瀏覽器
函數化組件主要適用於如下兩個場景:babel
children
、props
、data
傳遞給子組件以前操做它們。爲了讓Render函數更好地書寫和閱讀,Vue提供了插件babel-plugin-transform-vue-jsx
來支持JSX語法。app
使用createElement
時,經常使用配置:async
<p data-height="365" data-theme-id="0" data-slug-hash="Vdpwpz" data-default-tab="js" data-user="whjin" data-embed-version="2" data-pen-title="Vue-createElement" class="codepen">See the Pen Vue-createElement by whjin (@whjin) on CodePen.</p>
<script async src="https://static.codepen.io/ass...;></script>函數
JSX寫法:this
<p data-height="300" data-theme-id="0" data-slug-hash="eKvYvm" data-default-tab="js" data-user="whjin" data-embed-version="2" data-pen-title="Vue-JSX" class="codepen">See the Pen Vue-JSX by whjin (@whjin) on CodePen.</p>
<script async src="https://static.codepen.io/ass...;></script>插件
表格組件的全部的內容(表頭和行數據)由兩個prop
構成:columns
和data
。二者都是數組,columns
用來描述每列的信息,並渲染在表頭<head>
內,能夠指定某一列是否須要排序;data
時每一行的數據,由columns
決定每一行裏各列的順序。
爲了讓排序後的columns
和data
不影響原始數據,給v-table
組件的data
選項添加兩個對應的數據,組件全部的操做將在這兩個數據上完成,不對原始數據作任何處理。
columns
的每一項是一個對象,其中title
和key
字段是必填的,用來標識這列的表頭標題,key
的對應data
中列內容的字段名。sortable
是選填字段,若是值爲true
,說明該列須要排序。
v-talbe
組件的prop:columns
和data
的數據已經從父級傳遞過來,v-table
不直接使用它們,而是使用data
選項的currentColumns
和currentData
。因此在v-table
初始化時,須要把columns
和data
賦值給currentColumns
和currentData
。在v-table
的methods
選項裏定義兩個方法用來複制,並在mounted
鉤子內調用。
map()
是JavaScript數組的一個方法,根據傳入的函數從新構造一個新數組。
排序分升序(asc
)和降序(desc
)兩種,並且同時只能對一列數據進行排序,與其餘列互斥,爲了標識當前列的排序狀態,在map
列添加數據時,默認給每列都添加一個_sortType
的字段,而且賦值爲normal
,表示默認排序(也就是不排序)。
在排序後,currentData
每項的順序可能都會發生變化,因此給currentColumns
和currentData
的每一個數據都添加_index
字段,表明當前數據在原始數據中的索引。
render(h) { var ths = [], trs = []; return h('table', [ h('thead', [ h('tr', ths) ]), h('tbody', trs) ]) }
這裏的h
就是createElement
,只是換了個名稱。
表格主題trs
是一個二維數組,數據由currentColumns
和currentData
組成。
先遍歷全部的行,而後再每一行內再遍歷各列,最終組合出主題內容節點trs
。
若是col.sortable
沒有定義,或值爲false
,就直接把col.title
渲染出來,不然除了渲染title
,還加了兩個<a>
元素來實現升序和降序的操做。
排序使用了JavaScript數組的sort()
方法,這裏之因此返回1
或-1
,而不直接返回a[key]<b[key]
,也就是true
或false
,是由於在部分瀏覽器對sort()
的處理不一樣,而1
和-1
能夠作到兼容。
排序前,先將全部列的排序狀態都重置爲normal
,而後設置當前列的排序狀態(asc
或desc
),對用到render的<a>
元素的class
名稱on
,後面經過CSS來高亮顯示當前列的排序狀態。
當渲染完表格後,父級修改了data
數據,好比增長或刪除,v-table
的currentData
也應該更新,若是某列已經存在排序狀態,更新後應該直接處理一次排序。
經過遍歷currentColumns
來找出是否按某一列進行過排序,若是有,就按照當前排序狀態對更新後的數據作一次排序操做。
<p data-height="365" data-theme-id="0" data-slug-hash="XYMmJr" data-default-tab="html,result" data-user="whjin" data-embed-version="2" data-pen-title="Vue-可排序表格組件" class="codepen">See the Pen Vue-可排序表格組件 by whjin (@whjin) on CodePen.</p>
<script async src="https://static.codepen.io/ass...;></script>
發佈一條留言,須要的數據有暱稱和留言內容,發佈操做應該在根實例app
內完成。留言列表的數據也是從app
獲取。
數組list
存儲了全部的留言內容,經過函數handleSend
給list
添加一項留言數據,添加成後把texrarea
文本框置空。
Render函數內的節點使用v-model
:動態綁定value
,而且監聽input
事件,把輸入的內容經過$emit('input')
派發給父組件。
列表數據list
爲空時,渲染一個「列表爲空」的信息提示節點;不爲空時,每一個list-item
贏包含暱稱、留言內容和回覆按鈕3個子節點。
this.list.forEach
至關於template
裏的v-for
指令,遍歷出每條留言。句柄handleReply
直接向父組件派發一個事件reply
,父組件(app
)接收後,將當前list-item
的暱稱提取,並設置到v-textarea
內。
<p data-height="365" data-theme-id="0" data-slug-hash="ZRKGrR" data-default-tab="html,result" data-user="whjin" data-embed-version="2" data-pen-title="Vue-留言列表" class="codepen">See the Pen Vue-留言列表 by whjin (@whjin) on CodePen.</p>
<script async src="https://static.codepen.io/ass...;></script>