day01—JSX创建虚拟DOM元素

react是什么?

特点:虚拟DOM配合diff算法,最大限度地减少与DOM的交互。

react初体验

BootCDN网站(react.development文件 & react-dom.development文件)

//Step1:引入 react 的 核心文件
//目的是:在全局window添加了一个react属性,React属性是一个对象,React.xxx
<script src="./js/react.development.js"></script>

//Step2:引入 react操作页面元素DOM 的 核心文件
//引入react-dom,这个文件是为了后期可以操作页面的元素,这依赖于全局的React属性
//所以必须要先引入react.development.js这个文件,使其在全局产生一个react的属性
<script src="./js/react-dom.development.js"></script>

//Step3:创建一个 容器元素
<div id="root"></div>

//Step4:利用js来完成页面内容的渲染
<script>
	//Step5:创建一个  根标签容器 元素对象(通过 ReactDOM 来创建挂载的 根容器)
	const root = ReactDOM.createRoot(document.querySelector('#root'));
	
	//容器元素对象的原型属性之中有一个render方法
	//后期,借助于axios,向服务端、数据库请求数据,然后渲染到页面上
	//Step6:在容器元素中进行渲染
	root.render("Fighting Evelyn!");
</script>

打印root
【注意事项】:
1、root.render可写多次,但最后一次render会将之前的覆盖掉(类似于给对象的属性多次赋值);
2、不要同时挂载相同的容器;(同一个容器元素 ×)
3、在一个页面中,可以挂载多个不同的容器;(创建多个挂载的根容器,分别渲染)
4、render可以渲染的内容类型有:
(1)可以接收的数据类型:String、Number、Array、虚拟DOM元素;
(2)可以接收不会报错,但是不会有内容渲染的数据类型:Null、Undefined、Boolean;
(3)无法接收的类型:对象、函数(目前阶段,不包括后期函数作为组件使用)
【注】布尔值虽然不能直接将值渲染出来,但是可以作为条件判断,render中可以接收三元表达式,null数据类型和undefined数据类型同理。除了true之外 ,像undefined、null、false都为假,但是,undefined===undefined(null和false同理)这些为真。
【注】render中渲染对象一定会报错,故可以将对象转换成一个JSON字符串,root.render(JSON.stringfy ( { a : 1 , b : 2 } ) )

render渲染对象报错

5、不建议将根容器指定为body元素或者html元素;(document.body / document.documentElement)
render渲染body报错

render渲染html报错

6、render是容器元素对象(root)的原型对象身上的方法;

7、render方法是将虚拟DOM元素对象转换为真实DOM元素对象;

虚拟DOM元素对象

之前提到,render渲染可以是普通数据类型,如何渲染标签?通过虚拟DOM元素!
虚拟DOM元素是轻量级的,真实DOM是重量级的,虚拟DOM最终都会通过React转为真实DOM进行渲染,React操作的都是虚拟DOM。(虚拟DOM对象中属性比较少,真实DOM中属性特别多)
创建真实DOM元素对象:document.createElement(’ 标签名 ‘)
创建虚拟DOM元素对象:
方式一:React.creatElement(’ 标签名 ')(了解)
方式二:JSX(JavaScript xml)(重点)

创建虚拟DOM元素对象

方式一——React.createElement

React . createElement( ’ 标签名 ’ , { 属性名1:属性值1 ,属性名2:属性值2} , 值 )

【注】如果产生的虚拟元素对象,没有添加属性,则第二个参数可以直接设置为空对象{}或者是null;
【注】属性可以是内置属性,也可以是自定义属性;
【注】如果添加的属性是固有属性中的class,需要写成className;

//引入react.development.js文件
//引入react-dom.development.js文件
const root = ReactDOM.createRoot(document.querySelector('#root'));

//需求1:h1元素中包含span,span中包含两个并列的a标签
//如果创建的标签中嵌套其他子标签时:
let vDOM = React.createElement('h1', {}, React.createElement('span', null, React.createElement('a', { href: 'http://baidu.com' }, 'Evelyn'), React.createElement('a', { href: 'http://mi.com' }, '去小米')));
root.render(vDOM);

//需求2:在div元素中添加四个span虚拟元素对象
//当包含多个元素时,第三个参数可以设置为数组,此时需要添加唯一的key属性,key是一个唯一的标识属性
//key值可以是数值,也可以是字符串,只要每一个虚拟元素对象中的key值不一样就行
let span1 = React.createElement('span', { key: 1, className: 'span1' }, 'span1');
let span2 = React.createElement('span', { key: 2, className: 'span2' }, 'span2');
let span3 = React.createElement('span', { key: 3, className: 'span3' }, 'span3');
let vDOM = React.createElement('div', { id: 'box' }, [span1, span2, span3]);

方式二——JSX语法

1、jsx是react.createElement()的语法糖(简化)
2、JSX语法必须要有一个唯一绝对的根标签元素
3、目前位置当jsx语法换行书写仍然可以渲染,因为在浏览器端使用的时候还没有明确的组件结构定义,所以语法相对宽泛,但是到了后期使用组件渲染jsx的时候,如果标签换行则必须添加()否则无法渲染内容;
4、当JSX语法中出现了平行的多个元素的时候,语法要求必须有一个绝对的根标签,这样就会造成空div的元素的浪费,可以尝试将h1和p两个结构直接渲染到rootdiv节点上
5、<React.Fragment></React.Fragment>
6、JSX语法中如果想要添加注释,需要在其内部写{} 注释写在{}之内,单行注释和多行注释均可;
7、JSX语法遍历,只能使用map(注意有return),不能使用for循环或者forEach方法!
8、map函数中的return,如果要换行,要加括号,但是保证return后面有内容;
9、JSX语法遍历,每一项都需要加唯一键值key

jsx语法规则

//Step1:引入核心文件
//Step2:引入react操作DOM元素的核心文件
//Step3:引入babel转化文件
//Step4:创建容器元素
<div id="root"></div>
//Step5:设置脚本类型
<script type="text/babel"></script>
//Step6:创建容器元素对象
const root = ReactDOM.createRoot(document.querySelector('#root'))
//Step7:渲染


//要让内容直接挂载到root身上
{Fragment} = React;
const vDOM = <Fragment>
	<div>
		<span></span>
	</div>
	</Fragment>

插值表达式

插值表达式:只能放8表达式不能放语句
表达式:一个表达式会产生一个值(变量名 a+b fun(10) arr.map() 函数结构function()=>{}
语句:不会产生结果,只是控制程序的流程走向(if…else for循环 arr.forEach() switch…case)

插值表达式中:
(1)会渲染:String、Number、Array、虚拟DOM元素对象、js表达式
(2)不会渲染也不报错:undefined,null,true,false
(3)会报错:对象、js语句

条件渲染

一、方式一——if…else

const root = ReactDOM.createRoot(document.querySelector('#root'));
let isLogin = false;
let vDOM;
if (isLogin) {
 	vDOM = <h2>登录成功!</h2>
} else {
 vDOM = <div>
     <button>登录</button>
     <button>注册</button>
 </div>
}
root.render(vDOM)

方式二——三元运算符

const vDOM = isLogin ? <h2>登录成功!</h2> : <div>
            <button>登录</button>
            <button>注册</button>
        </div>

方式三——逻辑短路

逻辑短路更适合于单一条件的结果输出,只要条件满足则输出,否则不渲染

逻辑短路:
逻辑与短路:
当所有值都为真值的时候,返回的是最后一个值 ;
当逻辑与短路中出现假值,则返回第一个出现的假值;
逻辑或短路:
当逻辑或短路中出现假值,则返回第一个出现的真值

//如果登录过就显示,未登录状态什么都不显示
let vDOM = isLogin && <h2>恭喜您,登录成功</h2>;
root.render(vDOM)

属性渲染&样式渲染

行内样式:(通过添加style属性)
给虚拟元素对象添加一般属性,可以直接使用{},不需要加双引号;
给虚拟元素对象添加style属性,<元素名 style={{属性名:属性值;属性名:属性值;}}></元素名>
【注】样式属性名中如果带有"-"则需要转化成小驼峰写法
(background- border- margin- box- font- line-)
【注】当属性值单位为px的时候,且值为number类型,可以省略单位,直接写成数值,如果带单位要使用双引号括起来。

类样式:(通过加类名)
<元素名 className=“属性名”></元素名>

【注】:在后期实际开发的时候,当如果标签中的样式值会发生变化的时候,则需要写成行内样式,方便带入变量,否则如果样式只是为了简单渲染显示没有数值的变化,则可以考虑非行内样式className。

列表渲染——使用map方法遍历数组

const courses = [{ id: 1, name: 'React' }, { id: 3, name: 'Vue' }, { id: 5, name: '小程序' }];
const vDOM = <React.Fragment>
	<h3>课程列表</h3>
	<ul>
    	{
       	 	courses.map(item => {
            return (
                <li key={item.id}>{item.name}</li>
            	)
        	})
    	}
	</ul>
</React.Fragment>

React核心语法——事件

在JSX中,所有的虚拟元素对象身上添加的事件名都是小驼峰写法
事件名常用名称:onClick、onMouseOver、onMouseLeave、onMouseOut…
当如果函数体中业务逻辑代码偏多,我们一般会选择单独在外部声明函数,在插值表达式里面进行调用;
所有的事件类型中插值表达式接收的一定是函数体结构!!!

function fun(){}

//以下内容均在const vDOM = <React.Fragment></React.Fragment>中:(为了加注释方便)

//普通函数事件,不加参数————方式一:
<button onClick={function () {console.log('普通的函数事件1')}}>普通函数事件1</button>
//普通函数事件,不加参数————方式二:
function fun() {
    console.log('普通的函数事件2')
}

//普通函数事件,加参数————方式一:
function fun(x){
	return function(){
		console.log(x)
	}
}
<button onClick={fun(10)}>普通函数带参数调用</button>

//普通函数事件,加参数————方式二:
function fun(x){
	console.log(x);
}
<button onClick={function () { fun(10) }}>普通函数带参数调用</button>


//带有事件对象的函数,无参数
function fun(event) {
    console.log(event)
    console.log(event.target);
    console.log('fun3....')
}
<button onClick={fun}>不带参数的函数使用事件对象</button>


//带有事件对象的函数,有参数
//fun中的三个形式参数和调用函数的三个实际参数一一对应
function fun(a, b, c) {
//返回的才是真正的事件函数  btn.onclick = function(){}
	return function (ev) {
 		console.log(ev)
 		console.log(a)
 		console.log(b)
 		console.log(c)
 		console.log('fun4....')
	}
}
<button onClick={fun(10, 20, 30)}>带参数的函数使用事件对象</button>

function fun5(a, b, c, d) {
    console.log(a);//事件对象参数
    console.log(b, c, d);
}
<button onClick={function (ev) { fun5(ev, 10, 20, 30) }}>带参数的函数使用事件对象</button>
//事件函数必须是一个函数结构,可以直接写,也可以通过函数调用返回值是一个函数结构
//当如果函数调用的时候没有加(),则函数的第一个形式参数就是事件对象(事件函数的第一个参数就是事件对象参数)

在这里插入图片描述

案例——列表

**const vDOM = <div class="hot-news">
            <h2>头条热榜</h2>
            <hr />
            <ul>
                {
                    data.map(item => {
                        return (
                            <li key={item.id}>
                                <span className={`order index-${item.id}`}>{item.id}</span>
                                <span className={"title"}>{item.title}</span>
                                {item.is_hot && <span className={"hot"}></span>}
                            </li>
                        )
                    })

                }
            </ul>
       </div>**

非受控

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值