By a3040, Published on Invalid Date
display: inline-block; /* 또는 display: inline-flex; */
By a3040, Published on Invalid Date
유사배열은 실제 배열은 아니지만 배열과 유사한 동작을 하는 객체를 나타냅니다.
유사배열 객체는 다음 특징을 가집니다:
1.인덱스를 사용하여 요소에 접근할 수 있어야합니다.
2.length 속성을 가지고 있어서 요소의 개수를 알 수 있어야합니다.
3.반복 가능(iterable)하므로 for...of 루프나 forEach와 같은 반복 메서드를 사용할 수 있습니다.
4.Array객체가 아니어서 .map등 사용이 안됩니다. Array 객체로 변환 후 사용해야합니다.
대표적 예시 : 문자열(String), 함수 인자(arguments), NodeList, TypedArray
//문자열(String): //문자열은 각 문자에 대한 인덱스로 접근할 수 있으며 length 속성이 있습니다.
const str = "Hello";
console.log(str[0]); // "H"
console.log(str.length); // 5
//arguments는 함수라면 처음부터 갖고 있는 숨겨진 속성입니다.
function example() {
console.log(arguments[0]);// 1
console.log(arguments.length);// 3
}
example(1, 2, 3);
const elements = document.querySelectorAll("div");
console.log(elements[0]); // 첫 번째 div 요소
console.log(elements.length); // 요소의 개수
//TypedArray: Uint8Array, Int32Array와 같은 TypedArray 객체도 유사 배열입니다.
const uint8Array = new Uint8Array([1, 2, 3]);
console.log(uint8Array[0]); // 1
console.log(uint8Array.length); // 3
제너레이터(generator) 객체는 유사 배열이 아닙니다.
제너레이터 객체는 반복 가능한(iterable) 객체로, next() 메서드를 사용하여 값을 순차적으로 생성하고 반환하는 객체입니다.
function* gen(from=0, to=10, step=1){
for( let i=from; i<to; i+=step)
yield i;
}
const x = gen();
try{
console.log( x.join(',') )
}catch(e){
console.error('gen은 generator객체여서 join안됨', e);
}
console.log( x[3] ); //undefined , next()로 접근
console.log(Array.prototype.join.call([...x], '|'));
By a3040, Published on Invalid Date
1.생성되는 js 특정 위치에 놓기
vite -rollup설정 추가
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
// https://vitejs.dev/config/
export default defineConfig({
build:{
rollupOptions:{
input : "./src/main.tsx",
output:{
dir:"../../back/src/main/resources/static/js/admin", /*출력 디렉토리*/
entryFileNames:"dashboard.js", /*만들 js */
}
},
},
plugins: [react()],
})
2.tailwindcss를 통해 성성된 css파일 위치 및 파일명 고정
export default defineConfig({
build:{
rollupOptions:{
input : "./src/main.tsx",
output:{
assetFileNames: (chunkInfo) => {
if (chunkInfo.name === 'main.css') /*임시로 만들어 지는 파일명*/
return 'index.css' /* 새로 만들 원하는 고정 파일명 */
},
dir:"../../back/src/main/resources/static/js/admin", /*출력 디렉토리*/
entryFileNames:"dashboard.js", /*만들 js */
}
},
},
plugins: [react()],
})
css설정 전 임의의 파일 생성
css설정 후 고정 파일 생성
3.고정파일에서 페이지 설정
board.html
<!doctype html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<title>admin-dashboard</title>
<link rel="stylesheet" href="/js/admin/index.css">
</head>
<body>
<div id="root"></div>
<script type="module" src="/js/admin/dashboard.js"></script>
</body>
</html>
package.json
"scripts": {
"dev": "vite",
"build": "tsc && vite build --watch",
By a3040, Published on Invalid Date
Multer란?
파일 업로드를 위해 사용되는 multipart/form-data 를 다루기 위한 node.js 의 미들웨어 입니다. 효율성을 최대화 하기 위해 busboy 를 기반으로 하고 있습니다.
설치
$ npm install --save multer
파일 전송 쪽 단일 파일 //react, axios, react-dropzone 예시
const UploadApp = () => {
const onDrop = async (acceptedFiles) => {
const formData = new FormData();
formData.append('file', acceptedFiles[0]);
try {
const response = await axios.post('http://localhost:3000/upload', formData, {
headers: {
'Content-Type': 'multipart/form-data',
},
});
if (response.status === 200) {
console.log('File uploaded successfully.');
} else {
console.error('File upload failed.');
}
} catch (error) {
console.error('Error uploading file:', error);
}
};
const { getRootProps, getInputProps } = useDropzone({ onDrop });
return (
<div {...getRootProps()} style={{ border: '2px dashed #ccc', padding: '20px', textAlign: 'center' }}>
<input {...getInputProps()} />
<p>Drag & drop a file here, or click to select a file</p>
</div>
);
};
export default UploadApp;
서버쪽 Multer : multipart/form-data 데이터 처리
./up.js <-- url 처리 및 전송데이터 처리용 express코드
./uploads <-- 첨부파일 저장 위치
import express from 'express';
import multer from 'multer';
import path from 'path';
import cors from 'cors'; // CORS 미들웨어 추가
const app = express();
const port = 3000;
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, 'uploads/'); // 파일 저장 경로 설정
},
filename: (req, file, cb) => {
const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1e9);
const fileExtension = path.extname(file.originalname);
cb(null, file.fieldname + '-' + uniqueSuffix + fileExtension); // 파일 이름 설정
},
});
const upload = multer({ storage });
app.use(cors({
origin: 'http://localhost:5173', // 클라이언트 주소
}));
app.use(express.static('public'));
app.use('/uploads', express.static('uploads'));
app.post('/upload', upload.single('file'), (req, res) => {
console.log('request start....')
res.status(200).json({ message: 'File uploaded successfully.' });
});
app.get('/alive',(req, res) => {
res.status(200).json({ message: 'server alive.' });
});
app.listen(port, () => {
console.log(`Server is running on port ${port}`);
});
cors 미들웨어는 react실행하는 쪽 에서 axios 전송 요청시 에러가 발생해서 추가핬습니다.
실행 및 테스트
>node ./up.js
multer/doc/README-ko.md at master · expressjs/multer (github.com)
By a3040, Published on Invalid Date
<div className="sticky top-0 bg-blue-400 p-5 drop-shadow shadow-blue-600">
<h1 className="text-white text-4xl text-center">sticky top-0</h1>
</div>
sticky, top-0 속성을 이용해서 고정할수 있습니다. position: sticky;
"sticky": 이 클래스는 요소를 화면에서 고정시키는 데 사용됩니다. top: 0px;
"top-0": 이 클래스는 요소를 부모 요소의 상단에 고정시키는 데 사용됩니다.