浅析JSX模板组件使用

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

 

原文地址:https://www.cnblogs.com/goloving/p/13970454.html