Vue template To JSX

6,124 阅读3分钟
  • Vue 模板语法
    模板语法贴近 HTML,也是 Vue 官方推荐的写法,用起来很方便,但是也有不足的地方,因为是 html,linting、类型检查、编辑器的自动完成,这些基本都没有

  • 渲染函数
    这个我没有实际用过,不是很清楚利和弊,如果是用函数返回一个简单 VNode 的话,用这个也可以的

  • JSX
    你可以使用完整的编程语言 JavaScript 功能来构建你的视图页面。比如你可以使用临时变量、JS 自带的流程控制、以及直接引用当前 JS 作用域中的值等等。 开发工具对 JSX 的支持相比于现有可用的其他 Vue 模板还是比较先进的 (比如,linting、类型检查、编辑器的自动完成)。并且从使用上来说,JSX 应该是比渲染函数要好一些的,如果是从 Vue 模板迁移过来,也很方便。

Vue 模板转 JSX

Vue-cli 默认生成的项目里面默认就带有babel-plugin-transform-vue-jsx,所以直接写 jsx 就是了不用担心编译问题,但是还是建议多装一个babel-plugin-jsx-v-model,这个的作用是在 jsx 中使用 v-model,如果没有这个,你要自己手动实现双向绑定。
单文件组件,如果原本是模板想转 JSX 的话,比较简单,把模板复制,然后在 Vue 实例中,写一个 render(){},把代码复制进去就好了,然后你就会看到编辑器一片红。然后就把 vue 模板的语法改成 jsx 语法。变化的基本不大,变化比较大的,应该就是 v-for 和 v-if 了

  • v-bind

      // v-bind tmpl
      <input :disabled="true" />
      // v-bind jsx
      <input disabled={true} />
    
  • v-if

      // v-if tmpl
      <span v-if="item == 1">1</span>
      <span v-else>2</span>
      // v-if jsx
      // 如果复杂一点的话,还是单独写一个函数吧
      {item == 1 ? <span>1</span> : <span>2</span>}
    
  • v-for

      // v-for tmpl
      <ul>
          <li v-for="item in arr" :key={item}>{{item}}</li>
      </ul>
      // v-for jsx
      // 还是那句话,如果比较复杂的还是单独写一个函数
      <ul>
          {arr.map(item => <li key={item}>{item}</li>)}
      </ul>
    
  • v-show 和 v-model

      // v-show jsx支持v-show,所以这个不用改变
      // v-model,jsx默认不支持,可以引入babel-plugin-jsx-v-model
    
  • 绑定事件

      // 绑定事件 tmpl
      <button @click="testClick">Test Button</button>
      // 绑定事件 jsx
      // on-click和onCLick都可以
      <button on-click={testClick}>Test Button</button>
      <button onClick={testClick}>Test Button</button>
    
  • 绑定原生事件

      // 绑定原生事件 native
      <my-component @click.native="testClick" />
      <my-component nativeOnClick={testClick} />
      // 目前只能用驼峰式,至少我用native-on-click编译不过
    
  • 关于 jsx v-for 的$refs

      // 关于jsx v-for只能获得一个引用对象
      <ul>
          {arr.map(item => <my-componen key={item} ref="my" />)}
      </ul>
      /* 上面这种写法,this.$refs.my获取的只是一个对象,一般是数组最后一项的组件对象,但是实际上,我们要的是ref的数组 */
      /* 如果要获取里面,所有的ref,也就是要获取一个数组的话,必须加上refInFor,看下面,同样的,不能写成ref-in-for */
      <ul>
          {arr.map(item => <my-componen key={item} ref="my" refInFor />)}
      </ul>
      // 当然,如果你有想法,每次循环项的ref都不同的话,也不是不行,看你自己的需求了,模板也可以这么玩
    

看到这个相比你也知道 vue 的 JSX 其实和 react 的 JSX 很像,不过它们还是有点区别

  • react 属性只能用驼峰式,在 vue 你可以使用驼峰式,同时还能使用 kebab-case,事件也是同理,但是某些特定的暂时只能用驼峰式(例如 refInFor 等等)

  • react 的 class 要写成 className,在 vue 直接用 class,写 className 会出错

  • react 的 style 只支持引入对象,vue 除了能引入对象,还能用 html 的写法,简单粗暴

最后丢两个个链接就跑 babel-plugin-transform-vue-jsx
Render Functions & JSX

这是Vue官方给的一些JSX的教程