Vue 傳統都會以 Template 處理 HTML,Script 處理 JavaScript,事實上 Vue 有另外一種寫法:在 redner()
以 JSX 完全在 JavaScript 處理 HTML。
Version
Vue 2.6.11
Setup
$ yarn add @vue/babel-preset-jsx @vue/babel-helper-vue-jsx-merge-props --dev
Vue CLI 目前還沒有支援 JSX,需要自行安裝以上 package。
babel.config.js
module.exports = {
presets: [
'@vue/babel-preset-jsx'
]
}
修改 babel.config.js
的 presets
。
.eslintrc.js
module.exports = {
root: true,
env: {
node: true
},
'extends': [
'plugin:vue/essential',
'eslint:recommended'
],
parserOptions: {
parser: 'babel-eslint'
},
rules: {
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'no-unused-vars': 'off'
}
}
16 行
'no-unused-vars': 'off'
加上 no-unused-vars': 'off'
,因為 render(h)
的 h
為必要,但 ESLint 會檢查而導致編譯失敗。
JSX
以 JSX 實現 Hello World。
let render = function(h) {
let { message } = this
return <p>Hello { message }</p>
}
export default {
data: () => ({
message: 'World'
}),
render
}
第 2 行
let render = function(h) {
let { message } = this
return <p>Hello { message }</p>
}
HTML 改在 render()
內直接 return
,不必如 jQuery 那樣將 HTML 視為 String,直接在 JavaScript 寫 HTML 即可,這就是 JSX。
Ramda
使用 map()
取代 v-for
。
import { map } from 'ramda'
let render = function(h) {
let { books } = this
return (
<ul>
{ map(({ id, title }) => <li key={ id }>{ title }</li>, books) }
</ul>
)
}
export default {
data: () => ({
books: [
{ title: 'FP in JavaScript', price: 100 },
{ title: 'Programming Haskell', price: 200 },
{ title: 'Speaking JavaScript', price: 300 },
]
}),
render
}
第 4 行
let render = function(h) {
let { books } = this
return (
<ul>
{ map(({ id, title }) => <li key={ id }>{ title }</li>, books) }
</ul>
)
}
直接以 Ramda 的 map()
取代 v-for
產生 HTML,這也使得 Ramda 不再只能處理資料,也能用在 HTML。
Conclusion
- JSX 的優點在於直接是 JavaScript 一部分,因此 JavaScript 的強項如 first-class function、closure、IIFE、currying … 等技巧都能用於 JSX,也能使用 Ramda 組合出功能強大的 function 處理 HTML,不再如 template 只能用有限的 directive 處理