vue中的JSX和函数式组件

上一篇我们讲解了vue中使用 render 函数创建HTML,在创建过程比较复杂,而且模板中的 DOM 结构可读性差。那么这一篇我们主要了解JSX和函数组件

JSX

JSX全称是JavaScript XML,是一种JavaScript语法扩展,用于描述用户界面。其格式比较像是模板语言,但事实上完全是在JavaScript内部实现的。

JSX语法用于简化模板的编写,使得模板的编写变得和普通 DOM 模板一样简单。在 Vue.js中,想要使用 JSX 语法就必须下载 Babel 插件

将如下 DOM 结构:

<div>
   <span>hello,vue</span>
</div>

采用普通 render 函数实现:

createElement(
  'div', [
    createElement('span', 'Hello,vue')
  ]
)

采用 JSX 语法的 render 函数实现:

new Vue({
  el: '#demo',
  render() {
    return (
      <div>
        <span>Hello,vue</span> 
      </div >
    )
  }
})

函数式组件

vue中的函数式组件也称为无状态组件,其内部没有任何状态。函数式组件中只接受一个props参数,没有其他参数。

声明函数式组件有两种方式,如下所示:

<template functional>
	{{data}}
<template>

//声明为函数式组件
Vue.component('my-component', {
  functional: true, 
  // Props 是可选的
  props: {
    // ...
  }, render: function (createElement, context) {
    // ...
  }
})

声明函数式组件必须使用functional关键字,函数式组件的特点是,无状态——函数式组件本身是没有状态的,也就是没有响应式数据;无实例——函数式组件没有实例,也就是没有this上下文

render的参数中有一个context,这个用于函数式的参数传递,它是一个对象,包含如下对象:

  1. props:提供所有 prop 的对象
  2. children:VNode 子节点的数组
  3. slots:一个函数,返回了包含所有插槽的对象
  4. scopedSlots:(2.6.0+) 一个暴露传入的作用域插槽的对象。也以函数形式暴露普通插槽。
  5. data:传递给组件的整个数据对象,作为 createElement 的第二个参数传入组件
  6. parent:对父组件的引用
  7. listeners:(2.3.0+) 一个包含了所有父组件为当前组件注册的事件监听器的对象。这是 data.on 的一个别名。
  8. injections:(2.3.0+) 如果使用了 inject 选项,则该对象包含了应当被注入的 property。

函数式组件说到底,也是组件的一种声明方式,属于 render 函数的一种,只不过函数式组件渲染的开销很低,且函数式组件只是一个函数,这种组件声明过程中,只有 props 选项可用,其他选项就算声明了也无法使用。

函数式组件的传递属性和事件

在上面我们提到,函数式组件只有一个 props 选项,在普通方式声明组件时,非props 属性会自动添加到根元素。而函数式组件不行,函数式组件会自动将非 props 属性转化为 prop 属性。除此之外, context对象的 data 选项中包含所有的非prop 属性和所有的事件监听器,其中属性存放在 attrs 对象中,所有的事件监听器存放在 on 对象中。context对象的 children 选项中包含所有的子节点 。

通过具体实例了解一下,下列实例是完整的函数式组件实例:

 <div id="app">
        <h1>hello,vue</h1>
        <post-item @click="h1_click" :text="111">
            组件
        </post-item>
    </div>
    <script>
        Vue.component('PostItem', {
            functional: true,
            props: ['text'],
            render(createElement, context) {
                return createElement("button", context.props.text, context.children)
            },
        })
        let vm = new Vue({
            el: "#app",
            methods: {
                h1_click() {
                    console.log("点击事件");
                }
            },
        })
    </script>

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值