1、JSX是什么
JSX 是 Facebook 工程团队创造的一个术语。
JSX 是 JavaScript 的类似XML的语法扩展,没有任何定义的语义。
const div = <div>这是一个div盒子</div>
2、绑定变量
在JSX
中绑定变量,跟在template
中绑定变量,不太一样。
render (createElement) {
return ( <button content={this.generatedText}></button> )
}
3、绑定HTML
在JSX
中设置HTML
内容,跟在template
中也不太一样,在JSX中,是通过domPropsInnerHTML
, 在template
中,使用的是v-html
在template中:
<template>
<div v-html="content"></div>
</template>
在JSX
中:
const div = <div domPropsInnerHTML={content}></div>
4、绑定事件
在JSX
中绑定事件,是通过on
前缀来绑定事件,如onClick
事件,原生事件添加nativeOn
const button = <button onClick={this.handleClick}></button>
5、事件修饰符
事件修饰符是通过:
来修饰。
const button = <button onClick:prevent={this.handleClick}></button>
官方推荐:
<input vOn:click_stop_prevent="newTodoText" />
也可以使用快捷键
修饰符 | 前缀 |
---|---|
.passive | & |
.capture | ! |
.once | ~ |
.capture.once 或.once.capture | ~! |
使用方式如下: |
<el-button {...{
'!click': this.doThisInCapturingMode,
'!keyup': this.doThisOnce,
'~!mouseover': this.doThisOnceInCapturingMode
}}>Click Me!</el-button>
6、组件库事件绑定
当使用组件库开发的时候,事件名称如果有on-*
的,可以使用下面的写法。
exrpot default {
render() {
return (
<el-upload {...{
props: {
'on-success': () => {
// 业务逻辑代码...
}
}
}}>上传</el-upload>
)
}
}
7、v-for循环
在JSX
中,使用array.map()来进行循环。
const lis = ```
<div>
<ul>
{
this.data.map(item => {
return <li>{ item.title }</li>
})
}
</ul>
</div>
8、三元运算符
<script>
export default {
data() {
return {
isTrue: true,
};
},
render() {
const msg = this.isTrue ? '你中奖了' : '很遗憾,没中'
return (
<div>
中奖情况:{ msg }
</div>
);
}
};
</script>
9、style 方式
主要在标签上 使用{...{}}
进行绑定
<script>
export default {
data() {
return {
backgroundColor: 'blue',
styleObject: {
backgroundColor: 'red',
fontSize: '20px',
color: '#fff'
}
};
},
render() {
return (
<div>
<span {...{
style: {
backgroundColor: this.backgroundColor
}
}}>我是蓝色背景</span>
<span {...{
style: this.styleObject
}}>我是红色背景</span>
</div>
);
}
};
</script>
10、class 方式
在Vue
中jsx
中可以直接写成class="xx"
。实际上由于class
是JS
的保留字,因此在DOM中其属性名为className
而在HTML
属性中为class
,我们也可以在Vue中这样写:
<div domPropsClassName="mt__xs"></div>
注意 如果同时写了
class="xx" domPropsClassName="yy"
那么后者的优先级较高,和位置无关。所以尽量还是采用class
的写法 主要在标签上 使用{...{}}
进行绑定
<script>
export default {
data() {
return {
isBlue: true,
classOjbect: ['red']
};
},
render() {
return (
<div>
<span {...{
class: {
blue: this.isBlue,
}
}}>我是蓝色背景</span>
<span {...{
class: this.classOjbect
}}>我是红色背景</span>
</div>
);
}
};
</script>
11、directive 指令
对于自定义的指令可以使用v-name={value}
的语法来写,需要注意的是指令的参数、修饰符此种方式并不支持。以官方文档指令部分给出的示例v-focus
使用为例,介绍二种解决办法:
1、直接使用对象传递所有指令属性
<input type="text" v-focus={{value: true}}>
2、使用原始的vnode指令数据格式
{
directives:{
focus: {
inserted: function(el) {
el.focus()
}
}
},
render() {
const directives = [
{ name: 'focus', value: true }
]
return (
<div>
<input type="text" {...{ directives }} />
</div>
)
}
}
11、Attrs 绑定
常用的动态id
、data-*
赋值
<script>
export default {
data() {
return {
};
},
render() {
return (
<div>
<span {...{
attrs: {
'id': 'app',
'data-id': '1234'
}
}}>我是蓝色背景</span>
</div>
);
}
};
</script>
高阶组件
render(h) {
return (<my-button { ...{
props: this.attrs,
attrs: this.$attrs,
} }><my-button>);
}
12、Slots 插槽
<el-table
data={this.tableData}
stripe
>
<el-table-column
prop='shop_name'
label='店铺名称'
>
</el-table-column>
<el-table-column
prop='shop_status'
label='店铺状态'
{...{
scopedSlots: {
default: props => {
// props.row 当前行的数据
return props.row.shop_status ? <el-tag type='success'>启用</el-tag> : <el-tag type='danger'>禁用</el-tag>
}
}
}}
>
</el-table-column>
<el-table-column
prop='shop_create_time'
label='创建时间'>
</el-table-column>
</el-table>
默认插槽模板写法:
<button>
<slot></slot>
</button>
jsx
的写法:
<button>
{this.$scopedSlots.default()}
</button>
具名插槽模板写法:
<button>
<slot name="before"></slot>
<slot ></slot>
</button>
jsx
写法:
let before = '';
if (this.$scopedSlots.before) {
before = this.$scopedSlots.before(props => props.text);
}
return (<button>
{ before }
{this.$scopedSlots.default()}
</button>)
作用域插槽模板写法:
<slot :isAdvancedPanelShow="isAdvancedPanelShow"></slot>
jsx
写法:
{this.$scopedSlots.default({
isAdvancedPanelShow: this.isAdvancedPanelShow
})}
动态组件
还记得官网怎么介绍 createElement
获取js
的完全编程能力吗? 举了一个根据不同的等级使用不同标题的案例:
Vue.component('anchored-heading', {
render: function (createElement) {
return createElement(
'h' + this.level, // 标签名称
this.$slots.default // 子节点数组
)
},
props: {
level: {
type: Number,
required: true
}
}
})
这个案例通过jsx
的写法为:
Vue.component('anchored-heading', {
render: function (h) {
const TagName = 'h' + this.level;
return <TagName>{ this.$slots.default(this.props) }</TagName>
},
props: {
level: {
type: Number,
required: true
}
}
})
13、v-model
<!-- v-model -->
<el-input v-model={this.vm.name} />
要加修饰符:
<el-input vModel_trim={inputValue}/>
// 或者使用
<el-input
value={this.inputValue}
on-input={val => this.inputValue = val.trim()}/>
// 或者使用
<el-input v-model_trim={inputValue}/>
14、空标签
在React
中,可以使用空标签来渲染DOM,在jSX
中,不能直接使用<>空标签。
15、data写法
jsx本质上是createElement
的语法糖,最终会被编译器转为createElement
函数.当在jsx
的标签中使用{ ...obj }
时, obj将会编译为createElement
的第二个参数.
vue
的createElement跟react的createElement函数第二个参数意义是不一样的.在vue
中,第二个参数是 data对象, 而react
第二个参数是props
。所以本人将这种方式称为data写法
。
data中的参数:
render: h => h(CountTo, {
// 'class': 'count-to', // 给组件最外层盒子添加class类名
// 或者这样写
// 'class': ['count-to', true ? 'count-to2' : ''],
// 或者这样写
'class': {
'count-to': true,
'count-to2': 1 === 1,
},
attrs: {}, // 定义属性id等等
style: {}, // 定义样式
props: { // 添加属性 这里可以理解为就是<count-to :endValue="100"/>
endValue: 100
},
// domProps: { // dom的一些属性
// innerHTML: '11' // 可以设置标签的一些内容
// },
on: { // 添加事件
'on-animation-end': (val) => { // 事件名
console.log(val)
}
},
nativeOn: { // 组件内没有定义click事件时,给组件最外层元素绑定一个click事件
'click': () => {
console.log('click')
}
},
directives: [], // 可以定义自定义指令
scopedSlots: {},
slot: '', // 插槽
key: '', // 设置一个值让每个组件的key不相等
ref: '' // ref
})
如在vue
中需要设置动态属性时:
const props={
name: 'joyer',
},
<my-button {...{
props:props,
}}></my-button>
如官方推荐原生dom
属性的jsx
写法:
<button domPropsType="submit"><button>
采用data
写法为:
<button { ...{
domProps: {
type: 'submit',
},
}}><button>