在Vue 中使用 JSX 语法
在Vue 中使用 JSX 语法
Vue 中构建虚拟DOM可以直接使用渲染函数构建虚拟Dom,正常情况下用render函数的参数createElement方法构建虚拟Dom的语法比较繁琐,更方便的是用更接近于模板的JSX语法。
Vue实例与组件入门
我的vue脚手架是vue cli4,如果在新建项目时安装了babel,则自动安装了编译JSX需要的babel插件
babel.config.js
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset'
]
}
这种情况下,render()支持JSX语法。
Vue中定义模板的几种方法
JSX是什么
JSX(Javascript XML)是React发明的一种JavaScript的语法扩展,允许 HTML 与 JavaScript 的混写;JSX本身也是一个表达式,在编译后,JSX表达式会变成普通的JavaScript对象。
JSX语法不能被浏览器识别,需要Babel 转义成普通的JavaScript对象。
JSX语法规则
1、在JSX中可以在大括号{}里任意使用JavaScript表达式
2、必须包含一个根节点
3、标签必须正确嵌套,标签必须关闭,允许单标签,属性名会自动转为小写
4、注释的写法
注释需要包含在{}里
{/* **** */}
使用JSX构建虚拟Dom
单文件组件的模板
<template>
<div>
<p>Hello {{message}}</p>
</div>
</template>
<script>
export default {
data () {
return { message: 'Vue' }
}
}
</script>
render函数使用JSX构建虚拟Dom
- render函数中this指向当前实例
- render函数的参数createElement,JSX 中要用简写h。
- return的内容就是虚拟dom.使用的语法是JSX语法,它看起来和上例中的模板很像,语法规则中的最重要的一点就是要在大括号{}里使用JavaScript表达式
export default {
data () {
return { message: 'Hello Vue!' }
},
render: function (h) {
return (
<div>
<p>Hello {this.message}</p>
</div>
)
}
}
插值表达式
JSX不支持模板语法中的插值表达式,在JSX直接用{}包裹js表达式
JSX中引用组件
只需要将组件导入,无需在components选项中声明
import MyHeader from './MyHeader'
export default {
render(){
return (
<MyHeader>用户登录</MyHeader>
)
}
}
属性的写法
跟普通的 HTML一样,动态属性要用{}包裹
<div>
<p id="a" class={'b'}>{this.message}</p>
</div>
指令
常见的指令
render(){
return (
<div>
{/* v-model */}
<input vModel={this.newTodoText} />
{/* v-model 以及修饰符 */}
<input vModel_trim={this.newTodoText} />
{/* v-on 监听事件 */}
<input vOn:click={this.newTodoText} />
{/* v-on 监听事件以及修饰符 */}
<input vOn:click_stop_prevent={this.newTodoText} />
{/* v-html */}
<p domPropsInnerHTML={html} />
</div>
)
}
事件绑定
以下方式都可以,在使用不同的babel转义时,写法可能不同
<button vOn:click={this.handleClick}>确定</button>
<button onClick={this.handleClick}>确定</button>
<button on-click={this.handleClick}>确定</button>
插槽
子组件
render () {
return (
<div class="header">
{this.$slots.title}
{this.$slots.default}
</div>
)
}
相当于模板
<template>
<div class="header">
<slot name="title"></slot>
<slot></slot>
</div>
</template>
父组件
render () {
return (
<MyHeader>
<h1 slot="title">具名插槽</h1>
<p>默认插槽的内容</p>
</MyHeader>
)
}
同模板语法一致
循环语句
render () {
return (
<ul>
<li>1.a</li>
<li>2.b</li>
<li>3.c</li>
</ul>
)
}
上面的代码通过循环语句实现:
render () {
const todos = ['a', 'b', 'c']
return (
<ul>
{
todos.map((item,index)=> {
return <li>{index}.{item}</li>
})
}
</ul>
)
}
条件语句
- 三元表达式
render () {
const condition = true
return (
<div>
{
condition
? <span>1</span>
: <span>0</span>
}
</div>
)
}
- if - else
render () {
const condition = true
let content = ''
if (condition) {
content = <span>1</span>
} else {
content = <span>0</span>
}
return (
<div>
{content}
</div>
)
}
函数式组件
vue中的函数式组件也称为无状态组件,只有props选项,典型场景是如果一个组件没有复杂的交互,只用来展示DOM,用函数式组件则即快速又方便。
假设设计一个显示文章内容的函数式组件,其中有两个插槽一个是作者结束,一个是版权信息
- 父组件
<about-article id="1" class="article" style="font-size: 16px" className="article-article" title="标题" content="内容" @read="handleRead">
<div>作者介绍</div>
<p slot="copyright">版权所有</p>
</about-article>
- 子组件(函数式组件)
函数式组件内部没有响应式数据,没有this,但在其render函数的参数中多了一个参数context,提供了很多有用的信息
export default {
functional:true,
render(h,context){
console.log(context)
return (
<div onClick={context.listeners.read}>
{context.children[0]}
<h1>{context.props.title}</h1>
<div>{context.props.content}</div>
{context.slots().copyright}
</div>
)
}
}
context参数
props 提供所有 prop 的对象
在 2.3.0 及以上的版本中,如果不配置 props 选项,所有组件上的 attribute 都会被自动隐式解析为 prop。
如配置props选项,props将只包含配置的属性
props: ['title', 'content']
data 传递给组件的整个数据对象,作为 createElement 的第二个参数传入组件
- 不配置 props 选项
- 配置props 选项
children VNode 子节点的数组
slots 一个函数,返回包含所有插槽的对象
scopedSlots:(2.6.0+) 一个暴露传入的作用域插槽的对象。也以函数形式暴露普通插槽。
parent 对父组件的引用
listeners:(2.3.0+) 一个包含了所有父组件为当前组件注册的事件监听器的对象。这是 data.on 的一个别名。
injections:(2.3.0+) 如果使用了 inject 选项,则该对象包含了应当被注入的 property。
子组件
render (h, context) {
console.log(context)
return (
<div onClick={context.listeners.read}>
{context.children[0]}
<h1>{context.props.title}</h1>
<div>{context.props.content}</div>
{context.slots().copyright}
</div>
)
}
单文件组件可以使用基于模板的函数式组件
<template functional>
</template>
更多推荐
所有评论(0)