Author:ManStruggling
什么是 JSX?
JSX是一种JavaScript和XML的联合,即JavaScript + XML = JSX,JSX源于Facebook,能够在JavaScript里写XML,因为这个个性,所以具备了JavaScript的灵活性,同时又兼具html的语义化和直观性
为什么应用 JSX?
- jsx比照createElement函数可读性更强;<div></div> VS this.$createElement('div', {...}, [...])
- vue-cli3.0及以上默认反对jsx语法
- jsx能够使vue组件更容易导入和治理
首先来横向比照一下<template></template>模板语法、createElement函数、jsx三种渲染形式
栗子一
template模板语法
应用最多,不做解释
<div id="vnode"> 一些文本 <p class="bar" style="color: red; font-weight: bold;">Only you can stop forest fires</p> <span>span text</span> <b>b tag</b></div>
createElement
createElement函数实际上创立的是Virtual Node,创立VNode树,一旦Dom树的结构复杂,dom节点属性太多,势必会造成可读性差的问题。。。
render(h) { return h( "div", { attrs: { id: "vnode", }, }, [ "一些文本", h( "p", { class: { bar: true, }, style: { color: "red", fontWeight: "bold", }, }, "Only you can stop forest fires" ), h("span", {}, "span text"), h("b", { domProps: { innerText: "b tag" } }), ] ); }
JSX
而后jsx就闪亮退场
render() { return ( <div id="vnode"> 一些文本 <p class="bar" style="color: red; font-weight: bold;"> Only you can stop forest fires </p> <span>span text</span> <b>b tag</b> </div> ); }
可能有的同学感觉,就这,跟template没什么区别呀。
这个案例只波及到html没有波及javascript,jsx是把javascript和html放在一起来书写的。所以看下个栗子
栗子二
依据type的值进行条件渲染,A、B、C三个模块,每个模块有本人的对应模块的代码,也有一些公共的模块,假如这些代码有很多行,势必会造成浏览性的升高。有人可能感觉如果这样的话,把公共代码抽离出一个独自的组件不就好了,这样使能够解决问题,如果这里的公共代码仅仅只在这一个文件内应用,别的文件不会对这些公共代码做援用呢,要不要思考抽离公共组件的必要性呢,jsx就能够完满的解决这些问题。
template
,在template
<div> <!-- 模块A --> <div class="module-a" v-if="type === 0"> <div> ...模块A的代码 </div> <div> ...公共代码 </div> </div> <!-- 模块B --> <div class="module-b" v-else-if="type === 1"> <div> ...模块B的代码 </div> <div> ...公共代码 </div> </div> <!-- 模块C --> <div class="module-c" v-else> <div> ...模块C的代码 </div> <div> ...公共代码 </div> </div> </div>
createElement
这里就不做createElement函数的阐明了,想必也没有多少人用这个吧。。。。有的话,那你赢了
JSX
template模板代码超过三百行,就很难浏览了,会反复在VM、V层切换,所以在简单的大型项目中倡议用jsx来做render,进步代码的可浏览性
render() { // 提取公共模块代码 const renderCommon = () => <div>...公共代码</div>; const renderA = () => ( <div class="module-a"> <div>...模块A的代码</div> {renderCommon()} </div> ); const renderB = () => ( <div class="module-b"> <div>...模块B的代码</div> {renderCommon()} </div> ); const renderC = () => ( <div class="module-c"> <div>...模块C的代码</div> {renderCommon()} </div> ); return ( <div> {this.type === 0 ? renderA() : this.type === 1 ? renderB() : renderC()} </div> ); }
Usage
<script>export default { render() { // 条件渲染 const vIfRender = () => { let show = false; return ( <div id={"test"} class={{ "test-wrapper": true }} style={{ fontWeight: "bold" }} > {show ? <div>display</div> : "hidden"} </div> ); }; // v-html渲染 const vHtmlRender = () => <div domPropsInnerHTML={`<i>i text</i>`}></div>; const listRencer = () => ( <ol> {[1, 2, 3, 4, 5].map((item) => ( <li>{item}</li> ))} </ol> ); // 事件绑定 const handleParentClick = () => { console.log("trigger parent click"); }; const handleClick = (e) => { e.stopPropagation(); console.log("trigger click"); }; const eventBindingRender = () => ( <div onClick={handleParentClick}> parent text <button domPropsInnerHTML={"点一下试试"} onClick={handleClick}></button> </div> ); // 属性绑定 const inputAttrs = { type: "number", placeholder: "请输出数字", }; const attrBindingRender = () => <input {...{ attrs: inputAttrs }} />; // 指令 const directiveBindingRender = () => ( <button {...{ directives: [ { name: "permission", value: 666, modifiers: { foo: true }, }, ], }} > 权限治理 </button> ); return ( <div> { // v-if 三目运算符 vIfRender() } { // v-html vHtmlRender() } { // 列表渲染 listRencer() } { // 事件绑定 eventBindingRender() } { // 属性绑定 attrBindingRender() } { // 指令 directiveBindingRender() } </div> ); },};</script>
插槽和作用域插槽
// child.vue<script>export default { props: { config: { type: Object, required: true } }, render() { return ( <div> <h3>{this.config.text}</h3> {this.$scopedSlots.content({ data: this.config.childConfig })} </div> ) }}</script>
<script>import Child from "./child";export default { render() { const config = { text: "parent text jsx", childConfig: { test: "children text jsx", }, }; return ( <div> <Child config={config} {...{ scopedSlots: { content: ({data}) => { return <div>{data.test}</div>; }, }, }} ></Child> </div> ); },};</script>
组件间接引入应用,无需components注册,不便导入和治理
上述总结应用jsx的一些非凡状况,条件渲染、v-html、列表的渲染、事件的绑定、属性绑定、指令的应用、插槽和作用域插槽,聪慧的你必定能够看进去,应用jsx能像vue3的composition API一样把雷同的逻辑代码聚合在一起,防止大型项目开发时,页面逻辑简单导致代码量回升,option API在template和methods之间来回切换的问题。
第一次撰文,如有疑难,欢送各位大佬斧正,心愿大家可能STAR反对一下小编,心愿小编的内容对大家有所帮忙~
[TOC]