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