一、使用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>
)
}