前言:
Vue中的组件开发:
1.全局组件和局部组件
2.函数组件和类组件(vue3不具备functional函数组件)
React中的组件化开发:
没有明确全局和局部的概念,可以理解为都是局部组件,不过可以把组件注册到React上,这样每个组件只要导入React中即可使用
1.函数组件
2.类组件
3.hooks组件:在函数组件中使用React Hooks函数
1.函数组件
创建:在src目录中,创建一个xxx.jsx的文件,即创建一个组件,在组件中创建一个函数,让函数返回JSX视图(jSX元素/virtualDOM虚拟DOM对象)。
调用:基于ES6Moudle规范,导入创建的组件,可以省去.jsx后缀,然后调用组件一样的方式使用,单标签或双标签都可以,双标签可以放置子节点,后续能被props接收。
import DemoFun from "@/views/demo";
// 基于render方法渲染编写的视图,把渲染后的内容全被插入到#root中进行渲染
const root = ReactDOM.createRoot(document.getElementById("root"));
//调用组件的时候,可以给调用的组件设置传递各种属性,非字符串格式则使用大胡子语法
root.render(<><DemoFun /><DemoFun title="demo" data={[100,200]} className="demo"> </DemoFun></>
);
渲染机制:
- 基于babel-preset-react-app把调用的组件转换为createElement格式
React.createElement(DemoFun,{
title: "demo",
data: [100, 200],
className: "demo",
children: " "
}
//可以把标签丢进babel官网看看~
2)把createElement方法执行,创建出一个virtualDOM对象
3)基于root.render把虚拟dom变成了真实的dom
当type是一个函数的时候,会执行函数 DemoFun,把virtualDOM中的props,作为实参传递给函数->DemoFun(props),接收函数执行的返回结果即当前组件的JSX视图,最后基于render把组件返回的虚拟DOM转为真实DOM,插入到#root容器中~
形参props在子组件中的使用细节
- 调用组件,传递的属性是只读的,原理使用Object.isFrozen(props)冻结了
获取传递的参数值:通过点语法: props.xxx;
直接修改则报错,一定要修改则可以先声明一个新的变量进行赋值后,修改新的变量的结果
作用:父组件调用子组件的时候,可以基于属性,把信息传给子组件,子属性接收相应的属性值,呈现不同的效果,让组件的复用性更强~
2.直接修改是不行的,但是可以添加一些校验规则~
1)设置默认值:
2) 设置其他规则校验,是否必传、数据格式等。。。可使用prop-types插件
a)安装
b)引入:import PropTypes from "prop-types"
c)使用:
import PropTypes from "prop-types";
const DemoFun = (props) => {console.log(props,'props')return <div className="demo">I am demoone</div>;
};
DemoFun.defaultProps={x:0,title:'没有设置标题'
}
DemoFun.propTypes={title:PropTypes.string.isRequired,x:PropTypes.number
}
export default DemoFun;
常用的校验规则:
optionalArray: PropTypes.array,
optionalBool: PropTypes.bool,
optionalFunc: PropTypes.func,
optionalNumber: PropTypes.number,
optionalObject: PropTypes.object,
optionalString: PropTypes.string,
optionalSymbol: PropTypes.symbol,
官网
https://www.npmjs.com/package/prop-types
知识点补充:关于对象的规则设置
1)冻结:no修改、no新增、no删除、no劫持(Object.defineProperty)
冻结对象:Object.freeze(obj)
检测:Object.isFrozen(obj)
2) 密封:可改,no新增,no删除,no劫持
密封对象:Object.seal(obj)
检测:Object.isSealed(obj)
3) 不可拓展:only no新增,其余都可以处理
设为不可拓展对象:Object.preventExtensions(obj)
检测:Object.isExtensible(obj)