Layui 학습 노트 (주요 컴포넌트 사용법)
1. 그리드 시스템
주로 페이지 레이아웃을 구성하는 데 사용되며, 페이지를 12등분으로 나눕니다. div의 클래스 규칙을 통해 레이아웃을 구성할 수 있습니다.
기본 사용법
<div class="layui-row">
<div class="layui-col-xs6">
<div class="grid-demo grid-demo-bg1">6/12</div>
</div>
<div class="layui-col-xs6">
<div class="grid-demo">6/12</div>
</div>
</div>
간격 설정
"열 간격" 사전 클래스를 통해 열 간의 간격을 설정합니다. 한 행에서 가장 왼쪽 열은 왼쪽 여백이, 가장 오른쪽 열은 오른쪽 여백이 나타나지 않습니다. 열 간격은 배치 미학을 보장하는 동시에 분열 너비의 세밀함을 더욱 보장할 수 있습니다. 웹사이트에서 일반적으로 사용되는 여백과 결합하여 12가지 다른 크기의 여백을 사전 설정했습니다: layui-col-space1 ~ layui-col-space32
<div class="layui-row layui-col-space1">
<div class="layui-col-md3">
<div class="grid-demo grid-demo-bg1">1/4</div>
</div>
<div class="layui-col-md3">
<div class="grid-demo">1/4</div>
</div>
<div class="layui-col-md3">
<div class="grid-demo grid-demo-bg1">1/4</div>
</div>
<div class="layui-col-md3">
<div class="grid-demo">1/4</div>
</div>
</div>
2. 레이아웃
레이아웃은 주로 웹사이트나 시스템의 관리자 영역 빠른 레이아웃에 사용됩니다.
코드 예시
<div class="layui-layout-admin">
<div class="layui-header" style="background: #2F40F7">
헤더
</div>
<div class="layui-side" style="background: #1E9FFF"></div>
<div class="layui-body" style="background: #F5F7FA">
콘텐츠
</div>
<div class="layui-footer" style="background: #393D49">
푸터
</div>
</div>
모든 레이아웃 div는 layui-layout-admin 내에 있습니다.
layui-header == 헤더 layui-side == 사이드바 layui-body == 콘텐츠 layui-footer == 푸터
3. 폼
div 템플릿 스타일
<form class="layui-form">
<div class="layui-form-item">
<label class="layui-form-label">사용자명</label>
<div class="layui-input-block">
<input type="text" name="username" value="" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">비밀번호</label>
<div class="layui-input-block">
<input type="password" name="password" value="" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button type="submit" class="layui-btn layui-bg-blue">로그인</button>
</div>
</div>
</form>
- class="layui-form"으로 폼 영역을 정의하며, 일반적으로 form 태그나 div 태그에 설정합니다.
- class="layui-form-item"으로 블록 수준 요소의 폼 항목 컨테이너를 정의합니다.
- class="layui-form-label"으로 레이블을 정의합니다.
- class="layui-input-block"으로 블록 수준 요소인 폼 항목 부모 컨테이너를 정의합니다.
- class="layui-input-inline" 또는 class="layui-inline"으로 인라인 블록 요소인 폼 항목 부모 컨테이너를 정의합니다.
폼 데이터 처리
<form class="layui-form" lay-filter="user-form">
<div class="layui-form-item">
<label class="layui-form-label">사용자명</label>
<div class="layui-input-block">
<input type="text" name="username" value="" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">비밀번호</label>
<div class="layui-input-block">
<input type="password" name="password" value="" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button type="submit" class="layui-btn layui-bg-blue" lay-submit lay-filter="submit-login">로그인</button>
</div>
</div>
</form>
<button type="button" lay-on="fetchFormData">폼 데이터 가져오기</button>
<script>
layui.use(function(){
var form = layui.form;
var util = layui.util;
// 폼 내부 버튼 클릭 시 데이터 처리
form.on('submit(submit-login)', function(obj){
var formData = obj.field;
console.log(formData);
return false;
});
// 폼 외부에서 데이터 가져오기
util.on({
fetchFormData: function(){
var data = form.val('user-form');
console.log(data);
}
});
});
</script>
폼 데이터 채우기
<form class="layui-form" lay-filter="user-form">
<div class="layui-form-item">
<label class="layui-form-label">사용자명</label>
<div class="layui-input-block">
<input type="text" name="username" value="" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">비밀번호</label>
<div class="layui-input-block">
<input type="password" name="password" value="" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button type="submit" class="layui-btn layui-bg-blue" lay-submit lay-filter="submit-login">로그인</button>
</div>
</div>
</form>
<script>
layui.use(function(){
var form = layui.form;
var util = layui.util;
util.on({
fillFormData: function(){
var userData = {
username: "admin",
password: "secure123"
};
form.val('user-form', userData);
}
});
});
</script>
동적 폼 렌더링
form.render(type, filter);
// 매개변수 type은 선택 사항이며, 폼 컴포넌트 유형에 해당합니다: input, select, checkbox, radio; 비워두면 모든 유형을 가리킵니다.
// 매개변수 filter는 선택 사항이며, class="layui-form"이 있는 요소의 lay-filter 속성 값에 해당하며, 렌더링할 폼 영역을 지정하는 데 사용됩니다.
폼 컴포넌트는 요소 로딩이 완료된 후 자동으로 모든 폼 영역을 렌더링하므로, 이 메서드는 주로 동적으로 삽입된 폼 요소의 렌더링에 사용됩니다.
<form class="layui-form" lay-filter="dynamic-form">
동적으로 삽입된 폼 요소
</form>
<script>
layui.use(function(){
var form = layui.form;
// 폼 요소가 동적으로 삽입될 때, 컴포넌트 렌더링을 수동으로 수행해야 표시됩니다
form.render(); // 모든 폼 렌더링
form.render('select'); // select 요소만 렌더링
form.render(null, 'dynamic-form'); // lay-filter="dynamic-form" 컨테이너 내의 모든 폼 렌더링
form.render('checkbox', 'dynamic-form'); // lay-filter="dynamic-form" 컨테이너 내의 checkbox 요소만 렌더링
})
</script>
4. 테이블
테이블 기본 렌더링
<script>
layui.use(function(){
var table = layui.table;
var util = layui.util;
var form = layui.form;
table.render({
elem: '#user-table',
url: "/api/users", // 데이터 인터페이스
page: true, // 페이지네이션 활성화
response: {
statusCode: 200 // 성공 상태 코드를 200으로 재정의
},
parseData: function(res){
return {
"code": res.code,
"msg": res.message,
"count": res.total,
"data": res.records
};
},
cols: [[
{type: 'checkbox', width: '8%'},
{field: 'id', title: 'ID', width: '12%'},
{field: 'name', title: '이름', width: '25%'},
{field: 'email', title: '이메일', width: '35%'},
{field: 'role', title: '역할', width: '20%'}
]]
});
});
</script>
테이블 작업 열 이벤트 및 모니터링
<script type="text/html" id="operation-bar">
<button class="layui-btn layui-btn-sm layui-bg-blue" lay-event="view">보기</button>
<button class="layui-btn layui-btn-sm layui-bg-red" lay-event="remove">삭제</button>
</script>
<script>
layui.use(function(){
var table = layui.table;
var util = layui.util;
var form = layui.form;
table.render({
elem: '#user-table',
url: "/api/users",
page: true,
response: {
statusCode: 200
},
parseData: function(res){
return {
"code": res.code,
"msg": res.message,
"count": res.total,
"data": res.records
};
},
cols: [[
{type: 'checkbox', width: '8%'},
{field: 'id', title: 'ID', width: '12%'},
{field: 'name', title: '이름', width: '25%'},
{field: 'email', title: '이메일', width: '35%'},
{field: 'role', title: '역할', width: '20%'},
{title: '작업', width: '20%', templet: '#operation-bar'}
]]
});
// 작업 열 버튼 이벤트 모니터링
table.on('tool(user-table)', function(obj){
if(obj.event === 'view'){
var userData = obj.data;
console.log(userData);
} else if(obj.event === 'remove'){
console.log("삭제 처리");
}
});
});
</script>
다중 선택 및 전체 선택
<script>
layui.use(function(){
var table = layui.table;
var util = layui.util;
var form = layui.form;
table.render({
elem: '#user-table',
url: "/api/users",
page: true,
response: {
statusCode: 200
},
parseData: function(res){
return {
"code": res.code,
"msg": res.message,
"count": res.total,
"data": res.records
};
},
cols: [[
{type: 'checkbox', width: '8%'},
{field: 'id', title: 'ID', width: '12%'},
{field: 'name', title: '이름', width: '25%'},
{field: 'email', title: '이메일', width: '35%'},
{field: 'role', title: '역할', width: '20%'}
]]
});
// 선택된 데이터 가져오기
util.on({
getSelectedData: function(){
var tableStatus = table.checkStatus('user-table');
console.log(tableStatus.data);
console.log(tableStatus.data.length);
console.log(tableStatus.isAll);
}
});
});
</script>
검색 기능
<form class="layui-form" lay-filter="search-form">
<div class="layui-form-item">
<div class="layui-input-inline">
<input type="text" name="keyword" placeholder="검색어 입력" class="layui-input">
</div>
<button type="submit" class="layui-btn layui-bg-blue" lay-submit lay-filter="search">검색</button>
</div>
</form>
<script>
layui.use(function(){
var table = layui.table;
var form = layui.form;
form.on('submit(search)', function(obj){
var searchData = obj.field;
table.reload('user-table', {
where: searchData
});
return false;
});
});
</script>
5. 레이어 팝업
1. 팝업 요소 정의
<div id="add-user-modal" style="display: none; padding: 20px;">
<!-- 사용자 추가 폼 내용 -->
</div>
2. JavaScript로 팝업 열기
// 팝업 창 열기
layer.open({
type: 1,
content: $("#add-user-modal"),
area: ['600px', '400px'],
title: '사용자 추가',
btn: ['저장', '취소'],
yes: function(){
// 저장 로직
}
});
6. 파일 업로드
기본 업로드

<script>
var upload = layui.upload;
upload.render({
elem: '#avatar',
url: '/api/upload',
done: function(res){
if(res.code !== 200){
layer.msg("업로드 실패");
return false;
}
$("#avatar").attr('src', res.data.url);
}
});
</script>
업로드 진행률 표시
<div class="layui-progress" lay-filter="upload-progress" style="margin-top: 10px; width: 200px">
<div class="layui-progress-bar" lay-percent="0%"></div>
</div>
<script>
upload.render({
elem: '#avatar',
url: '/api/upload',
progress: function(n, elem, res){
var percent = n + '%';
layui.element.progress('upload-progress', percent);
}
});
</script>
백엔드 인터페이스
@PostMapping("/upload")
@ResponseBody
public Map<String, Object> uploadFile(@RequestParam("file") MultipartFile file) throws IOException {
String uploadDir = request.getServletContext().getRealPath("/uploads/");
File dir = new File(uploadDir);
if(!dir.exists()) {
dir.mkdirs();
}
String fileName = file.getOriginalFilename();
file.transferTo(new File(uploadDir + fileName));
Map<String, Object> result = new HashMap<>();
result.put("code", 200);
result.put("data", "/uploads/" + fileName);
return result;
}
7. AES 암호화
프론트엔드 암호화
<script src="/static/js/crypto-js.min.js"></script>
<script>
function encryptData(data) {
var key = CryptoJS.enc.Utf8.parse("encryption-key-123");
var encrypted = CryptoJS.AES.encrypt(JSON.stringify(data), key, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
});
return encrypted.toString();
}
</script>
백엔드 암호화
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
public class AESUtil {
private static final String ALGORITHM = "AES/ECB/PKCS5Padding";
private static final String SECRET_KEY = "encryption-key-123";
public static String encrypt(String data) throws Exception {
SecretKeySpec keySpec = new SecretKeySpec(SECRET_KEY.getBytes(), "AES");
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, keySpec);
byte[] encrypted = cipher.doFinal(data.getBytes());
return Base64.getEncoder().encodeToString(encrypted);
}
public static String decrypt(String encryptedData) throws Exception {
SecretKeySpec keySpec = new SecretKeySpec(SECRET_KEY.getBytes(), "AES");
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, keySpec);
byte[] decoded = Base64.getDecoder().decode(encryptedData);
byte[] decrypted = cipher.doFinal(decoded);
return new String(decrypted);
}
}