详解利用jsx写vue组件的方法示例


Posted in Javascript onJuly 17, 2017

前言

本文主要给大家介绍的是关于利用jsx写vue组件,下面话不多说,来一起看看详细的介绍吧。

我们平常写vue的组件时,一般都是用的是模版,这种方式看起来比较简洁,而且vue作者也推荐使用这个方式,但是这种方式也有一些它的弊端,例如模版调试麻烦,或者在一些场景下模版描述可能没那么简单和方便。

下面我们要讲的是如何在vue里面写jsx,知道react的人应该都知道jsx,jsx的一个特性就是非常灵活,虽然有的人觉得jsx很丑陋,把逻辑都写到模版的感觉,但萝卜青菜各有所爱,适合自己适合团队的就是最好的。

在使用jsx之前我们需要安装一个babel插件(babel-plugin-transform-vue-jsx )

安装方式:

npm install\
 babel-plugin-syntax-jsx\
 babel-plugin-transform-vue-jsx\
 babel-helper-vue-jsx-merge-props\
 babel-preset-es2015\
 --save-dev

然后再.babelrc里面添加:

{
 "presets": ["es2015"],
 "plugins": ["transform-vue-jsx"]
}

接着我们就可以愉快地在vue里面编写jsx了。

Test.vue

<script>
export default {
 props: ['onClick', 'isShow'],
 
 data() {
  return {
   test: 123
  };
 },
 
 render() {
  return (
   <div class="test" onClick={ this.onClick }>
    { this.test }
    { this.isShow + '' }
   </div>
  );
 }
}
</script>

可以看到我们把jsx写在了render方法里面,render方法是vue2.0才支持的,用来提供对虚拟DOM的支持,也就是说只有vue2.0才支持jsx语法转换。

这里要注意的一点是vue里面编写jsx和在react里面的jsx语法还是有一点不一样的。

以下是一段覆盖大部分语法的vue jsx代码:

render (h) {
 return (
 <div
  // normal attributes or component props.
  id="foo"
  // DOM properties are prefixed with `domProps`
  domPropsInnerHTML="bar"
  // event listeners are prefixed with `on` or `nativeOn`
  onClick={this.clickHandler}
  nativeOnClick={this.nativeClickHandler}
  // other special top-level properties
  class={{ foo: true, bar: false }}
  style={{ color: 'red', fontSize: '14px' }}
  key="key"
  ref="ref"
  // assign the `ref` is used on elements/components with v-for
  refInFor
  slot="slot">
 </div>
 )
}

可以看到DOM属性要加domProps前缀,但这里lass和style却不需要,因为这两个是特殊的模块,而且react的class用的是className,vue却用的class。事件监听是以“on”或者“nativeOn”为开始。

实际上vue2.0的模版最后都会被编译为render方法,所以模版声明的组件和jsx声明的组件最后都是一样的。

上面的jsx最后会被编译成下面这样:

render (h) {
 return h('div', {
 // Component props
 props: {
  msg: 'hi'
 },
 // normal HTML attributes
 attrs: {
  id: 'foo'
 },
 // DOM props
 domProps: {
  innerHTML: 'bar'
 },
 // Event handlers are nested under "on", though
 // modifiers such as in v-on:keyup.enter are not
 // supported. You'll have to manually check the
 // keyCode in the handler instead.
 on: {
  click: this.clickHandler
 },
 // For components only. Allows you to listen to
 // native events, rather than events emitted from
 // the component using vm.$emit.
 nativeOn: {
  click: this.nativeClickHandler
 },
 // class is a special module, same API as `v-bind:class`
 class: {
  foo: true,
  bar: false
 },
 // style is also same as `v-bind:style`
 style: {
  color: 'red',
  fontSize: '14px'
 },
 // other special top-level properties
 key: 'key',
 ref: 'ref',
 // assign the `ref` is used on elements/components with v-for
 refInFor: true,
 slot: 'slot'
 })
}

这也意味着两种形式的组件是可以相互引用的。

有时候我们难免会在模版里引入jsx编写的vue组件或者在jsx编写的vue组件里引入模版组件,这里还是有些需要注意的事项:

1.在模版里面引入jsx的组件,可以通过components引用,另外props的编写从驼峰式改为连接符:

<template>
 <div class="wrapper">
 <Test :on-click="clickHandler" :is-show="show"></Test>
 </div>
</template>
 
<script>
import Test from './Test.vue';
 
export default {
 name: 'hello',
 components: {
 Test
 },
 data() {
 return {
  msg: 'Welcome to Your Vue.js App',
  show: true
 };
 },
 methods: {
 clickHandler(){
  this.show = !this.show;
 }
 }
};
</script>

2.在jsx里面引入vue模版组件,这里没有什么要注意的,除了连接符式的属性要转换成驼峰式,还有一个需要注意的是指令,如果用了jsx,那么内置的指令都不会生效(除了v-show),好在内置指令大部分都可以用jsx描述。那么自定义指令要怎么用呢?

自定义指令可以使用“v-name={value} ”语法,如果要支持指令参数和modifier可以用“v-name={{ value, modifier: true }} ”语法:

<script>
import Vue from 'vue';
 
Vue.directive('my-bold', {
 inserted: function (el) {
 el.style.fontWeight = 900;
 }
})
 
export default {
 props: ['onClick', 'isShow'],
 
 data() {
  return {
   test: 123
  };
 },
 
 methods: {
  afterLeave() {
   console.log('afterLeave')
  }
 },
 
 render() {
  const directives = [
   { name: 'my-bold', value: 666, modifiers: { abc: true } }
  ];
 
  return (
   <transition onAfterLeave={this.afterLeave} name="fade">
    <div class="test" onClick={this.onClick} v-show={ this.isShow } v-my-bold>
     {this.test}
     {this.isShow + ''}
    </div>
   </transition>
  );
 }
}
</script>
<style>
.fade-enter-active, .fade-leave-active {
 transition: opacity .5s
}
.fade-enter, .fade-leave-to {
 opacity: 0
}
</style>

我们还可以用原生vnode的数据格式使用自定义指令:

const directives = [
 { name: 'my-dir', value: 123, modifiers: { abc: true } }
]
 
return <div {...{ directives }}/>

扩展

如果有人觉得在vue组件里面要写data,props,computed和methods不够优雅,可以参考下这个插件vue-class-component,它能让你使用ES6的class和ES7的装饰器编写vue组件。

相关链接:

babel-plugin-transform-vue-jsx

总结

以上就是这篇文章的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
jQuery模拟超链接点击效果代码
Apr 21 Javascript
利用ajaxfileupload插件实现文件上传无刷新的具体方法
Jun 08 Javascript
javascript通过navigator.userAgent识别各种浏览器
Oct 25 Javascript
jQuery实现tab标签自动切换的方法
Feb 28 Javascript
javascript的变量、传值、传址、参数之间关系
Jul 26 Javascript
JQuery实现的按钮倒计时效果
Dec 23 Javascript
JS读取XML文件数据并以table形式显示数据的方法(兼容IE与火狐)
Jun 02 Javascript
AngularJS Select(选择框)使用详解
Jan 18 Javascript
详解如何在React组件“外”使用父组件的Props
Jan 12 Javascript
jquery3和layui冲突导致使用layui.layer.full弹出全屏iframe窗口时高度152px问题
May 12 jQuery
微信小程序搜索框样式并实现跳转到搜索页面(小程序搜索功能)
Mar 10 Javascript
vue scroll滚动判断的实现(是否滚动到底部、滚动方向、滚动节流、获取滚动区域dom元素)
Jun 11 Javascript
Javascript实现找不同色块的游戏
Jul 17 #Javascript
Vue.js 单页面多路由区域操作的实例详解
Jul 17 #Javascript
Vue项目webpack打包部署到服务器的实例详解
Jul 17 #Javascript
JS中Safari浏览器中的Date
Jul 17 #Javascript
Vue.extend构造器的详解
Jul 17 #Javascript
原生js实现密码输入框值的显示隐藏
Jul 17 #Javascript
extjs简介_动力节点Java学院整理
Jul 17 #Javascript
You might like
提升PHP执行速度全攻略
2006/10/09 PHP
php通过隐藏表单控件获取到前两个页面的url
2014/09/09 PHP
PHP实现随机生成水印图片功能
2017/03/22 PHP
php中钩子(hook)的原理与简单应用demo示例
2019/09/03 PHP
JS获取鼠标坐标的实例方法
2013/07/18 Javascript
javascript使用定时函数实现跳转到某个页面
2013/12/25 Javascript
button没写type=button会导致点击时提交
2014/03/06 Javascript
jQuery移除元素自动解绑事件实现思路及代码
2014/05/31 Javascript
js使用html()或text()方法获取设置p标签的显示的值
2014/08/01 Javascript
用Jquery选择器计算table中的某一列某一行的合计
2014/08/13 Javascript
JS中setTimeout的巧妙用法前端函数节流
2016/03/24 Javascript
微信小程序 icon组件详细及实例代码
2016/10/25 Javascript
javascript中BOM基础知识总结
2017/02/14 Javascript
js解决软键盘遮挡输入框的问题分享
2017/12/19 Javascript
零基础之Node.js搭建API服务器的详解
2019/03/08 Javascript
微信小程序自定义组件传值 页面和组件相互传数据操作示例
2019/05/05 Javascript
vue轻量级框架无法获取到vue对象解决方法
2019/05/12 Javascript
ES6常用小技巧总结【去重、交换、合并、反转、迭代、计算等】
2019/12/21 Javascript
Node.js API详解之 assert模块用法实例分析
2020/05/26 Javascript
使用python实现tcp自动重连
2017/07/02 Python
Python根据当前日期取去年同星期日期
2019/04/14 Python
django使用haystack调用Elasticsearch实现索引搜索
2019/07/24 Python
opencv python图像梯度实例详解
2020/02/04 Python
python函数定义和调用过程详解
2020/02/09 Python
python exit出错原因整理
2020/08/31 Python
CSS3使用border-radius属性制作圆角
2014/12/22 HTML / CSS
匡威帆布鞋美国官网:Converse美国
2016/08/22 全球购物
八年级物理教学反思
2014/01/19 职场文书
应用化学专业职业生涯规划书
2014/01/22 职场文书
生日礼品店创业计划书范文
2014/03/21 职场文书
幼儿教师师德演讲稿
2014/05/06 职场文书
电气工程及其自动化专业毕业生自荐信
2014/06/21 职场文书
国王的演讲观后感
2015/06/03 职场文书
新闻稿格式范文
2015/07/18 职场文书
MySQL安装后默认自带数据库的作用详解
2021/04/27 MySQL
如何通过一篇文章了解Python中的生成器
2022/04/02 Python