Material-UI
使用模組為React設計版面
2019/07/21
React + Material-UI(Tables)
這次接續使用上一章的範例 (教學: React - Rest Example),我們直接使用rest讀取的資料來建立一個table,示範如何用Material-UI的「Tables 」模組將資料顯示在頁面上。Material Design是Google開發的設計語言,Material-UI就是一些Material Design的react模組/元件。
事前準備
- index.js
修改掛載頁面為<PersonList />
- PersonList.js
讀取API資料複製到 state ( persons )
*添加 console.log()
函數可以在頁面後台看到從接受API接收到的data內容。
- Browser ( localhost:3000 )
打開瀏覽器查看頁面結果
*右邊為Chrome的開發人員工具,在console標籤可以看到我們剛才log的data內容。
範例上方的按鍵打開可以看見範例代碼:
import React from 'react';
import { makeStyles } from '@material-ui/core/styles';
import Table from '@material-ui/core/Table';
import TableBody from '@material-ui/core/TableBody';
import TableCell from '@material-ui/core/TableCell';
import TableHead from '@material-ui/core/TableHead';
import TableRow from '@material-ui/core/TableRow';
import Paper from '@material-ui/core/Paper';
const useStyles = makeStyles(theme => ({
root: {
width: '100%',
marginTop: theme.spacing(3),
overflowX: 'auto',
},
table: {
minWidth: 650,
},
}));
function createData(name, calories, fat, carbs, protein) {
return { name, calories, fat, carbs, protein };
}
const rows = [
createData('Frozen yoghurt', 159, 6.0, 24, 4.0),
createData('Ice cream sandwich', 237, 9.0, 37, 4.3),
createData('Eclair', 262, 16.0, 24, 6.0),
createData('Cupcake', 305, 3.7, 67, 4.3),
createData('Gingerbread', 356, 16.0, 49, 3.9),
];
function SimpleTable() {
const classes = useStyles();
return (
<Paper className={classes.root}>
<Table className={classes.table}>
<TableHead>
<TableRow>
<TableCell>Dessert (100g serving)</TableCell>
<TableCell align="right">Calories</TableCell>
<TableCell align="right">Fat (g)</TableCell>
<TableCell align="right">Carbs (g)</TableCell>
<TableCell align="right">Protein (g)</TableCell>
</TableRow>
</TableHead>
<TableBody>
{rows.map(row => (
<TableRow key={row.name}>
<TableCell component="th" scope="row">
{row.name}
</TableCell>
<TableCell align="right">{row.calories}</TableCell>
<TableCell align="right">{row.fat}</TableCell>
<TableCell align="right">{row.carbs}</TableCell>
<TableCell align="right">{row.protein}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</Paper>
);
}
export default SimpleTable;
import
最上面的部分import所需使用的模組
import React from 'react';
import { makeStyles } from '@material-ui/core/styles';
import Table from '@material-ui/core/Table';
import TableBody from '@material-ui/core/TableBody';
import TableCell from '@material-ui/core/TableCell';
import TableHead from '@material-ui/core/TableHead';
import TableRow from '@material-ui/core/TableRow';
import Paper from '@material-ui/core/Paper';
makeStyles()
Material-UI用來定義頁面樣式的hook函式。
const useStyles = makeStyles(theme => ({
root: {
width: '100%',
marginTop: theme.spacing(3),
overflowX: 'auto',
},
table: {
minWidth: 650,
},
}));
React 特別之處就在於它可以全部使用JavaScript去撰寫網頁,包含html、CSS 跟 Script(雖然這部分本來就是用JS寫的啦哈哈哈)的部分,我們可以統一使用JS定義完成。這種使用JS定義CSS的方法稱為——「 CSS in JS 」(JSS)
當然我們也可以透過import CSS檔,用傳統的方式撰寫網頁樣式,但如果使用了Material-UI,還是建議使用JSS的方式定義樣式,即便要將所有樣式集中到同一個檔案裡管理,也還是可以使用JSS的方式定義樣式。
另外,JSS要特別注意的地方是,由於JS用Object的概念定義樣式,所以有些地方的格式跟CSS不太一樣:
- 樣式名稱不用 ' - ' 符號連結而是駝峰式命名。例:
overflowX: 'auto'
,原本在CSS中是over-flow
的寫法,這裡把連結符號刪掉,第二個單字的第一個字母大寫,變成overFlow
- 樣式的內容為需為變數或字串。例:
width: '100%'
,原本在CSS 100%的數值需要加上' ' 或 " "(JS中兩著皆可);如數值不加單位例:minWidth: 650
,預設單位則為 px,即 min-width 等於 650px。 - 樣式換行結尾使用 ' , '符號。與一般CSS用分號不同,JSS用的是逗號。
createData()
創建文件資料。這部分不會使用於此次範例中。
function createData(name, calories, fat, carbs, protein) {
return { name, calories, fat, carbs, protein };
}
const rows = [
createData('Frozen yoghurt', 159, 6.0, 24, 4.0),
createData('Ice cream sandwich', 237, 9.0, 37, 4.3),
createData('Eclair', 262, 16.0, 24, 6.0),
createData('Cupcake', 305, 3.7, 67, 4.3),
createData('Gingerbread', 356, 16.0, 49, 3.9),
];
Function Component(SimpleTable())
輸出組件頁面與嵌入資料陣列。
function SimpleTable() {
const classes = useStyles();
return (
<Paper className={classes.root}>
<Table className={classes.table}>
<TableHead>
<TableRow>
<TableCell>Dessert (100g serving)</TableCell>
<TableCell align="right">Calories</TableCell>
<TableCell align="right">Fat (g)</TableCell>
<TableCell align="right">Carbs (g)</TableCell>
<TableCell align="right">Protein (g)</TableCell>
</TableRow>
</TableHead>
<TableBody>
{rows.map(row => (
<TableRow key={row.name}>
<TableCell component="th" scope="row">
{row.name}
</TableCell>
<TableCell align="right">{row.calories}</TableCell>
<TableCell align="right">{row.fat}</TableCell>
<TableCell align="right">{row.carbs}</TableCell>
<TableCell align="right">{row.protein}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</Paper>
);
}
export default SimpleTable;
加入Material-UI改寫範例檔案:
export default function PersonList() {
/*------------ STATE ------------*/
const [persons, setPersons] = useState([]);
/*------------ STYLE ------------*/
const classes = useStyles();
/*=========== Create Table HEAD ===========*/
const personList = [ 'id', 'name', 'phone', 'username' ]
useEffect(() => {
async function fetchData() {
const result = await axios.get(`https://jsonplaceholder.typicode.com/users/`);
setPersons(result.data);
console.log(result.data)
}
fetchData();
}, []);
return (
<Paper className={classes.root}>
<Table className={classes.table}>
{/*===== TableHead =====*/}
<TableHead>
<TableRow>
{
personList.map( (list, i) => i === 0 ?
<TableCell key={i} align="center"> {list} </TableCell> :
<TableCell key={i} align="right"> {list} </TableCell>
)
}
</TableRow>
</TableHead>
{/*===== TableBody =====*/}
<TableBody>
{persons.map(person => (
<TableRow key={person.name}>
{
personList.map( (list, i) => i === 0 ?
<TableCell key={i} component="th" scope="row" align="center" >
{person[list]}
</TableCell>:
<TableCell key={i} align="right">{person[list]}</TableCell>
)
}
</TableRow>
))}
</TableBody>
</Table>
</Paper>
)
}
改寫後完成頁面:
**感謝伍庭儀同學提供本頁面內容