eact開發者的核心理念認為前端應該組件化,組件應該與關注點分離而不是與模板和展現邏輯分離。傳統的前端組件化其思路都是基于模板技術,如Ext、jQuery UI等,結構化標記和生成結構化標記的代碼是緊密關聯的。此外,展現邏輯一般都很復雜,使用模板語言會使展現變得笨重。React解決這個問題的方式就是直接通過JavaScript代碼生成HTML和組件樹,這樣,就可以使用JavaScript豐富的表達力去構建UI。但滿屏的React.createElement出現的時候,代碼的可讀性、可維護性會變得極差。為了使這個過程變得更簡單,React創建了類似XML的語法去構建虛擬DOM樹,即JSX。
JSX即JavaScript XML,它使用XML標記的方式來創建虛擬DOM和聲明組件。前面所舉的例子,從本質上已經能完成所有的工作了。只是有一些開發效率問題,比如JavaScript代碼與標簽混寫在一起、缺乏模板支持等。而使用JSX,則可以有效地解決這些問題。JSX的實質是使用一種更為“自然”的方式來創建ReactElement,它具有以下優點:可以使用熟悉的語法仿照HTML來定義虛擬DOM;JavaScript語義增強,提供更加語義化的標簽支持復雜應用創建;程序代碼更加直觀;抽象ReactElement創建過程;支持變量嵌入和一些模板特性;便于代碼模塊化;與JavaScript之間存在等價轉換。以Helloworld為例,使用JSX語法描述如下:
從上面的代碼可以看出,JSX具有更簡潔、更強大的表現力,而且基本不需要學習就能上手。需要說明的是,JSX是基于ECMAScript的一種新特性,但并不是一種新語言,它只是定義帶屬性的虛擬DOM樹的一種語法,具體運行時,還需要通過轉譯器將JSX轉換為原生JavaScript代碼再執行。
React框架推薦使用的DOM語法格式為JSX語法,屬于一種JavaScript擴展,React使用JSX來描述用戶界面。我們可以粗略的認為JSX是JavaScript和HTML的結合,但是在實際的使用過程中還有一定的細節區別。本文就帶領大家系統的學習JSX語法的格式。
const element=<div>你好,React!</div>;
這里需要注意,上述代碼不是JavaScript字符串,所以沒有用任何引號引住;也不是HTML代碼。而是JSX語法格式。
React應用的最小單位是“元素”,JSX語法格式就是React推薦用來聲明元素的。
對于相互嵌套的JSX元素,JSX語法推薦使用()擴住。
const ulElement=(
<ul>
<li>第一名</li>
<li>第二名</li>
</ul>
)
使用()擴住嵌套的JSX元素,讓格式更加清晰。從實際的操作來看,不書寫()也是可以的。
在JSX元素中使用變量必須使用{}擴住,變量可以用于JSX元素的內容中,也可以用于JSX元素的HTML屬性取值上。
let name='張三';
const strongElement=<strong>你好,{name}</strong>
let url='https://www.baidu.com';
const link=<a href={url}>百度一下</a>
對于具有return返回值的函數,JSX元素可以像使用變量一樣,利用{}擴住對函數進行調用。
function getSum(a,b){
return a+b;
}
let a=10,b=20;
const sum=<div>{a}+{b}={getSum(a,b)}</div>
上述幾種情況中舉的案例元素(element、ulEelement、strongElement、link、sum)都可以直接用在ReactDOM。render()方法的第一個參數中,充當向第二個參數所指的DOM節點中放入的元素。以sum為例,代碼如下所示。
ReactDOM.render(
sum,
document.querySelector('#app')
);
JSX元素在書寫時還要注意下列語法規定:
請大家仔細閱讀下列代碼:
const element=(
/*一個完整的JSX元素:本注釋沒有在任何標記內部,所以不用{}擴住*/
<div> {/*唯一的根節點:本注釋在標記內部,必須用{}擴住*/}
<div className="top"> {/*className屬性的使用*/}
{/*style屬性的使用必須是雙大括號*/}
<div style={{width:'1200px',height:'40px',backgroundColor:'#3385ff'}}>
歡迎學習React框架。
<img src=”images/01.jpg” /> {/*標記必須有結尾標識*/}
</div>
</div>
</div>
);
ReactDOM.render(
element,
document.querySelector('#app')
);
上述代碼在瀏覽器中運行,可以從開發人員工具的Elements選項卡中看到下列如圖所示的結構。
從圖中可以看得出,id屬性取值為app的div和class屬性取值為top的div之間,有一個空的div。這是由于為了滿足JSX元素必須具備一個唯一的根節點,而設置的最外層的div標記對。為了不讓最外層的根節點顯示在DOM結構中,React建議使用React.Fragment作為所有JSX元素最外層的根節點。代碼改為如下格式。
const element=(
/*一個完整的JSX元素:本注釋沒有在任何標記內部,所以不用{}擴住*/
<React.Fragment> {/*唯一的根節點:本注釋在標記內部,必須用{}擴住*/}
<div className="top"> {/*className屬性的使用*/}
{/*style屬性的使用必須是雙大括號*/}
<div style={{width:'1200px',height:'40px',backgroundColor:'#3385ff'}}>
歡迎學習React框架。
<img src=”images/01.jpg” /> {/*標記必須有結尾標識*/}
</div>
</div>
</ React.Fragment >
);
這時再看開發人員工具的Elements選項卡,React.Fragment標記位置是沒有任何標記對的。
在JSX格式中遍歷數組不能使用for循環,只能使用ES5為數組提供的各種方法。下面的例子展示了用數組的map()方法來遍歷數組的功能實現。
例1:實現頁面導航條的JSX格式。
let navText=['首頁','產品展示','技術展望','視頻會議','金牌團隊','關于我們'];
let navLink=['index.html','product.html','technology.html','videol.html','team.html','about.html'];
const nav=(
<React.Fragment>
<div className="top">
<div className="topContent">
<ul>
{
navText.map((item,index)=>{
return <li key={index}><a href={navLink[index]}>{item}</a></li>
})
}
</ul>
</div>
</div>
</React.Fragment>
);
從上述代碼中可以看出下列有關JavaScript語言在JSX語法中的規范:
例2:有一個JSON數組,每個元素有兩個屬性:isShow和file。其中isShow取值為邏輯值,file取值為表示圖片路徑的字符串。當isShow取值為true時,file指定的圖片要顯示在頁面中;當isShow取值為false時,file指定的圖片不顯示在頁面中。
let picture=[
{isShow:true,file:'images/01.jpg'},
{isShow:true,file:'images/02.jpg'},
{isShow:false,file:'images/03.jpg'},
{isShow:true,file:'images/04.jpg'},
{isShow:true,file:'images/05.jpg'}
];
const img=(
<React.Fragment>
<h2>圖片欣賞</h2>
<div className="picture">
{
picture.filter((item,index)=>{
return item.isShow
}).map((item,index)=>{
return <img src={item.file} key={index} />
})
}
</div>
</React.Fragment>
);
上述代碼中,使用數組的filter()方法對picture數組進行篩選,篩選條件是isShow取值為true。然后再對篩選出來的數組元素使用map()方法進行遍歷,以用來在頁面中顯示圖片。
在JSX格式中是不能直接使用JavaScript的if語句的,我們通過下列五種方式來為大家講解可行的方法。
例:設置一個變量flag。規定當flag=true時,頁面中顯示一個類名為box的div標記;當flag=false時,頁面中顯示一個類名為fox的div標記。
JavaScript提供的三元運算符(? :)也被稱為“三目運算符”。該運算符適合分為兩種情況的分支判定。
let flag=true;
const element=(
<React.Fragment>
{
flag?
<div className="box">
我是box元素......
</div>
:
<div className="fox">
我是fox元素
</div>
}
</React.Fragment>
);
JavaScript提供的邏輯與運算符(&&)的短路原理規定:當&&運算的左側為false時,右側不予計算。該運算符適合多分支的判定。
let flag=true;
const element=(
<React.Fragment>
{flag && <div className="box">
我是box元素......
</div>}
{!flag && <div className="fox">
我是fox元素
</div>}
</React.Fragment>
);
上述代碼中,因為flag變量的取值為true,所以!flag的取值為false,則!flag &&右側的元素不再計算,也就不會被渲染出來。
既然JSX格式不允許直接使用if語句,那我們就不在JSX格式中使用。我們可以在JSX格式以外的區域使用if語句。
let flag=false;
let target;
if(flag){
target=(
<div className="box">
我是box元素......
</div>
)
}else{
target=(
<div className="fox">
我是fox元素
</div>
)
}
const element=(
<React.Fragment>
{target}
</React.Fragment>
);
上述代碼中定義了一個名為target的變量,通過在JSX格式以外進行if語句的判定,讓target變量獲得不同的JSX元素,最終在React.Fragment標記對中使用{target}引用了判定后的結果。
我們也可以在JSX格式以外的區域聲明一個函數,在函數體總使用if語句進行判定,并最終將需要渲染的JSX格式利用return語句返回。
let flag=true;
function getTarget(){
if(flag){
return (
<div className="box">
我是box元素......
</div>
)
}else{
return (
<div className="fox">
我是fox元素
</div>
)
}
}
const element=(
<React.Fragment>
{getTarget()}
</React.Fragment>
);
上述代碼中定義了一個名為getTarget的函數,該函數內部使用if判定flag變量的值,然后利用return語句將需要的JSX元素返回出去。在React.Fragment標記對中只需要使用{getTarget()}調用該函數即可。
本文是React系列教程的第二篇文章,主要為大家講解了React框架中JSX語法的書寫格式。系統的學會了JSX語法的書寫格式,對于編寫復雜的React項目有很大的幫助。明天會為大家系統的講解React組件的使用方法。
小海前端,具有18年Web項目開發和前后臺培訓經驗,在前端領域著有較為系統的培訓教材,對Vue.js、微信小程序開發、uniApp、React等全棧開發領域都有較為深的造詣。入住?,希望能夠更多的結識Web開發領域的同仁,將Web開發大力的進行普及。同時也愿意與大家進行深入的技術研討和商業合作。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>jsx</title>
<style>
.title{
background-color: orange:
width: 200px;
}
</style><!--定義個樣式,也可以寫在CSS文件里,引入進來-->
</head>
<body>
<div id="test"></div>
<script type="text/javascript" src="../js/react.development.js"></script>
<script type="text/javascript" src="../js/react-dom.development.js"></script>
<script type="text/javascript" src="../js/babel.min.js"></script>
</body>
<script type="text/babel">
const myid="lOVE you"
const mydata="hellO jsx"
const VDOM=( // <!--h2標簽引入樣式,用className,span標簽引入內聯樣式的時候,不是用雙引號,而是雙花括號,-->
<div>
<h2 className="title" id={myid.toLowerCase()}>
<span style={{color:'red',fontSize:'29px'}}>{mydata.toLowerCase()}</span>
</h2>)// <!--標簽中混入JS表達式時要用花括號{},如這里mydata取值 -->
//jsx中只能有一個根標簽,比如這里的h2,可以在h2的外面包一層div,就可以寫兩個h2
<h2 className="title" id={myid.toUpperCase()}>
<span style={{color:'red',fontSize:'29px'}}>{mydata.toLowerCase()}</span>
</h2>)
//標簽首字母若是小寫字母,則將該標簽轉為html中同名元素,若html中無該標簽對應的同名元素,則報錯
//標簽首字母若是大寫字母,react就去渲染對應的組件,若組件沒有定義,則報錯
</div>
ReactDOM.render(VDOM,document.getElementById('test'))
</script>
</html>
<script type="text/babel">
const data=['A','B','C']
const VDOM=(
<div> //js表達式會產生一個值。js語句(代碼),有if,for,switch判斷,
<h1>jsx框架</h1>
<ul>
{
data.map((item,index)=>{
return <li key={index}>{item}</li>
}) //item拿到data里面對應的值,map遍歷的第二個值是索引值,
}
</ul>
</div>
)
ReactDOM.render(VDOM,document.getElementById('test'))
</script>
對應的網頁如下:
模塊是向外提供特定功能的js程序,一般就是一個js文件。
組件比模塊更高一級,比如實現一個網頁的頭部的html,字體,css,js,圖像這些元素組合在一起,就形成了頭部這個組件。
函數式組件:
<script type="text/babel">
function MyComponent(){
return <h2>show the function component</h2>
}
ReactDOM.render(<MyComponent/>,document.getElementById('test'))
//<MyComponent/>要寫上標簽,函數定義首字母需要大寫
</script>
執行了ReactDOM.render(<MyComponent/>。。之后,React解析組件標簽,找到MyComponent組件,發現組件是使用函數定義的,隨后調用該函數,將返回的虛擬DOM轉為真是DOM,隨后呈現在頁面中。
類式組件:
*請認真填寫需求信息,我們會在24小時內與您取得聯系。