Vue 中使用jsx示例

了解什么是JSX

为何要在Vue中使用jsx呢,首先咱们须要了解JSX是什么,它解决了什么问题,最后如何使用它。html

jsx的定义

JSX 是一种相似于 XML 的 JavaScript 语法扩展 JSX 不是由引擎或浏览器实现的。相反,咱们将使用像 Babel 这样的转换器将 JSX 转换为常规 JavaScript。基本上,JSX 容许咱们在 JavaScript 中使用相似 HTML 的语法。vue

jsx的优点

  1. 能够将 模版分离 这样模版的每一个部分更加独立,又能够随机的组合,复用性更高。相比与组件的组合,粒度更细
  2. 使用 js 可配置每项要渲染的 dom,更加动态可配置化

小结

虽然了解了jsx的相关定义,可能对它仍是比较陌生,首先要知道不管在 Vue中仍是React,使用JSX 都是可选的。如:react

// react 中使用jsx
class Hello extends React.Component {
  render() {
    return <div>Hello {this.props.toWhat}</div>;
  }
}

// 同等效果的代码能够以下,只不过是babel帮咱们作了这些
class Hello extends React.Component {
  render() {
    return React.createElement('div', null, `Hello ${this.props.toWhat}`);
  }
}
复制代码

了解Vue组件

在使用 Vue 时一般咱们经过new Vue()是建立一个根实例,而组件是可复用的 Vue 实例 它们与 new Vue 接收相同的选项,例如 data、computed、watch、methods 以及生命周期钩子等。npm

new Vue({
  data: {
    foo: 1
  },
  computed: {
    bar: function () { /* ... */ }
  },
  methods: {
    baz: function () { /* ... */ }
  }
})
复制代码

为了处理多个组件映射关系,将路由实例对象做为参数传递给 Vue构造函数。new Vue()建立的是根实例,而每一个页面组件实例经过 router 来控制。结构以下:数组

export default {
    name: '',
    props:{},
    data:{},
    methods:{}
  }
复制代码

能够看到路由映射的组件其实也是暴露出一个对象,在Vue就是经过一个对象去描述组件。而默认状况下,咱们使用 template 做为模版,若是想使用 jsx 来渲染模版写格式以下,其实就是省略来 template 模版,取而代之使用 render 方法 return 要渲染的模版。而且其余都是选填项,render 方法必须返回出要渲染的模版。浏览器

export default {
    name: '',
    props:{},
    data:{
        return {
            text:'hello jsx'
        }
    },
    render(){
        return <div>{text}</div>
    },
    methods:{}
  }
复制代码

Vue 中使用jsx

经常使用 React 的同窗对 jsx 的语法比较熟悉,其实不少用法能够参照 react 的官方文档以下面咱们会提到的经常使用语法bash

js 环境

在 Vue 模版中渲染一个变量的方式babel

<div id="app">
  {{ message }}
</div>
复制代码

包括使用 v-bind 绑定一个变量值app

<span v-bind:title="message">
    鼠标悬停几秒钟查看此处动态绑定的提示信息!
</span>
复制代码

而在 jsx 中是用 {} 表示的相同的代码表示以下dom

render(){
    return (
        <div id="app">
            <div>
              { message }
            </div>
            <span title={message}>
                鼠标悬停几秒钟查看此处动态绑定的提示信息!
            </span>
        </div>
    )
}
复制代码

须要解释一下的是,在 Vue 中 "" 表示一个js环境,你能够在其中作一些简单的运算 <img :src="'/path/to/images/' + fileName">,在 jsx 中{}表示 js 环境。<span>{3+2}</span>

v-if 语法糖

Vue经常使用的 v-if 来控制dom的显示隐藏,本质就是 dom 的渲染和卸载。那么在 jsx 中如何实现

data(){
    return {
        isShow:false
    }
},
render(){
    return <div>
        { this.isShow ? <span>显示啦</span>:null}
    </div>
}
复制代码

上面代码中 { } 表示一个js环境,判断this.isShow 的真假来控制 dom 的显示与否

绑定事件

Vue 中使用 v-on 来绑定事件 简写@

<button @click="onButtonClick">按钮</button>
复制代码

而在jsx中绑定事件前面都会加一个 on- 做为前缀

<button onClick={this.onButtonClick}>按钮</button>
复制代码
  1. 如何在 jsx 中传参
<button onClick={this.onButtonClick.bind(this,value)}>按钮</button>
复制代码

上面对面中的 value 就是传递给 onButtonClick 函数的参数。首先经过 { } 创建起js环境,而后经过 this.onButtonClick 拿到定义在 methods 中定义的函数,经过 bind 函数给当前函数传递参数 value 并返回一个待执行的新函数。最终,onClick 绑定的是 bind 返回的新函数。

  1. 如何绑定子组件 emit 的事件,假设在 child.vue 中派发了一个 emit 事件,jsx中如何去绑定监听事件
// father.js
export default {
    components:{
        child
    },
    render(){
        return  <div>
        <child onCancel={this.onCancel} />
    </div>
    }
}
// child.vue
methods:{
    onCancelClick(){
        this.$emit('cancel')
    }
}
复制代码
  1. 其余类型的事件的绑定 , 类比 onClick 就是前面加上 on-
<input  onChange={this.onValueChange} />
复制代码

v-for 枚举实现

在 Vue 中咱们能够用 v-for 指令基于一个数组来渲染一个列表。

<ul id="example-1">
  <li v-for="item in items">
    {{ item.message }}
  </li>
</ul>
复制代码

在 jsx 中在 { } 使用数组的 map 方法遍历生成一个新的数组

<div>
    {this.tagList.map(item => {
        return <div>{item}</div>
    })}
</div>
复制代码

slot

Vue 中在标签中间添加内容的方式,向组件传递内容,slot 位置内容会被传入的内容替代

// 传值
<alert-box>
  Something bad happened.
</alert-box>

// 接收
Vue.component('alert-box', {
  template: `
    <div class="demo-alert-box">
      <slot></slot>
    </div>
  `
})
复制代码

jsx 中经过 this.$slots 对象能够拿到组件标签中的内容

<Temp>
    123
    <span>ccc</span>
</Temp>
// Temp.js
export default {
  render(){
    return <h1>{this.$slots.default}</h1>
  }
}
复制代码
  1. 具名插槽
<Temp>
    123
    <span slot="text">ccc</span>
</Temp>
// Temp.js
export default {
  render(){
    return <h1>{this.$slots.text}</h1>
  }
}
复制代码
  1. 解构插槽
export default {
  data(){
    return {
    list: [
        {
          "id":11,
          "name":"保险百科"
        }
      ],
      propList: [
        {
          props: {
            prop: "name",
            label: "分类名称"
          }
        },
      ]
    }
  },
  render(){
    let slot = {
      scopedSlots :{
        default :props=>{
          return <h1>{props.row.name}</h1>
        }
      }
    }
    return (
      <el-Table data={this.list}  >
      {this.propList.map((item, index) =>{
        return (
          <el-table-column {...item} {...slot} ></el-table-column>
        )
      }
      )}
    </el-Table>
    )
  }
}
复制代码

props 属性传递

Vue 中父组件传递 props 给子组件 经过 v-bind,若是有多个值须要传递,则须要声明多个props,或者传递一个对象给子组件,

<my-component :prop="someThing"></my-component>
复制代码

而 jsx 中可使用... 扩展符来实现多个值的传递,注意传递的属性须要声明在 props 对象下

render(){
    let value = {
      props:{
        type:'primary',
        disabled:'disabled'
      }
    }
    return (
      <el-button {...value}>按钮</el-button>
    )
  }
复制代码

codepen 完整示例

codepen 上没有找到 babel-plugin-transform-vue-jsx 插件,没法正常展现,能够copy代码到本地项目使用

参考

babel-plugin-transform-vue-jsx
渲染函数 & JSX

相关文章
相关标签/搜索