相关文章推荐
魁梧的水煮鱼  ·  PyPDF2.errors.Deprecat ...·  10 月前    · 
瘦瘦的伤痕  ·  Day18. 匯入 3D 模型 - iT ...·  1 年前    · 
爱跑步的柳树  ·  Android ...·  1 年前    · 
求醉的大蒜  ·  keytool error ...·  2 年前    · 

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第1天, 点击查看活动详情

为什么需要在vue中使用jsx

几年前面试的时候,被问过这个问题,当时我一脸懵,这两个东西为啥要混用呢?

直到后来,我遇到了这种场景。

tab切换展示组件,大部分组件展示表格,除了2个tab需要展示不同,这个不同,怎么处理呢?

当然可以直接改封装的tab组件,v-if条件渲染嘛

那如果后面再有其他需求,tab组件继续写if么

这个时候,组件就过于冗余啦

那怎么让组件统一处理呢?当然可以用render函数来抽象组件啦

render函数写法有多恶心,想必大家都知道 => 不知道的看段简单的ul,li布局

with(this){  // this 就是 vm
  return _c(
      'div',
          attrs:{"id":"app"}
              'div',
                      'input',
                          directives:[
                                  name:"model",
                                  rawName:"v-model",
                                  value:(title),
                                  expression:"title"
                          domProps:{
                              "value":(title)
                          on:{
                              "input":function($event){
                                  if($event.target.composing)return;
                                  title=$event.target.value
                  _v(" "),
                  (!title) ? _c(
                      'button',
                          on:{
                              "click":add
                      [_v("submit")]
                  ): _e()
          _v(" "), // 空字符串节点
          _c('div',
                      'ul',
                      _l((list),function(item){return _c('li',[_v(_s(item))])})

这...日子没法过了

于是我们就发现了jsx的好用,同样上述代码,可读性更高,更加精简

在vue中如何使用jsx

主要是依赖babel插件

  • 安装babel依赖,npm install babel-plugin-transform-vue-jsx babel-helper-vue-jsx-merge-props
  • 配置.babelrc文件
    "plugins": [
        [ "transform-vue-jsx" ]
    
  • 子组件是函数式组件
  •   // content.js
      export default {
        name: 'content',
        functional: true,
        props: {
          render: Function,
          column: {
            type: Object,
            default: null
          params: {
            type: Object,
            default: () => {}
        render: (h, ctx) => {
          const params = ctx.props.params
          return ctx.props.render && ctx.props.render(h, params)
    
  • 父组件引入
  • <el-tabs
      v-model="activeName">
        <el-tab-pane
          v-for="item in tabList"
          :key="item.code"
          :label="item.label">
          <span v-if="item.render">
              <content
                  :params="item.params"
                  :render="item.render"
                ></content>
          </span>
        </el-tab-pane>
    </el-tabs>
        <script>
            import Content from './content'
            components: {
               Content
        </script>
    

    template转jsx的语法转换

    v-model,v-if,v-forv-html,v-text,vue中的指令

  • jsx语法是不会有对应的指令的,所以我们就要实现这些指令的功能,对于v-model
  • // 在vue中
    <el-input
      v-model="searchParams.searchVal">
    </el-input>
    // 对应jsx语法
    function _input (value) {
        this.searchParams.searchVal = value
    item.render = (h, params) => {
        // 这里也可以从params传入参数
        return (
            <el-input
              value={this.searchParams.searchVal}
              onInput={_input}>
            </el-input>
    
  • v-if其实就是判断语句,用&&或三元表达式
  • // 在vue中
    <el-button v-if="show"></el-button>
    // 对应jsx语法
    item.render = (h, params) => {
        return (
            this.show && <el-button></el-button>
    
  • v-for其实就是循环语句,用map
  • // 在vue中
        <li v-for="item in list">{{item.label}}</li>
    // jsx语法
    item.render = (h, params) => {
         return (
                     list.map((item, index) => (
                           <li>{item.label}</li>
    
  • v-html
  • item.render = (h, params) { 
        return ( 
            <div> <div domPropsInnerHTML={htmlStr}></div> </div> 
    

    vue中el-input组件上触发原生enter事件,@keyup.enter.native对应nativeOnKeyup

    // 在vue中
    <el-input
      @keyup.enter.native="onSearch"
    ></el-input>
    // 在jsx中
    item.render = (h, params) => {
         function _keyup (e) {
            if (e.keyCode === 13) {
              // 13为enter键的键盘码
              this.onSearch()
         return (
             <el-input
              nativeOnKeyup={e => _keyup(e)}>
            </el-input>
    

    vue中的插槽,在jsx中用scopedSlots

    // 在vue中
    <el-table
        :data="tableData">
        <el-table-column
          v-for="column in columnData"
          :key="column.value"
          :prop="column.value"
          :label="column.value"
          sortable
          :sort-change="change">
          <template slot-scope="scope">
            <span>{{scope.row[column.value]}}</span>
          </template>
        </el-table-column>
     </el-table>
    // 在jsx中
    item.render = (h, params) => {
        return (
            <el-table
                data={tableData}>
                  columnData.map((column, index) => (
                    <el-table-column
                      prop={column.value}
                      label={column.label}
                      sortable
                      onSort-change={(...args) => sortChange(...args)}
                      scopedSlots={{
                        default: (scope) => <span>{scope.row[column.value]}</span>
                    </el-table-column>
              </el-table>
    

    组件用-分隔的事件,在jsx中在第一段on后大写即可触发

    比如el-tablesort-change,在jsx中是onSort-change,第一段在on后大写即可,见上个例子

  • 分类:
    前端