使用vue的渲染函数时给我的感觉就是想在使用原生的js创建虚拟dom类似,很繁琐,
而jsx就类似于原生js中的innerHTML中书写HTML代码
在Vue中使用JSX语法。可以让我们回到更接近模板的语法上。
注意
在jsx中 <> 内输入的是HTML代码 {} 内输入的js代码
插值
<div>{ this.value }</div>
指令
在JSX中,一些指令并不存在,所以我们可以换一种方式来处理。
v-text
<div domPropsTextContent="<p>i am a p</p>"></div>
v-html
<div domPropsInnerHTML="<p>i am a p</p>"></div
v-show
js-x支持v-show指令
<div v-show={this.show}></div>
v-if
<!-- v-if --><script>export default {data(){return {bool:true,}},methods:{vIf(num){if(num == 1){return <h1>1</h1>}else if(num == 2){return <h1>2</h1>}else{return <h1>3</h1>}},},render(){return (<div>v-if 第一种方式{true && <h1>if</h1>}第二种方式{ !this.bool ? <h1>false</h1>:<h1>true</h1> }第三种方式{this.vIf(3)}</div>)}}</script>
v-for
v-for 与 key{this.arr.map(ele => <h1 key={ele}>v-for:{ele}</h1>)}
v-on
<script>import baseDemo from './baseDemo'export default {methods:{handleClick(str,e){console.log(123)console.log(str,e.target)}},components:{baseDemo,},render(){return (<div>事件监听<h1 on-click={this.handleClick}>click</h1>也可使用<h1 onClick={this.handleClick}>click</h1>原生事件监听<h1><base-demo nativeOnClick={this.handleClick}/></h1>事件监听+传递参数<h1 on-click={e => this.handleClick('我是参数',e)}>click传递参数</h1></div>)}}</script>
v-bind
直接书写特姓名<input value={this.value}/>内联样式<div class="a b c d " style="background:blue; width:100px; height:100px;">123456</div>在JSX中可以直接使用class="xx"来指定样式类,内联样式可以直接写成style="xxx"<div class='a'>单个class</div>class<div class={{a:true,b:false,c:true}}>class</div>style<div style={{ color:'red',fontSize:'20px'}}>style</div>
v-model
有相应的插件 支持 v-model,所以可以直接使用:
<input type="text" v-model={this.value} />
Ref
<script>export default {data(){return {arr:[1,2,3,4,5,6,7],}},render(){return (<div><p>Ref--访问子组件实例或子元素</p><input ref="input" value="123456789"/>当为v-for时ref特性应该包括所有循环生成的元素,而不是只有最后一个<ul>{this.arr.map(ele => <li ref="li" key={ele} refInFor={true}>{ele}</li>)}</ul></div>)},mounted(){console.log(this.$refs)console.log(this.$refs.input.value)console.log(this.$refs.li[1].innerText)}}</script>
自定义指令
两种方式
- 写在行间上
- 写成对象
写在行间上
<script>// 写在行间上export default {data(){return {value:'123456'}},directives:{'slice':{bind (el, binding, vnode) {const vm = vnode.context;let { value, expression, arg, modifiers } = binding.value;console.log(binding,'directive-行间书写')if(modifiers.number) {value = value.replace(/[^0-9]/g, '');}el.value = value.slice(0, arg);vm[expression] = value.slice(0, arg);el.oninput = function (e) {let inputVal = el.value;if(modifiers.number) {inputVal = inputVal.replace(/[^0-9]/g, '');}el.value = inputVal.slice(0, arg);vm[expression] = inputVal.slice(0, arg);}},update (el, binding, vnode) {const vm = vnode.context;let { value, arg, expression, modifiers } = binding.value;if(modifiers.number) {value = value.replace(/[^0-9]/g, '');}el.value = value.slice(0, arg);vm[expression] = value.slice(0, arg);},}},// 写在行间上render(){return (<div>写在行间上<input v-slice={{value:this.value,expression:'value',arg:5,modifiers: {number: true},}}/>{this.value}</div>)}}</script>
使用对象的方式
<script>// 自定义对象,使用对象的方式export default {data(){return {value:'123456'}},directives:{'slice':{bind (el, binding, vnode) {const vm = vnode.context;let { value, expression, arg, modifiers } = binding; // 写在行间上此处的数据储存位置不一样console.log(binding,'directive-对象展开')if(modifiers.number) {value = value.replace(/[^0-9]/g, '');}el.value = value.slice(0, arg);vm[expression] = value.slice(0, arg);el.oninput = function (e) {let inputVal = el.value;if(modifiers.number) {inputVal = inputVal.replace(/[^0-9]/g, '');}el.value = inputVal.slice(0, arg);vm[expression] = inputVal.slice(0, arg);}},update (el, binding, vnode) {const vm = vnode.context;let { value, arg, expression, modifiers } = binding;if(modifiers.number) {value = value.replace(/[^0-9]/g, '');}el.value = value.slice(0, arg);vm[expression] = value.slice(0, arg);},}},render(){const directives = [{name:'slice',value:this.value,expression:'value',arg:5,modifiers:{number:true,}}]return (<div>使用对象展开的方式<input {...{directives}}/>{this.value}</div>)}}</script>
过滤器
<!-- 正常使用过滤器 --><div>{{ msg | capitalize }}</div><!-- 在jsx中使用过滤器 --><div>{ this.$options.filters['capitalize'](this.msg)}</div>
示例
<script>// <template>// <div> {{ msg | capitalize }}</div>// </template>export default {data(){return{msg : 'wula'}},filters:{capitalize(value){if(value) return "我过滤器"}},render(){console.log(this,'filter')console.log(this.$options,'filter')return (<div>{this.$options.filters['capitalize'](this.msg)}</div>)}}</script>
插槽
普通书写方式和具名插槽
子组件书写示例
<script>export default {render(){return (<div><header>{this.$slots.header}</header>123546<main>{this.$slots.default}</main></div>)}}</script>
父组件使用插槽
<script>import jsxSlot from './components/jsx-slot'export default {components:{jsxSlot,},render(){return(<div>普通插槽与具名插槽<jsx-slot><i>我是默认插槽</i><strong slot="header">我是头部</strong></jsx-slot></div>)}}</script>
作用域插槽
子组件书写示例
<script>export default {data(){return {msg:"我是作用域插槽的内"}},render(){return (<div>作用域插槽{this.$scopedSlots.default({msg:this.msg,})}</div>)}}</script>
父组件示例
<script>import jsxSlot2 from './components/jsx-slot2'export default {components:{jsxSlot2,},render(){return(<div>作用域插槽<jsx-slot2 {...{scopedSlots:{default:(props) => props.msg}}}></jsx-slot2></div>)}}</script>
jsx利用变量名生成一个元素
示例代码
<script>export default {render(){const tag = "h1";return(<tag></tag>)}}</script>
演示案例
父组件代码
<template><base-demo :level="level"> 标题 </base-demo></template><script>import baseDemo from "./components/baseDemo";export default {name: "App",components: {baseDemo,},data() {return {level: "1",};}}</script>
子组件代码
<script>export default {props:{level:{type:String,required:true,}},render(){const tag = 'h' + this.props.levelreturn(<tag>{this.$slots.default}</tag>)}}</script>
