1) 문법

> 무조건 하나의 태그만 리턴하기때문에 최상위 태그 필요

> 변수선언은 let or const로만 해야한다.(스코프가 꼬이기때문)

*** let은 변수 const는 상수임

> if사용 불가능

*** 대신 삼항연산자 사용가능 -> 조건 ? 값(true) : 값(false), 조건부렌더링 -> 조건 && 값 (false면 안나옴)

> css 방식

1. 내부에 정의 > style 정의(비추천)

2. 외부에 정의(css파일에 정의) >> class로 지정이아닌 className 사용해야함

3. 라이브러리사용 (부트스트랩)

2)배열사용

>>> ... 스프레드를 사용해서 값 수정등이 용이하다 !!

*** map 사용시 권고사항 ***

>> map을 뿌릴때 해당 형태로 사용해야한다.(위치 설정으로 값 변경시 리렌더링 방지)

state.map((실제 value 변수, 위치) => (<태그 key={위치}>{실제 value 변수}</태그>))

3) 함수와 이벤트

 

>> 일반적인 방법이며, number가 상태값이 아니기 때문에 렌더링이 안된다

 

>> useState사용하여 상태값을 변경하고 화면과 렌더링한다.

******************

const 변수 = () => {

return();

};

--------------------------

function(){

return();

};

>> 위의 두 구문은 같다.

>>>>> 해당함수 자동생성 스니펫 : rsc

******************

4. useState

import './App.css';
import { useState } from 'react';
import Sub from './Sub';

function App() {
  console.log("앱실행!!")

  const [num, setNum] = useState(5);

  let sample = [
    {id:1, name:"홍길동"},
    {id:2, name:"임꺽정"},
    {id:3, name:"장보고"},
    {id:4, name:"샹크스"}
  ];
  
  const [users, setUsers] = useState(sample);
  
  const download = () => {
    setUsers([...sample, { id:num, name: '조자룡' }]);
    setNum(num+1);
  };

  return (
    <>
      <div>
          <button onClick={download}>다운로드</button>
          {users.map((u, index) => (
            <ul key={index}> 
              <li>
               {u.id}, {u.name}
              </li>
            </ul>
            
          ))}
      </div>
    </>
  );
}

export default App;

>> 버튼을 누를때마다 조자룡 숫자 증가

5. useEffect

*** {} 중괄호 안에 갇혀 import되는 애들은 from 위치의 메인 함수 즉 export나 default 값이 아닌 값을 가져올때 중괄호로 감싸서 보낸다

import { useEffect, useState } from 'react';
import './App.css';
import Sub from './Sub';


function App() {

  const [data, setData] = useState(0);

  const [search, setSearch] = useState(0);

  const download = () => {
    let downloadData = 5;
    setData(downloadData)
  }
  
  // 실행시점 : 
  // 1. App() 함수가 최초 실행될 때(마운트, 그림이그려질때)
  // 2. 상태 변수가 변경될때(useState) >> []로 디펜던시를 설정
  // 설정한 값이 변경될때만 useEffect실행 > 공백이면 최초 한번만 실행
  // 3. 의존리스트를 관리할 수 있다.
  useEffect(()=>{
    console.log("useEffect 실행");
    download();
  },[search]);
  
  return (
    <>
      <div>
        <button onClick={()=>{
          setSearch(search+2);
        }}>
          검색하기
        </button>
        <h1>데이터:{data}</h1>
        <button onClick={()=>{
          setData(data+1);
          }}
        >
          더하기
        </button>
      </div>
    </>
  );
}

export default App;

>>> useEffect는 [ ] 를 통한 디펜던시가 중요!!, 검색하기 버튼 클릭시 다시 그림을 그린

6. useMemo

import { useEffect, useMemo, useState } from 'react';
import './App.css';
import Sub from './Sub';


function App() {
  
  const [list, setList] = useState([1,2,3,4]);
  const [str, setStr] = useState("합계");

  const getAddResult =()=> {
    let sum = 0;
    list.forEach((i) => (sum = sum + i));
    console.log("sum 함수 실행", sum);
    return sum;
  }
  const addResult = useMemo(() => getAddResult(), [list])
  
  return (
    <>
      <button onClick={()=>{
        setStr("안녕!!");
        }}>
          문자 변경
      </button>
      <button onClick={()=>{
        setList([...list, 10]);
        }}>
          리스트 값 추가
      </button>
      <div>
       {list.map((i)=>(
        <h1>{i}</h1>
       ))}
      </div>
      <div>{str} : {addResult}</div>
    </>
  );
}

export default App;

>> useMemo를 사용해 getAddResult 함수를 기억해서 문자 변경이벤트가 이루어질때 묶여있는 행을 재실행하지 않는다

7.useRef

import { createRef, useEffect, useMemo, useRef, useState } from 'react';
import './App.css';
import Sub from './Sub';


function App() {
  
  const myRef = useRef(null);
  const [list, setList] = useState([
    {id:1, name:'길동'},
    {id:2, name:'꺽정'}
  ])
  const myRefs = Array.from({length:list.length}).map(()=>createRef());
  

  return (
    <>
      <button onClick={()=>{
        console.log(myRef);
        console.log(myRef.current);
        myRefs[1].current.style.backgroundColor = 'red';
      }}>
        색 변경!!
      </button>
      <div ref={myRef}> 박스 </div>
      {list.map((user, index)=>
        <h1 key={index} ref={myRefs[index]}>{user.name}</h1>
      )}
    </>
  );
}

export default App;

>> useref는 특정 dom을 가리키고 해당 dom을 수정한다. key설정 말고도 useref를 사용해서 index를 부여할 수 있다.

Array.from({length:list.length}).map(()=>createRef()
//위의 구문을 사용해 새로운 배열을 생성한다

8. style-component

>> npm install --save styled-components / yarn add styled-components 를 통해서 스타일 컴포넌트 설

https://styled-components.com/docs

위의 사이트에서 참고하여 스타일컴포넌트 사용 !!

import styled from 'styled-components';
import './App.css';

function App() {
  
  const Title = styled.h1`
  font-size: 1.5em;
  text-align: center;
  color: palevioletred;
`;

  return (
    <>
     <Title>헬로</Title>
    </>
  );
}

export default App;

>> 해당형식으로 컴포넌트별로 디자인을 달리하여 한페이지에 넣고 사용!!

>> 변수명은 정해진 규칙을 찾아보고 사용하자(없으면 styled+변수명+변수형식 형태로 사용)

9. props사용하기(데이터 전송, 값 분배) = passing

//HomePage.js

import React, { useEffect, useState } from 'react';
import Footer from '../components/Footer';
import Header from '../components/Header';
import Home from '../components/home/Home';

const HomePage = () => {

    // http 요청 >> fetch, axios(다운), ajax..
    const [boards, setBoards] = useState([]);

    // 빈배열이기에 한번만 실행
    useEffect(() => {
      //다운로드 가정
      let data = [
        {id:1, title:"제목1", contents:"내용1"},
        {id:2, title:"제목2", contents:"내용2"},
        {id:3, title:"제목3", contents:"내용3"}
      ];

      setBoards([...data]);

    }, [])
    
    return (
        <div>
            <Header/>
            <Home boards={boards} setBoards={setBoards}/>
            <Footer/>
        </div>
    );
};

export default HomePage;
//Home.js

import React from 'react';

const Home = (props) => {
    // 구조분할 할당
    const {boards, setBoards} = props;

    return (
        <div>
            <h1>홈페이지입니다!</h1>
            <button onClick={()=>setBoards([])}>전체 삭제</button>
            {boards.map((board) => 
                <h3>
                    제목 : {board.title} 내용 : {board.contents}
                </h3>
            )}
        </div>
    );
};

export default Home;

>> 해당형식으로 HomePage에 변수를 설정하고 Home에게 전송한 후 Home에서 props를 사용하여 데이터를 받고, 받은 데이터를 이용하여 화면을 구성한다

>> 컴포넌트 패싱은 하기 형태로 작성한다.

// Homepage.js

import React, { useEffect, useState } from 'react';
import Footer from '../components/Footer';
import Header from '../components/Header';
import Home from '../components/home/Home';

const HomePage = () => {

    // http 요청 >> fetch, axios(다운), ajax..
    const [boards, setBoards] = useState([]);
    const [user, setUser] = useState([]);

    // 빈배열이기에 한번만 실행
    useEffect(() => {
      //다운로드 가정
      let data = [
        {id:1, title:"제목1", contents:"내용1"},
        {id:2, title:"제목2", contents:"내용2"},
        {id:3, title:"제목3", contents:"내용3"}
      ];

      setBoards([...data]);
      setUser({id:1, userName:'ssar'});
    }, [])
    

    return (
        <div>
            <Header/>
            <Home boards={boards} setBoards={setBoards} user={user}/>
            <Footer/>
        </div>
    );
};

export default HomePage; 
// Home.js
import React from 'react';
import styled from 'styled-components';


let StyledDeleteButton = styled.button`
    color: ${(props)=>(props.user.userName === 'ssar'?'blue':'red')};
`;

const Home = (props) => {
    // 구조분할 할당
    const {boards, setBoards, user} = props;

    return (
        <div>
            <StyledDeleteButton user={user} onClick={()=>setBoards([])}>
                전체 삭제
            </StyledDeleteButton>
            {boards.map((board) => 
                <h3>
                    제목 : {board.title} 내용 : {board.contents}
                </h3>
            )}
        </div>
    );
};

export default Home;
// Header.js

import React from 'react';
import styled from 'styled-components';

const StyledHeaderDiv = styled.div`
    border: 1px solid black;
    height: 300px;
    background-color: ${(props)=>props.backgroundColor}
`;

const Header = () => {
    return (
        <>
            <StyledHeaderDiv backgroundColor="blue">
                <ul>
                    <li>메뉴 1</li>
                    <li>메뉴 2</li>
                </ul>
            </StyledHeaderDiv>
        </>
    );
};

export default Header;

10. 스타일 상속(확장)

const StyledDeleteButton = styled.button`
color: ${(props)=>(props.user.userName === 'ssar'?'blue':'red')};
`;

const StyledAddButton = styled(StyledDeleteButton)`
    background-color:green;
`;

>>> styled(작성해둔스타일컴포넌트) 형식으로 작성하면 기존에 작성한 컴포넌트를 그대로 사용하며 수정할 수 있다.

11. 라우팅(react router dom), 네비게이션

>> yarn add react-router-dom 이나 npm install react-router-dom를 통해서 설치한다

>> 페이지 일괄 수정

1) index.js

// index.js

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
    <BrowserRouter>
        <App />
    </BrowserRouter>
);

>> BrowserRouter로 App컴포넌트를 감싸준다.

2) App.js

// App.js

import { Route, Routes } from 'react-router-dom';
import './App.css';
import Footer from './components/Footer';
import Header from './components/Header';
import HomePage from './pages/HomePage';
import LoginPage from './pages/LoginPage';

function App() {

  return (
    <>
      <Header></Header>
      <Routes>
        <Route path='/' exact={true} element={<HomePage/>}></Route>
        <Route path='/login' exact={true} element={<LoginPage></LoginPage>}></Route>
      </Routes>
      <Footer></Footer>
    </>
  );
}

export default App;

>> Header와 Footer등 컴포넌트가 모든 페이지에 적용될 시 App.js에 삽입해준다.

>> <Routes><Route path=경로 exact={true} element={컴포넌트}></Route></Routes>

위의 형태로 나타낼 페이지의 네비를 삽입해준다.

2) Header.js(컴포넌트 중 네비설정할곳)

// Header.js

const Header = () => {
    return (
        <>
            <StyledHeaderDiv backgroundColor="blue">
                <ul>
                    <li>
                        <Link to={'/'}>홈</Link>
                    </li>
                    <li>
                        <Link to={'/login'}>로그인</Link>
                    </li>
                </ul>
            </StyledHeaderDiv>
        </>
    );
};

>> 위와같이 Link to=경로 를 사용하여 네비를 지정해준다

*** react는 spa를 권고하는데 a태그를 사용하면 페이지가 새로고침 되므로 link 태그사용!!

 

3) 뒤로가기 or 앞으로가기 등 페이지 이동 구현

** 5버전과 6버전이 많이 다르니 알아보고 사용

// LoginPage.js

import React from 'react';
import Login from '../components/Login';
import { useNavigate } from 'react-router-dom';

const LoginPage = () => {

    const navi = useNavigate();

    const GoBack = () => {
        navi(-1);
    };
    
    return (
        <div>
            <button onClick={()=> GoBack()}>뒤로가깅</button>
            <Login/>
        </div>
    );
};

export default LoginPage;

>> 위와같은 형태로 react-router-dom의 useNavigate 사용하여 -1, / 1 ....으로 원하는 만큼 이동하는 버튼 생성하여 사용!!

'react' 카테고리의 다른 글

Breadcrumb 만들기  (0) 2023.05.16
페이지 인쇄 구현  (0) 2023.05.16
react 전체 선택/해제 구현  (0) 2023.05.16
네이버 스마트에디터(2.0) 사용하기  (0) 2023.05.16
React 사용(in VSCode)  (0) 2023.05.15

- 띄어쓰기 공백 자동처리

- js 코드오류 검색

- 코드조각 설정을 통해 자동 코드완성

- 태그명 변환시 대응하는 닫기태그도 변환 / 태그 자동닫기 기능

- 에디터 꾸미기

-작업 미리보기. live server는 작업창 하단의 go live를 통해 보기 가능 live priview는 우측상단 미리보기표시 아이콘을 통해 실시간으로 보기 가능(html만되는듯)

 

 

- AI 코드 자동완성

 

 

- git 확장프로그램

 

 

- 코드 가독성 향상

react를 시작하기 앞서 먼저 Node.js와 npx를 다운받아야한다.

1. node.js 설치

>> 아래의 경로에 들어가서 다운로드

nodejs.org/ko/download/

 

다운로드 | Node.js

Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine.

nodejs.org

 

> 계속 Next하여 설치 > cmd에서 node -v과 npm -v로 설치 확인

2. npx 설치

>> cmd 창에 npm install npx -g 입력하여 npx 설치

** yarn 설치(yarn은 npm과 같은 노드 매니저로 노트 사용을 돕는다)

>> npm install -g yarn

3. create-react-app 사용하여 프로젝트 생성

>> cmd창에서 생성 위치 설정 > npx create-react-app 프로젝트명 입력하여 생성

**yarn >> yarn create react-app 프로젝트명

*** cmd창 위치변경법 ***

d: (d드라이브로 변경) > cd 경로 입력(d드라이브 뒤부터) , cd ..은 상위폴더로 이동

▼하기 사진 참조

4. cmd에서 react 설치 확인

>> 3번에서 생성한 프로젝트의 위치에서 npm start 입력하여 react 설치 확인

**yarn >> yarn start로 시작

>> 위의 안내문이 뜨고 local 주소창이 열리면 설치확인

5. VSCode에서 실행해보기

>> 터미널단에서 cmd창 열거나 새터미널로 추가 터미널 생성해 실행하여 npm start 입력

> 새로운 react창이 열린다.

6. 리엑트 페이지 작성

>> 페이지 작성 이전에 필요없는 파일부터 정리한다(아래의 선택된 영역 삭제)

> css 부분 내용 전체삭제 > App.js파일에 원하는 형태로 수정

************************ 구동원리 ************************

1. React앱 실행시 public 폴더의 index.html 실행됨

2. index.html는 index.js에서 root id를 가지고 있는 부분을 렌더링

3. index.js는 App.js를 참조

4. 최종적으로 App.js에 작성된 화면을 index.html에서 출력

************************************************************

7. 부트스트랩 적용

>> 터미널 cmd에서 npm install react-bootstrap bootstrap 사용해서 부트스트랩 설치

**yarn >> yarn add react-bootstrap bootstrap 사용해서 설치

> index.js에 import 'bootstrap/dist/css/bootstrap.min.css' 구문 삽입

테마적용법 익히자자자

사용 https://react-bootstrap.github.io/getting-started/introduction/

 

React-Bootstrap

The most popular front-end framework, rebuilt for React.

react-bootstrap.github.io

 

해당 사이트에 접속해서 원하는 스타일 가져와서 사용하면됨

 

************************ 부트스트랩 디자인 사용 ************************

1. 새로운 파일 생성하여 부트스트랩 시트 가져오기

2. App.js에 작성한 파일 import

3. import할때 지정한 별칭(위의 Boot)의 태그를 사용해서 function안에 삽입

(react는 여러태그 사용시 최상단 태그가 존재해야함)

4. 실행확인

************************************************************

**************************** 부트스트랩 템플릿 적용 ********************************

1. 프로젝트생성 >> yarn create react-app 프로젝트

2. 템플릿 다운로드 >> 위의 추천사이트에서 원하는 템플릿 다운

3. 템플릿을 생성한 프로젝트에 덮어쓰기

4. 해당 프로젝트에서 yarn install

5. yarn start

>> 적용된 템플릿 수정하여 사용하면 된다!!

************************************************************************************************

'react' 카테고리의 다른 글

Breadcrumb 만들기  (0) 2023.05.16
페이지 인쇄 구현  (0) 2023.05.16
react 전체 선택/해제 구현  (0) 2023.05.16
네이버 스마트에디터(2.0) 사용하기  (0) 2023.05.16
React hooks, jsx 문법  (0) 2023.05.15

1. el과 jstl

1)el(expression language)

- <%= %> , out.println()과 같은 자바코드를 더 이상 사용하지 않고 좀더 간편하게 출력을 지원하기 위한 도구.

배열이나 컬렉션에서도 사용되고, JavaBean의 프로퍼티에서도 사용된다.

- <%=%> 대신 ${}를 사용하며, parameter형식에서는 ${param.///} 형태로 사용한다.

2) jstl(jsp standard tag library)

-자신만의 태그를 추가할 수 있는 기능 제공. <jsp:include>또는 <jsp:usebean>과 같은 커슽텁 태그처럼

연산이나 조건문, 반목분인 if문, for문, db를 편리하게 처리할 수 있게 도와주는 것

-선언방식

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>

3) el과 jstl 사용하기

1. jstl 사용을 위한 jar파일 다운로드 (maven pository)

>> jstl검색후 다운수 제일많은거 다운

>> web-inf 의 lib 폴더에 넣고 사용한다.

2. dto 셋팅

package kr.or.ksmart;

public class UserDto {
	private String userName;
	private String userAddr;
	
	public String getUserName() {
		return userName;
	}
	public void setUserName(String userName) {
		this.userName = userName;
	}
	public String getUserAddr() {
		return userAddr;
	}
	public void setUserAddr(String userAddr) {
		this.userAddr = userAddr;
	}
	
	@Override
	public String toString() {
		return "UserDto [userName=" + userName + ", userAddr=" + userAddr + "]";
	}
}

3. servlet에서 값을 세팅(경로를 설정해줘야함)

package kr.or.ksmart;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/Ksmart")
public class Ksmart extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		/******************
		 * 포워드 기본
		 ******************/
		List<String> strList = new ArrayList<String>();
		strList.add("A");
		strList.add("B");
		strList.add("C");
		
		UserDto dto = new UserDto();
		dto.setUserAddr("전주시");
		dto.setUserName("홍길동");
		
		request.setAttribute("strList", strList);
		request.setAttribute("userDto", dto);
		request.setAttribute("myName", "홍길동");

		
		//getRequestDispatcher("출력을 위임할 경로를 기입")
		RequestDispatcher rd = request.getRequestDispatcher("/eljstl.jsp");
		//출력을 위임할 페이지에 리퀘스트와 리스폰스 객체를 전달
		rd.forward(request, response);
		
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}

4. 출력형태 설정

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%
	/*
		Model -> spring에서 객체담고 화면에 그 객체를 전달해줌. request 기능을 한다.
		서블릿 -> request 속성에 객체를 삽입하고 화면에서 객체를 받는다.
		(포워드가 되었을 시 )
	
	*/
	request.setAttribute("userName", "홍길동");
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>el과 jstl</title>
</head>
<body>
	안녕하세요. ${myName}
	<br>
	${userDto} <br>
	${userDto.userName}
	
	<c:if test="${!empty userDto}">
		${userDto.userName}
	</c:if>
	
	<c:if test="${!empty strList}">
		<c:forEach var="str" items="${strList}">
			${str}
		</c:forEach>
	</c:if>
</body>
</html>

5. 확인(서블릿 페이지에서 실행하면 서블릿에 세팅된 경로로 실행된다.)

'JAVA' 카테고리의 다른 글

데이터 암/복호화 (AES256)  (0) 2023.05.16
데이터 암호화(SHA256)  (0) 2023.05.16
Java-Jsp Driver로딩 및 DTO Bean  (0) 2023.05.15
Jsp-Java JDBC 연결  (0) 2023.05.09
매서드(method), 상속, final  (0) 2023.04.17

1. 부트스트랩

- html, css, js를 합쳐놓은 프레임워크

- html, css, js를 활용하여 만들진 많은 컴포넌트 (기능-자바스크립트 + 화면-html, css)제공

- 부트스트랩으로 만들어진 웹사이트는 반응형 웹사이트이다. (비반응형도 가능)

- 반응형이란 ? -> 디바이스의 크기에 따라 크기에 맞는 최적화된 화면으로 변환

1) 다운로드

- bootstrap.min.js, bootstrap.min.css 파일 필요

- 테마css(필수x)

- 버저너에 따라 제이쿼리 필요

2) 구조 및 준비

- html5, 뷰포트 메타태그(모바일 웹 구성시 필수 정보), bootstrap.min.js, bootstrap.min.css 파일

- 3버전과 4버전은 제이쿼리가 필수이나, 5버전은 제이쿼리가 없어도 된다(필요에 의하여 추가 가능)

>> 웹컨텐츠 하위에 plugin 폴더를 생성하여 홈페이지에서 다운로드받은 부트스트랩폴더를 삽입하였다.

3) 부트스트랩 사용하기

- 부트스트랩 사용을 위한 jsp:include

1. index파일을 하나 잡는다.

2. include폴더를 생성하여 head와 foot 부분의 페이지를 각각 작성한다.

* head

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<!-- 모바일웹 작업시 필수 메타 태그 정보 -->
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="${pageContext.servletContext.contextPath}/plugin/bootstrap-3.3.2/css/bootstrap.min.css">
<script type="text/javascript" src="${pageContext.servletContext.contextPath}/plugin/js/jquery-3.6.0.min.js"></script>
<title>${param.pageTitle}</title>
</head>
<body>

* foot

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    
<script type="text/javascript" src="${pageContext.servletContext.contextPath}/plugin/bootstrap-3.3.2/js/bootstrap.min.js"></script>
</body>
</html>

 

* index

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<% request.setCharacterEncoding("UTF-8"); %>
<jsp:include page="/include/head.jsp">
	<jsp:param value="부트스트랩 시작하기" name="pageTitle"/>
</jsp:include>
	
	<h1>부트스트랩 시작하기</h1>
	<span class="glyphicon glyphicon-asterisk"></span>
	
	<button type="button" class="btn btn-default" aria-label="Left Align">
		<span class="glyphicon glyphicon-align-left" aria-hidden="true"></span>
	</button>
	
<jsp:include page="/include/foot.jsp"></jsp:include>

>>>이렇게 해주는 이유는 이런식으로 부분을 나눠두고 include 하면 매 페이지마다 부트스트랩 사용을위한 링크를 걸지않아도 되기때문에, 편리성과 중복의 우려를 배제할 수 있기 때문이다.

>> index 페이지 상의 버튼과 *컴포넌트 사용 예시

4) 컴포넌트

- 부트스트랩 기반으로 작성된 디자인 요소를 컴포넌트라 한다.

- 컴포넌트는 html과 css의 구조가 있다.

1. css 구조

- 컴포넌트는 대표 클래스와 옵션 클래스로 구성되어 있다.

- 대표클래스 : 전체적인 외형

- 옵션클래스 : 색상, 여백 등

- 헬퍼클래스 : 각 컴포넌트에 종속이 없으며 모든 곳에서 도움을 줄 수 있는 클래스

* 대표적인 옵션클래스 *

- 크기

> class="대표클래스 대표클래스-*"

> 크기 옵션 클래스 종류 : lg > md > sm > xs

ex) class="대표클래스 대표클래스-lg"

<h4>크기</h4>
	<button type="button" class="btn btn-lg">버튼1</button>
	<button type="button" class="btn btn-md">버튼2</button>
	<button type="button" class="btn btn-sm">버튼3</button>
	<button type="button" class="btn btn-xs">버튼4</button>
	
	<input type="text" class="form-control">
	<input type="text" class="form-control input-lg">

- 색상

> class="대표클래스 대표클래스-*"

> 색상 옵션 클래스 종류 : defalut, danger, warning, primary, success, info

ex) class="대표클래스 대표클래스-danger"

<h4>색상</h4>
	<button type="button" class="btn btn-dafault">버튼1</button>
	<button type="button" class="btn btn-danger">버튼2</button>
	<button type="button" class="btn btn-warning">버튼3</button>
	<button type="button" class="btn btn-primary">버튼4</button>
	<button type="button" class="btn btn-success">버튼5</button>
	<button type="button" class="btn btn-info">버튼6</button>

2. 이벤트 메서드

- 각 컴포넌트들이 특정 행위(이벤트)가 발동시 등록해놓은 콜백함수가 작동된다.

- data-toggle 속성 : 이벤트 종류

- data-target 속성 : 이벤트 작동 대상

- data-dismiss 속성 : 이벤트 종료

<!-- Button trigger modal -->
	<button type="button" class="btn btn-primary btn-lg" data-toggle="modal" data-target="#myModal">
	  Launch demo modal
	</button>
	
	<!-- Modal -->
	<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
	  <div class="modal-dialog">
	    <div class="modal-content">
	      <div class="modal-header">
	        <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
	        <h4 class="modal-title" id="myModalLabel">Modal title</h4>
	      </div>
	      <div class="modal-body">
	      		<input type="text" id="myInput">
	      </div>
	      <div class="modal-footer">
	        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
	        <button type="button" class="btn btn-primary">Save changes</button>
	      </div>
	    </div>
	  </div>
	</div>
	
	<script>
		$(function(){
			var
			$myInput = $('#myInput'),
			$myModal = $('#myModal');
			
			$myModal.on('show.bs.modal', function (e) {
				  alert('모달이 호출 되었습니다.');
			});
			$myModal.on('hidden.bs.modal', function (e) {
				$myInput.val('');
			});
		});
	</script>

>> 자바스크립트를 이용한 모달(Modal) 사용

>> 버튼클릭시 모달실행. 모달이 실행되면 alert, 종료되면 input의 value를 초기화시킨다.

3. 그리드 시스템

- 1행을 부요 요소 기준의 크기로 12열로 나눈다.

- col-* 접두사로 시작된다.

- 디바이스 크기의 옵션도 부여 할 수 있다.(디바이스 크기 영역에 도달될 시 해당 클래스만 작동된다.)

- col-lg-*, col-md-*, col-sm-*, col-xs-*

ex) [col-lg-6 col-md-12][col-lg-6 col-md-12]

- 1행을 초기화 하는 클래스는 row 클래스이다. (1행을 표현하기전에 row 클래스로 감싼다.)

1. 1행 표기

- 설정된 디바이스 크기 미만으로 넘어갔을 경우 그 이하의 디바이스 크기 12로 강제 변환

- sm 영역 미만으로 사이즈 변경시 xs-12로 강제 변환

<div class="row">
		<div class="col-sm-4">
			<div class="alert alert-danger"></div>
		</div>
		<div class="col-sm-4">
			<div class="alert alert-danger"></div>
		</div>
		<div class="col-sm-4">
			<div class="alert alert-danger"></div>
		</div>
	</div>

2. 1행 디바이스 크기별로 지정

- 해당 디바이스 크기에 관련된 그리드 시스템 클래스 적용

<div class="row">
		<div class="col-lg-3 col-md-6">
			<div class="alert alert-info"></div>
		</div>
		<div class="col-lg-3 col-md-6">
			<div class="alert alert-info"></div>
		</div>
		<div class="col-lg-3 col-md-6">
			<div class="alert alert-info"></div>
		</div>
		<div class="col-lg-3 col-md-6">
			<div class="alert alert-info"></div>
		</div>
	</div>

3. 반응형 유틸

- 특정 디바이스 크기에서만 보이게하거나 감추게 할 수 있다.

- visible-*(lg, md, sm, xs)-*(inline, block, inline-block)

ex) class="visible-lg-block" -> lg 영역에서 블럭요소로 보이도록

- hidden-*(lg, md, sm, xs)

ex) class="hidden-xs" -> xs 영역에서만 보이지 않도록

<div class="row">
		<div class="col-lg-3 col-md-6">
			<div class="alert alert-info"></div>
		</div>
		<div class="col-lg-3 col-md-6">
			<div class="alert alert-info"></div>
		</div>
		<div class="col-lg-3 col-md-6">
			<div class="alert alert-info"></div>
		</div>
		<div class="col-lg-3 col-md-6 hidden-xs hidden-sm">
			<div class="alert alert-info">최소 사이즈에서는 안보여야함</div>
		</div>
		<div class="col-xs-12 visible-xs-block">
			<div class="alert alert-warning">작은 사이즈의 컨텐츠</div>
		</div>
	</div>

4. 빈 영역 -> offset

- offset이 지정된 대상 왼쪽으로 빈공간 할당

<div class="row">
		<div class="col-sm-3">
			<div class="alert alert-warning"></div>
		</div>
		<div class="col-sm-6"></div>
		<div class="col-sm-3">
			<div class="alert alert-warning"></div>
		</div>
	</div>
	<div class="row">
		<div class="col-sm-3">
			<div class="alert alert-warning"></div>
		</div>
		<div class="col-sm-3 col-sm-offset-6">
			<div class="alert alert-warning"></div>
		</div>
	</div>

>> 다른코드지만 같은모습인걸 확인할 수 있다.

*** 네비게이션바와 케러셀을 이용하여 화면 구성해보기 ***

>>> 부트스트랩 홈페이지의 네비게이션바와 케러셀을 이용하여 화면구성

>> 네비게이션 바

// 네비게이션바 부분
<nav class="navbar navbar-inverse navbar-static-top">
  <div class="container-fluid">
    <!-- Brand and toggle get grouped for better mobile display -->
    <div class="navbar-header">
      <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
        <span class="sr-only">Toggle navigation</span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </button>
      <a class="navbar-brand" href="#">Brand</a>
    </div>

    <!-- Collect the nav links, forms, and other content for toggling -->
    <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
      <ul class="nav navbar-nav">
        <li class="active"><a href="#">Link <span class="sr-only">(current)</span></a></li>
        <li><a href="#">Link</a></li>
        <li class="dropdown">
          <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">Dropdown <span class="caret"></span></a>
          <ul class="dropdown-menu" role="menu">
            <li><a href="#">Action</a></li>
            <li><a href="#">Another action</a></li>
            <li><a href="#">Something else here</a></li>
            <li class="divider"></li>
            <li><a href="#">Separated link</a></li>
            <li class="divider"></li>
            <li><a href="#">One more separated link</a></li>
          </ul>
        </li>
      </ul>
      <form class="navbar-form navbar-left" role="search">
        <div class="form-group">
          <input type="text" class="form-control" placeholder="Search">
        </div>
        <button type="submit" class="btn btn-default">Submit</button>
      </form>
      <ul class="nav navbar-nav navbar-right">
        <li><a href="#">Link</a></li>
        <li class="dropdown">
          <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">Dropdown <span class="caret"></span></a>
          <ul class="dropdown-menu" role="menu">
            <li><a href="#">Action</a></li>
            <li><a href="#">Another action</a></li>
            <li><a href="#">Something else here</a></li>
            <li class="divider"></li>
            <li><a href="#">Separated link</a></li>
          </ul>
        </li>
      </ul>
    </div><!-- /.navbar-collapse -->
  </div><!-- /.container-fluid -->
</nav>

>> 케러셀부분

<div id="myCarousel" class="carousel slide" data-ride="carousel">
  <!-- Indicators -->
  <ol class="carousel-indicators">
    <li data-target="#myCarousel" data-slide-to="0" class="active"></li>
    <li data-target="#myCarousel" data-slide-to="1"></li>
    <li data-target="#myCarousel" data-slide-to="2"></li>
  </ol>

  <!-- Wrapper for slides -->
  <div class="carousel-inner" role="listbox">
    <div class="item active">
      <img src="http://hrdmarket.co.kr/resources/file/hrd/institution_ksmart_13123100001/220214113940-9d2ce2c0-d984-4117-ac74-b31d17cdb4d6.jpg" alt="...">
      <div class="carousel-caption">
		이미지 설명입니다.1
      </div>
    </div>
    <div class="item">
      <img src="http://hrdmarket.co.kr/resources/file/hrd/institution_ksmart_13123100001/220214113940-9d2ce2c0-d984-4117-ac74-b31d17cdb4d6.jpg" alt="...">
      <div class="carousel-caption">
		이미지 설명입니다.2
      </div>
    </div>
    <div class="item">
      <img src="http://hrdmarket.co.kr/resources/file/hrd/institution_ksmart_13123100001/220214113940-9d2ce2c0-d984-4117-ac74-b31d17cdb4d6.jpg" alt="...">
      <div class="carousel-caption">
		이미지 설명입니다.3
      </div>
    </div>
  </div>

  <!-- Controls -->
  <a class="left carousel-control" href="#myCarousel" role="button" data-slide="prev">
    <span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
    <span class="sr-only">Previous</span>
  </a>
  <a class="right carousel-control" href="#myCarousel" role="button" data-slide="next">
    <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
    <span class="sr-only">Next</span>
  </a>
</div>

<div class="container" style="margin-top: 15px;">
	<div class="row">
		<div class="col-sm-6">
			<div class="panel panel-default">
			  <div class="panel-body">
			    	<table class="table table-striped">
			    		<thead>
			    			<tr>
			    				<th>제목</th>
			    				<th>등록일</th>
			    			</tr>
			    		</thead>
			    		<tbody>
			    			<tr>
			    				<th>공지사항입니다.</th>
			    				<th>2022-06-08</th>
			    			</tr>
			    			<tr>
			    				<th>공지사항입니다.</th>
			    				<th>2022-06-08</th>
			    			</tr>
			    			<tr>
			    				<th>공지사항입니다.</th>
			    				<th>2022-06-08</th>
			    			</tr>
			    			<tr>
			    				<th>공지사항입니다.</th>
			    				<th>2022-06-08</th>
			    			</tr>
			    			<tr>
			    				<th>공지사항입니다.</th>
			    				<th>2022-06-08</th>
			    			</tr>
			    		</tbody>
			    	</table>
			  </div>
			</div>
		</div>
		<div class="col-sm-6">
			<div class="panel panel-default">
			  <div class="panel-body">
			    	<table class="table table-striped">
			    		<thead>
			    			<tr>
			    				<th>제목</th>
			    				<th>등록일</th>
			    			</tr>
			    		</thead>
			    		<tbody>
			    			<tr>
			    				<th>공지사항입니다.</th>
			    				<th>2022-06-08</th>
			    			</tr>
			    			<tr>
			    				<th>공지사항입니다.</th>
			    				<th>2022-06-08</th>
			    			</tr>
			    			<tr>
			    				<th>공지사항입니다.</th>
			    				<th>2022-06-08</th>
			    			</tr>
			    			<tr>
			    				<th>공지사항입니다.</th>
			    				<th>2022-06-08</th>
			    			</tr>
			    			<tr>
			    				<th>공지사항입니다.</th>
			    				<th>2022-06-08</th>
			    			</tr>
			    		</tbody>
			    	</table>
			  </div>
			</div>
		</div>
	</div>
</div>

<footer>
	ksmart.or.kr 2022-06-08
</footer>

>>결과확인

'CSS' 카테고리의 다른 글

가상선택자(CSS)  (0) 2023.05.09
CSS 속성 종류  (0) 2023.04.17
form 요소, 화면 구성 태그 활용  (0) 2023.04.17

1. 새로운 작업환경설정

- 작업 폴더생성

- UTF-8로 환경 설정

- html 템플릿 수정

- thymeleaf플러그인 설치

help > install new software > work with 부분에 플러그인 주소입력

(http://www.thymeleaf.org/eclipse-plugin-update-site/) > 라이센스 허용 > install anyway > restart

 

2. 파일생성

- 기존 작업파일의 해당 폴더 복사해오기

- pom.xml 수정

1) thymeleaf layout dialect 사용하기(fragment 끼워넣기)

https://mvnrepository.com/

> thymeleaf layout dialect

> 버전선택

> Maven 의존성 스크립트 코드 복사

> pom.xml의 dependencies 내부에 해당 코드 삽입 (버전 생략시 최신버전으로 자동 다운로드)

<!-- https://mvnrepository.com/artifact/nz.net.ultraq.thymeleaf/thymeleaf-layout-dialect -->
		<dependency>
		    <groupId>nz.net.ultraq.thymeleaf</groupId>
		    <artifactId>thymeleaf-layout-dialect</artifactId>
		</dependency>
	</dependencies>

2) log4j 사용하기(프로젝트 의존성 추가)

> pom.xml의 dependencies 내부에 해당 코드 삽입

<!-- https://mvnrepository.com/artifact/org.bgee.log4jdbc-log4j2/log4jdbc-log4j2-jdbc4.1 -->
		<dependency>
		    <groupId>org.bgee.log4jdbc-log4j2</groupId>
		    <artifactId>log4jdbc-log4j2-jdbc4.1</artifactId>
		    <version>1.16</version>
		</dependency>
	</dependencies>

- application.properties 설정

#server port 설정
server.port=80

#thymeleaf 새로고침 여부
spring.thymeleaf.cache=false

# DB 연결정보 설정
spring.datasource.driver-class-name=net.sf.log4jdbc.sql.jdbcapi.DriverSpy
spring.datasource.url=jdbc:log4jdbc:mysql://localhost:3306/ksmart43db?serverTimezone=UTC&characterEncoding=UTF8
spring.datasource.username=ksmart43id
spring.datasource.password=ksmart43pw

3. MainController 생성 및 동작 확인

package com.test.mybatis.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class MainController {

	/*
	 * 메인화면 index
	 * @return index.html 논리적경로 
	 */
	@GetMapping("/")
	public String index() {
		return "index";
	}
}

> run as 동작확인

'springboot' 카테고리의 다른 글

VSCode에서 SpringBoot 사용하기  (1) 2023.05.23
thymeleaf로 레이아웃 관리(fragment)  (0) 2023.05.15
thymeleaf(타임리프)  (0) 2023.05.15
Spring - Maven  (0) 2023.05.15
스프링부트(Spring Boot), Spring MVC  (0) 2023.05.15

1. ajax

- 비동기화 통신을 할 수 있는 웹 어플리케이션 기법

- XMLHttpRequest 객체 활용

- ajax에서 요청할 컨텐츠 타입을 주로 -> json, xml, text

*** 동기화와 비동기화 ***

동기화

- 요청과 응답이 동시에 이루어짐

- 클라이언트가 서버에 요청시 서버에서 응답

- 작성된 코드 순서대로 처리를 완료하고 이후에 클라이언트에 응답을하는방식

> 서버에서 응답이 늦어질 경우 클라이언트에서 화면출력을 대기하는 시간이 길어진다.

비동기화

- 요청과 응답이 동시에 이루어지지 않는다

- 웹페이지를 리로드하지 않고 서버와 통신하는 방식

- 클라이언트 먼저 실행이되고 서버에서 응답이 왔을 경우 작성된 코드가 실행이 된다.

**********************

*** contnetType (MIME-TYPE) ***

html -> text/html

xml -> application/xml

json -> application/json

text -> text/plain

**********************

1) json

- application/json 콘텐츠 타입

- 구문 {"key" : "value"}

- 구문 [{"key" : "value"}, {"key" : "value"}]

2) jQuery $.ajax

- XMLHttpRequest 가공하여 만들어진 메서드

- 응답페이지의 요청 방식을 설정

▼ html 템플릿

<button type="button" id="ajaxCall">요청</button>
	
	<script type="text/javascript">
		$(function(){
			$('#ajaxCall').click(function(){
				
				//1. $.ajax() 메서드 실행시 객체를 삽입하여 실행 가능
				//2. 객체에는 요청 주소, 요청 방식, 데이터, 응답방식
				var request = $.ajax({
					url: "jsonContentType.jsp", //요청주소
					method: "POST", //요청방식
					data: { myName : '홍길동' }, //요청하는 페이지에 전달할 데이터
					dataType: "json" //응답방식(html, xml, json, text, function)
				});
				 
				request.done(function( data ) { //응답 정상 완료시 실행되는 메서드
					//응답 완료시 등답페이지의 텍스트를 읽어 콜백데이터로 전달
					//응답방식에 맞춰서 파싱하여 전달
					console.log(data);
				});
				 
				request.fail(function( jqXHR, textStatus ) { //응답 실패시 실행
					//파싱에러 -> 포멧방식이 잘못 전달
					//에러 -> 서버에서 대부분 에러
					alert( "Request failed: " + textStatus );
				});
			})
		})
	</script>

▼ jsp 템플릿

<%@ page language="java" contentType="application/json; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	String myName = request.getParameter("myName");
%>  
  
{"key" : "value", "key1" : 0, "key2" : true, "myName" : "<%=myName%>"}

>>> 상단의 html 템플릿은 jQuery 홈페이지에서 복사하면된다.(ajax검색 -> 하단의 항목선택 후 소스코드 복사)

 

2. spring - ajax 비동기 통신

 

0. 파일생성

1. application.properties 수정

server.port=80
//정적리소스 맵핑
spring.web.resources.static-locations=classpath:/static/
//로거레벨설정
logging.level.root=INFO
logging.level.org.springframework.web=OFF

2. controller 생성(동작확인)

@Controller
public class MainController {
	
	@GetMapping("/")
	public String main() {
		
		return "index";
	}

3. 경로생성

4. dto생성 (작성 후 getter/setter와 toString 작업)

package kr.or.ksmart.dto;

public class User {
	private String userName;
	private String userAddr;
	private int userAge;
	
	public String getUserName() {
		return userName;
	}
	public void setUserName(String userName) {
		this.userName = userName;
	}
	public String getUserAddr() {
		return userAddr;
	}
	public void setUserAddr(String userAddr) {
		this.userAddr = userAddr;
	}
	public int getUserAge() {
		return userAge;
	}
	public void setUserAge(int userAge) {
		this.userAge = userAge;
	}
	@Override
	public String toString() {
		return "User [userName=" + userName + ", userAddr=" + userAddr + ", userAge=" + userAge + "]";
	}
	
	
}

5. service생성(/**후 자동완성기능을 사용하여 @param, @return등 설정)

package kr.or.ksmart.service;

import org.springframework.stereotype.Service;

import kr.or.ksmart.dto.User;

@Service
public class UserService {
	
	/**
	 * 회원 1명의 정보를 가지고 오기
	 * @param - 없음
	 * @return User
	 */
	public User getUser() {
		//db에서 회원 1명의 정보를 가지고 왔다는 가정
		User user = new User();
		user.setUserName("홍길동");
		user.setUserAddr("전주시");
		user.setUserAge(20);
		return user;
	}
	
}

6. 경로 수정

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>AJAX</title>
<script type="text/javascript" src="/js/jquery-3.6.0.min.js"></script>
</head>
<body>
	<button type="button" id="getUser">회원정보</button>
	
	<script type="text/javascript">
		$('#getUser').click(function(){
			var request = $.ajax({
			  url: "/user/getUser",
			  method: "POST",
			  dataType: "json"
			});
			request.done(function( data ) {
			  console.log(data);
			});
			request.fail(function( jqXHR, textStatus ) {
			  alert( "Request failed: " + textStatus );
			});
		});
	</script>
</body>
</html>

>>확인

 

3. map data 전달

> js부분

var request =
			$.ajax({
				url: "/payList/modifyList",
				type: "POST",
				data : {
						"modifyCode" : modifyCode,
						"modifyName" : modifyName,
						"modifyAmount" : modifyAmount,
						"modifyContents" : modifyContents,
				},
				success: function(data){
					alert('성공~');
				}
			});
			request.fail(function( jqXHR, textStatus ) {
				alert( "Request failed: " + textStatus );
			});

> controller부분

// 급여내역 수정 ajax
	@RequestMapping(value = "/modifyList", method = { RequestMethod.POST })
	@ResponseBody 
	public String modifyFixedList(@RequestParam Map<String, Object> param) {
		String modifyCode = (String) param.get("modifyCode");
		String modifyName = (String) param.get("modifyName");
		String modifyAmount = (String) param.get("modifyAmount");
		String modifyContents = (String) param.get("modifyContents");
		System.out.println(modifyCode + " <- modifyCode!!");
		System.out.println(modifyName + " <- modifyName!!");
		System.out.println(modifyAmount + " <- modifyAmount!!");
		System.out.println(modifyContents + " <- modifyContents!!");
		
		/*
		 * log.info("수정화면에서 입력받은 data:{}", fixedAllowanceList);
		 * payListService.modifyFixedList(fixedAllowanceList);
		 */
		
		
		return modifyCode;
	}

'javascript' 카테고리의 다른 글

제이쿼리(J-Query)  (0) 2023.05.15
이벤트 등록, 동적 바인딩  (0) 2023.05.15
Document API - 객체 검색  (0) 2023.05.15
html 요소 이벤트, on-- 속성, form 객체  (0) 2023.05.15
브라우저 객체 모델(window)  (0) 2023.05.15

1. thymeleaf - fragment

- fragments를 이용해서 레이아웃을 분리하고 확장 라이브러리를 이용하여 하나의 템플릿을 기준으로 끼워넣는 방식의 페이지 처리가 가능 >>> 모든 페이지마다 th:insert가 사용될 필요가 없음

>>> 반드시 dependency 태그 안쪽에 위치해야한다. 버전을 생략할 시 자동으로 최신버전으로 다운로드해준다.

- 프로젝트 내에 fragment폴더를 생성하여 각 부분의 html 파일 작성

- 분리된 fragments 파일을 하나로 합칠 layout 폴더 및 파일 생성

- head부분 작성

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
	  xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
	<head th:fragment="headFragment">
		<meta charset="UTF-8">
		<title>ksmart43</title>
		
		<!-- thymeleaf 링크 표현 구문 @{} -->
		<link rel="stylesheet" type="text/css" th:href="@{/css/main.css}">
		
		<!-- 사용자 정의 css -->
		<th:block layout:fragment="customCss"></th:block>

		<!-- 사용자 정의 js -->
		<th:block layout:fragment="customJs"></th:block>
	</head>
</html>

>>> 확장라이브러리를 사용하기 때문에 html 부분에

xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" 태그를 추가로 사용한다

 

- header 부분 작성

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
	<div id="header" th:fragment="headerFragment">
		head.html<br>
		상단메뉴<br>
		<a href="#">01회원가입</a>
		<a href="#">02회원목록</a>
		<a href="#">03상품등록</a>
		<a href="#">04상품목록</a>
	</div>
	
</html>

- leftmenu 부분 작성

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
	<div id="leftcolumn" th:fragment="leftmenuFragment">
		left.html <br><br>
		왼쪽메뉴
	</div>
</html>

- footer 부분 작성

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
	<div id="footer" th:fragment="footerFragment">
		footer.html<br>
		하단메뉴<br>
		063-717-1008-ksmart.or.kr 한국스마트정보교육원
		
	</div>
	
</html>

- contents 부분 작성

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
	  xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
	  layout:decorate="~{layout/default}">
	
	<!-- 사용자 정의 css -->
	<th:block layout:fragment="customCss">
	
	</th:block>

	<!-- 사용자 정의 js -->
	<th:block layout:fragment="customJs">
		<script src="http://code.jquery.com/jquery-latest.min.js"></script>
	</th:block>
	
	<!-- 사용자 정의 contents -->
	<th:block layout:fragment="customContents">
		<!-- $ : 모델의 값을 바인딩하는 구문 -->
		<!-- ${key} : 태그의 속성에서 값을 바인딩하는 구문 -->
		<h1 th:text="${title}"></h1>
		<!-- [[${key}]] : 인라인 스타일 -->
		[[${title}]]
		[[${member}]]
	</th:block>
</body>
</html>

 

- 통합 default 부분 작성

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
	  xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head th:replace="fragments/head :: headFragment"></head>
<body>
	<div id="wrapper">
		<div th:replace="fragments/header :: headerFragment"></div>
		<div th:replace="fragments/leftmenu :: leftmenuFragment"></div>
		<div id="rightcolumn">
			<!-- 사용자 정의 contents -->
			<th:block layout:fragment="customContents"></th:block>
		</div>
		<div th:replace="fragments/footer :: footerFragment"></div>
		
	</div>
</body>
</html>

- 확인

'springboot' 카테고리의 다른 글

VSCode에서 SpringBoot 사용하기  (1) 2023.05.23
Spring-Boot 환경설정  (0) 2023.05.15
thymeleaf(타임리프)  (0) 2023.05.15
Spring - Maven  (0) 2023.05.15
스프링부트(Spring Boot), Spring MVC  (0) 2023.05.15

+ Recent posts