一、使用template還是JSX?
1、template特點
- 模板語法(HTML的擴展)
- 數據綁定使用Mustache語法(雙大括號):
<span>{{title}}<span>
2、JSX特點
- JavaScript的語法擴展
- 數據綁定使用單引號:
<span>{title}<span>
Vue官方建議使用template
模板,但是 :
更抽象一點來看,我們可以把組件區分為兩類:一類是偏視圖表現的 (presentational),一類則是偏邏輯的 (logical)。
我們推薦在前者中使用模板,在后者中使用 JSX 或渲染函數。這兩類組件的比例會根據應用類型的不同有所變化,但整體來說我們發現表現類的組件遠遠多於邏輯類組件。
也就是說,在一些特定場景下可以建議使用JSX語法。比如以下面的一組狀態判斷按鈕為例,我們很容易就下意識地在模板內寫下這種代碼:
<button v-if="status === 1" class="btn1" :class="status === 1" @click="">未開始</button>
<button v-if="status === 2" class="btn2" :class="status === 2" @click="">進行中</button>
<button v-if="status === 3" class="btn3" :class="status === 3" @click="">可領取</button>
<button v-if="status === 4" class="btn4" :class="status === 4" @click="">已領取</button>
是不是很多v-if-else 看的眼花繚亂,別着急,來看jsx大法。
如果我們利用渲染函數可以將上面的代碼抽取成優雅的使用組件
<!DOCTYPE html>
<html lang="en">
<body>
<div id="app">
<child :status="status"></child>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script> Vue.component('child', { props: { status: { type: Number, required: true } }, render(createElement) { const innerHTML = ['未開始', '進行中', '可領取', '已領取'][this.status] return createElement('button', { class: { active: this.status }, attrs: { id: 'btn' }, domProps: { innerHTML }, on: { click: () => console.log(this.status) } }) } }) var app = new Vue({ el: '#app', data: { status: 0 } }) </script>
</body>
</html>
我們將所有的邏輯封裝進渲染函數內,外部只需要傳遞一個狀態參數即可改變:<child :status="status"></child>
二、JSX語法如何在vue中使用
1、什么是JSX?
JSX就是Javascript和XML結合的一種格式。React發明了JSX,利用HTML語法來創建虛擬DOM。當遇到<,JSX就當HTML解析,遇到 { 就當JavaScript解析。vue中大部分場景是不需要用render函數的,還是用模板更簡潔直觀。
vue template
語法簡單明了,數據操作與視圖分離,開發體驗友好。但是在某些特定場合中,會限制一些功能的擴展,如動態使用過濾器、解析字符串類型的模板文件、動態渲染機器人交互
等。以上功能的實現可以借助vue的render語法
,render語法比template
更偏底層,允許在HTML中使用js語法,可以極大的擴展HTML的能力。注意:vue+jsx
的寫法,需要 摒棄
vue的部分特性
2、props傳參
// /views/about.vue
子組件 export default { props:['msg','changeInput'], //接收父組件傳遞的值、事件等
render(){ return( <div id='wrap'>
<div class='children'>我是子組件</div>
<div class='title'>這是父組件傳遞過來的數據:{this.msg}</div>
<input placeholder='請輸入姓名' value={this.msg} onInput={this.changeInput}/>
</div> ) } }
<style lang="less" scoped> .children{ color: blue } </style>
props:
子組件接收父組件傳遞的數據,使用onInput
監聽輸入框變化實現數據雙向綁定,把輸入框事件操作交給父組件,子組件動態監聽輸入框數據
/views/home.vue
父組件:組件引用后直接在函數中使用,無需使用components
<script> import About from './About.vue' export default { name: 'Home', data(){ return{ msg:'這是父組件,使用JSX渲染' } }, methods:{ changeInput(e){ this.msg = e.target.value console.log(this.msg); } }, render(){ return( <div id='wrap'>
<p class='title'>我是父組件</p>
//引用子組件,把父組件的數據、方法傳給子組件
<About msg={this.msg} changeInput={this.changeInput}></About>
</div> ) } } </script>
<style lang="less" scoped> .title{ color: red } </style>
3、事件
比如點擊事件:vue中綁定點擊事件直接是@click='fn'
,在JSX
中需要改為onClick={fn}
render(){ return( <div id='wrap'>
<p onClick={this.alert}>點擊我出現彈框</p>
</div> ) }