使用裝飾器@
裝飾器 用來裝飾類的,可以增強類,在不修改類的内部的源碼的同時,增強它的能力(屬性或方法)
裝飾器使用
@函數名
寫法,對
類
進行裝飾,目前在js中還是提案,使用需要配置相關相容代碼庫。
react腳手架建立的項目預設是不支援裝飾器,需要手動安裝相關子產品和添加配置檔案
💥安裝相關子產品
yarn add -D customize-cra react-app-rewired @babel/plugin-proposal-decorators
💥修改package.json檔案中scripts指令
"scripts": {
"start": "react-app-rewired start",
"build": "react-app-rewired build",
"test": "react-app-rewired test",
"eject": "react-scripts eject"
}
💥在項目根目錄中添加
config-overrides.js
配置檔案
此檔案可以了解為就是
webpack.config.js
的擴充檔案
const { resolve } = require('path')
const { addDecoratorsLegacy, override } = require('customize-cra')
// 增強自定義給webpack添加相關配置
const custom = () => config => {
config.resolve.alias['@'] = resolve('./src')
return config
}
module.exports = override(addDecoratorsLegacy(), custom())
一般加上這個就行:
// 增量配置目前項目中的webpack配置,建議在react18中不要用
// 建議在react18中也不要用裝飾器
// override 方法,如果webpack中有此配置則,覆寫,如果沒有則添加
const { addDecoratorsLegacy, override } = require('customize-cra')
// 追加上一個裝飾器
module.exports = override(addDecoratorsLegacy())
裝飾器的使用
裝飾類
裝飾函數,在裝飾時它沒有寫小括号,target它就是目前你裝飾的類
添加靜态方法/屬性:
不是成員方法
const handle = target =>{
target.run = ()=>{
console.log("run");
}
}
@handle
class Demo {};
const d = new Demo();
Demo.run();
添加成員方法/屬性:
const handle = target =>{
target.prototype.run = ()=>{
console.log("run");
}
}
@handle
class Demo {};
const d = new Demo();
d.run();
裝飾器加上了小括号,則定義函數時一定要傳回一個新函數
const handle = (msg) => target =>{
target.prototype.run = ()=>{
console.log("run",msg);
}
}
@handle("我愛你")
class Demo {};
const d = new Demo();
d.run();
裝飾成員屬性
裝飾器裝飾成員屬性,裝飾時沒有寫小括号
裝飾器裝飾成員屬性,裝飾時沒有寫小括号
target 裝飾的類的執行個體 new Demo this
key 目前的成員屬性名稱 username
description 就是目前屬性在對象中它的描述 Object.defineProperty
const handle = (target, key,) => {
// 設定目前屬性為隻讀屬性
// description.writable = false
console.log(target, key, description)
}
class Demo {
@handle
username = 'abc'
}
高階元件
定義高階元件,用來進行全局布局
1.它就是一個函數
2.參數首字母大寫,因為你傳入的是一個元件,在react中元件的調用必須首字母大寫
3.傳回一個元件
高階元件的使用場景
1, 需要代碼重用時, react如果有多個元件都用到了同一段邏輯, 這時,就可以把共同的邏輯部分提取出來,
利用高階元件的形式将這段邏輯整合到每一個元件中, 進而減少代碼的邏輯重複。
2, 需要元件增強優化時, 比如我們在項目中使用的元件有些不是自己寫的, 而是從網上C下來的,
但是第三方寫的元件可能比較複雜, 有時不能完全滿足需求, 但第三方元件不易修改, 此時也可以用高階元件,
在不修改原始元件的前提下, 對元件添加滿足實際開發需求的功能。
高階元件的實作方式
高階元件的實作方式有兩種:
1, 屬性代理: 通過建立新組建來包裹原始元件, 把原始元件作為新組建的子元件渲染
功能: 可實作對原始元件的 props資料更新 和 元件模闆更新。
下面是實作屬性代理的代碼片段:
(1), 建立高階元件檔案 MyHOC.jsx
function MyHoc(OldCom){
return class NewCom extends React.Component{
render(){
let newProps = { age: 10, sex: '男' }
return (
<OldCom {...newProps} ></OldCom>
)
}
}
}
// 導出高階元件函數
export default MyHOC;
// 屬性代理: 通過建立新組建來包裹原始元件, 把原始元件作為新組建的子元件渲染
// 功能: 可實作對原始元件的 props資料更新 和 元件模闆更
(2), 在檔案中建立函數 函數的參數是一個元件OldCom(參數可以自定義), 函數的傳回值也是一個元件 NewCom(自定義)
反向繼承: 通過建立新組建繼承自原始元件, 把原始元件作為父元件
功能: 可實作對原始元件的state狀态資料更新 和 元件模闆更新。
下面是實作反向繼承的代碼片段:
function MyHOC (OldCom){
return class NewCom extends OldCom{
componentDidMount() {
this.setState({ name: '李四' })
}
render() {
return super.render()
}
}
}
// 導出高階元件函數
export default MyHOC;
// 反向繼承的state資料, 不能在render中改, 會進入死循環
// 一般在生命周期函數或自定義函數中更新state
簡單的樣式修改
一、沒有使用cssModule時,隻能直接導入
import './style.css'
<div className="todo-title">任務清單</div>
注意手動添加辨別符
例如:
.todo-title {
color: red;
}
二、 在react中create-react-app工程,它内置了cssModule功能,但是檔案字尾一定要有
xxx.module.css/scss
如果有scss檔案,必須得安裝
yarn add sass
import styles from './style.module.css'
<div className={styles.title}>任務清單</div>
<span className={done ? style.title : ''}>{title}</span>
通過裝飾器來調用高階元件
完成修飾後類元件導出:
@withLayout
class Child extends Component{
render() {
return ()
}
}
export default Child;
//export default withRouter(Child);