Vue 是使用的的模板语法,Vue的模板实际上就是编译成了 render 函数,同样支持 JSX 语法。在 Vue 官网中,提供 createElement 函数中使用模板中的功能。

createElement 方法

createElement(
  'anchored-heading', {
    props: {
      level: 1
    }
  }, [
    createElement('span', 'Hello'),
    ' world!'
  ]
)


渲染成下面这样
<anchored-heading :level="1">
  <span>Hello</span> world!
</anchored-heading>

使用 JSX 语法

Babal plugin 插件,用于在 Vue 中使用 JSX 语法,它可以让我们回到更接近于模板的语法上。

1、安装依赖

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

2、配置 .babelrc 文件

module.exports = {
  plugins: ['transform-vue-jsx']
}

3.该插件会编译 JSX 语法:

<div id="foo">{this.text}</div>
// 插件将上述编译 JSX 编译成下述 JS:
h('div', {
  attrs: {
    id: 'foo'
  }
}, [this.text])

h 函数就是 Vue 实例 $createElement 方法的简写,必须在JSX 所在的范围内。由于此方法作为第一个参数传递给组件渲染函数,因此在大多数情况下,你可以这样做:

Vue.component('jsx-example', {
  render (h) { // <-- h must be in scope
    return <div id="foo">bar</div>
  }
})

h 自动注入

从 3.4.0 版本开始,我们会自动注入 const h = this.$createElement ES2015 语法中声明的具有 JSX 的任何方法和 getter(不是函数或箭头函数),因此你可以删除 h 参数。

Vue.component('jsx-example', {
  render () { // h will be injected
    return <div id="foo">bar</div>
  },
  myMethod: function () { // h will not be injected
    return <div id="foo">bar</div>
  },
  someOtherMethod: () => { // h will not be injected
    return <div id="foo">bar</div>
  }
})

@Component
class App extends Vue {
  get computed () { // h will be injected
    return <div id="foo">bar</div>
  }
}

与 React JSX 的区别

Vue 2.0 的 vnode 格式与 React 的不同的是:createEelement 调用的第二个参数是‘数据对象’,它接受嵌套的对象。每个嵌套对象将由相应的模块处理:

render (h) {
  return h('div', {
    // Component props
    props: {
      msg: 'hi',
      onCustomEvent: this.customEventHandler
    },
    // 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'
  })
}

Vue 2.0 JSX 中与上述等效:

render (h) {
  return (
    <div
      // normal attributes or prefix with on props.
      id="foo"
      propsOnCustomEvent={this.customEventHandler}
      // 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>
  )
}

组件引入

如果自定义元素以小写字母开头,则它将被视为字符串 ID,并用于查找已注册的组件。如果以大写开头,则将其视为标识符,你可以执行以下操作:

import Todo from './Todo.js'

export default {
  render (h) {
    return <Todo/> // no need to register Todo via components option
  }
}

JSX 扩展运算符

支持 JSX 扩展,此插件将智能地合并嵌套的数据数据。例如:

const data = {
  class: ['b', 'c']
}
const vnode = <div class="a" {...data}/>
// 合并之后的 data
{ class: ['a', 'b', 'c'] }

Vue 指令

使用 JSX 时,几乎不支持所有内置的 Vue 指令,唯一例外的是 v-show,可以与 v-show={show} 语法一起使用。在大多数情况下,存在明显的,例如 v-if 用三元表达式,并且 v-for 是用 array.map() 表达式等。对于自定义指令,可以使用 v-name={value} 语法。但是使用此语法不支持指令参数和修饰符,有两种解决方案:

1.将所有内容作为对象通过传递 value,例如 v-name={{ value, modifier: true }}

2.使用原始 vnode 指令数据格式:

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

JSX 语法使用 v-model

1.安装依赖

npm i babel-plugin-js-v-model -D

2..babelrc 文件中添加配置

module.exports = {
  plugins: ['jsx-v-model']
}

 

Logo

前往低代码交流专区

更多推荐