模块与组件,模块化与组件化的理解
模块
理解:向外提供特殊功能的JS程序,一般就是一个js文件;
为什么要拆成模块:随着业务逻辑的增多,代码越来越多且复杂;
作用:复用js,简化js的编写,提高js运行效率。
组件
理解:用来实现局部功能效果的代码和资源的集合;
为什么:一个界面的功能更复杂;
作用:复用代码,简化项目编码,提高运行效率;
模块化
当应用的js都已模块来编写的,这个应用就是一个模块化的应用
组件化
当应用是以多组件的方式实现,这个应用就是一个组件化的应用
定义函数式组件和类式组件
函数式组件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>函数定义的组件</title>
</head>
<body>
<!---准备好一个容器-->
<div id="test">
</div>
<!---引入核心库,必须最先引入-->
<script src="../js//react.development.js"></script>
<!---引入react-dom,用于支持react操作dom,其次引入-->
<script src="../js/react-dom.development.js"></script>
<!---引入babel,用于将jsx转化为js,最后引入-->
<script src="../js/babel.min.js"></script>
<script type="text/babel">
//1.创建函数式组件
function Mycomponent() {
console.log(this) // 此处的this是undefine,因为babel编译后开启了严格模式
return <h2>我是用函数定义的组件(适用于【简单】组件的定义)</h2>
}
//2.渲染组件到页面
ReactDOM.render(<Mycomponent />, document.getElementById('test'))
</script>
</body>
</html>
执行了ReactDOM.render(Mycomponent />, document.getElementById('test'))之后,发生了什
么?
1.react解析组件标签,找到了Mycomponent函数组件,如果找不到,则报错
2.发现组件是使用函数定义的,随后调用该函数,将返回的虚拟dom转为真实dom,随后呈现在页
面中
定义类组件
定义类式组件,要求自己的类必须继承react中的类(React.component),该类是react内置的
创建类组件必须要满足的三点:
1.必须继承react当中的类(React.component)
2.必须写render() {}
3.render函数中必须写返回值
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>类式组件</title>
</head>
<body>
<!---准备好一个容器-->
<div id="test">
</div>
<!---引入核心库,必须最先引入-->
<script src="../js//react.development.js"></script>
<!---引入react-dom,用于支持react操作dom,其次引入-->
<script src="../js/react-dom.development.js"></script>
<!---引入babel,用于将jsx转化为js,最后引入-->
<script src="../js/babel.min.js"></script>
<script type="text/babel">
//1.创建类式组件(类名就是组件名)
//react如果定义类式组件,要求自己的类必须继承react中的类(React.component),该类是react内置的
/*
创建类式组件必须要满足的三点
1.必须继承react当中的类(React.component)
2.必须写render() {}
3.render函数中必须写返回值
*/
class Mycomponent extends React.Component{
render() {
// render函数放在了哪里?--放在了myComponent的原型对象上,供实例使用
// render中的this是谁?----myComponent的实例对象,也是myComponent组件实例对象
console.log('render中的this是:',this)
return <h2>我是用类定义的组件(适用于【复杂】组件的定义)</h2>
}
}
//2.渲染组件
ReactDOM.render(<Mycomponent />, document.getElementById('test'))
</script>
</body>
</html>
执行了ReactDOM.render(Mycomponent />, document.getElementById('test'))之后,发生了什
么?
1.react解析组件标签,找到了myComponent函数组件,如果找不到,则报错
2.发现组件是使用类定义的,随后new出来该类实的例,并通过该实调例用到原型上的render方法
3.将render返回的虚拟dom转为真实dom,随后呈现在页面中
复习类的基础知识
类的定义及使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>类的基本知识</title>
</head>
<body>
<script>
// 创建一个person类,class是定义类的关键字
class Person {
// 构造器方法
constructor(name, age){ // 该函数主要是接收new实例对象传递的参数
// 构造器中的this是谁?-----是类的实例对象
console.log('@@@',this);
this.name = name
this.age = age
}
// 一般方法
speak() {
console.log('speak',this);
// speak方法放在了哪里?---类的原型对象上,供实例使用
// 通过Person实例调用speak()时,speak中的this就是Person实例
console.log(`我叫${this.name},我年龄是${this.age}`)
}
}
// 创建一个person实例
const p1 = new Person('tom', 18)
const p2 = new Person('jerry',19)
console.log(p1)
console.log(p2)
p1.speak()
p2.speak()
</script>
</body>
</html>
类的继承
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>继承</title>
</head>
<body>
<script>
// 创建一个person类,class是定义类的关键字
class Person {
// 构造器方法
constructor(name, age){ // 函数主要是接收new实例对象传递的参数
// 构造器中的this是谁?-----是类的实例对象
this.name = name
this.age = age
}
// 一般方法
speak() {
// speak方法放在了哪里?---类的原型对象上,供实例使用
// 通过Person实例调用speak()时,speak中的this就是Person实例
console.log(`我叫${this.name},我年龄是${this.name}`)
}
}
// 创建一个student类,继承与person类
class Student extends Person {
constructor(name, age, grade) {
super(name,age) // 把接收到的相同信息发给父类,调用父类的构造器方法
this.grade = grade
}
// 重写重父类继承过来的方法
speak() {
console.log(`我叫${this.name},我年龄是${this.name},我年龄是${this.grade}年级`)
}
study() {
//study方法放在了哪里?---类的原型对象上,供实例使用
// 通过Student实例调用study中的this就是Student实例
console.log('我很努力的学习')
}
}
const s1 = new Student('toy', 18, '高三')
console.log(s1)
s1.speak()
s1.study()
</script>
</body>
</html>
总结:
1.类中的构造器不是必须写的,要对实例进行一些初始化的操作,如添加指定属性时才写
2.如果A类继承了B类,且A类中写了构造器,那么A类构造器中的super是必须要调用的,且要写在
新 增属性的 最前面
3.类中所定义的方法,都是放在了类的原型对象上,供实例去使用