๐Ÿš€ Blazor๋กœ ์›น ์•ฑ ๊ฐœ๋ฐœํ•˜๊ธฐ: ์ดˆ๋ณด์ž๋„ ์‰ฝ๊ฒŒ ๋”ฐ๋ผํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ€์ด๋“œ! ๐ŸŽจ

์ฝ˜ํ…์ธ  ๋Œ€ํ‘œ ์ด๋ฏธ์ง€ - ๐Ÿš€ Blazor๋กœ ์›น ์•ฑ ๊ฐœ๋ฐœํ•˜๊ธฐ: ์ดˆ๋ณด์ž๋„ ์‰ฝ๊ฒŒ ๋”ฐ๋ผํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ€์ด๋“œ! ๐ŸŽจ

 

 

์•ˆ๋…•, ์นœ๊ตฌ๋“ค! ์˜ค๋Š˜์€ ์ •๋ง ์‹ ๋‚˜๋Š” ์ฃผ์ œ๋กœ ์ฐพ์•„์™”์–ด. ๋ฐ”๋กœ Blazor๋ฅผ ์ด์šฉํ•œ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ฐœ๋ฐœ์— ๋Œ€ํ•ด ์–˜๊ธฐํ•ด๋ณผ ๊ฑฐ์•ผ. ๐Ÿ˜Ž C# ๊ฐœ๋ฐœ์ž๋“ค์—๊ฒŒ๋Š” ์ •๋ง ๊ฟ€ ๊ฐ™์€ ์†Œ์‹์ด์ง€? ์›น ๊ฐœ๋ฐœ์„ ์œ„ํ•ด JavaScript๋ฅผ ๋ฐฐ์šฐ์ง€ ์•Š์•„๋„ ๋œ๋‹ค๋‹ˆ, ์–ผ๋งˆ๋‚˜ ์ข‹์•„!

์šฐ๋ฆฌ๊ฐ€ ์˜ค๋Š˜ ๋‹ค๋ฃฐ ๋‚ด์šฉ์€ ์žฌ๋Šฅ๋„ท(https://www.jaenung.net)์˜ '์ง€์‹์ธ์˜ ์ˆฒ' ๋ฉ”๋‰ด์—๋„ ๋“ฑ๋ก๋  ์˜ˆ์ •์ด์•ผ. ์žฌ๋Šฅ๋„ท์€ ๋‹ค์–‘ํ•œ ์žฌ๋Šฅ์„ ๊ฑฐ๋ž˜ํ•˜๋Š” ํ”Œ๋žซํผ์ธ๋ฐ, ์—ฌ๊ธฐ์„œ ์šฐ๋ฆฌ๊ฐ€ ๋ฐฐ์šธ Blazor ๊ธฐ์ˆ ๋„ ์ถฉ๋ถ„ํžˆ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์„ ๊ฑฐ์•ผ. ์˜ˆ๋ฅผ ๋“ค์–ด, Blazor๋กœ ๋งŒ๋“  ์›น ์•ฑ์„ ํ†ตํ•ด ์ž์‹ ์˜ ์žฌ๋Šฅ์„ ๋” ํšจ๊ณผ์ ์œผ๋กœ ๋ณด์—ฌ์ค„ ์ˆ˜ ์žˆ๊ฒ ์ง€? ๐ŸŒŸ

์ž, ์ด์ œ ๋ณธ๊ฒฉ์ ์œผ๋กœ Blazor์˜ ์„ธ๊ณ„๋กœ ๋›ฐ์–ด๋“ค์–ด๋ณผ๊นŒ? ์ค€๋น„๋์–ด? ๊ทธ๋Ÿผ ์ถœ๋ฐœ~! ๐Ÿ

๐Ÿค” Blazor๊ฐ€ ๋ญ๊ธธ๋ž˜? ์ดˆ๋ณด์ž๋„ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋Š” ์„ค๋ช…!

Blazor? ์ฒ˜์Œ ๋“ค์–ด๋ณด๋Š” ์นœ๊ตฌ๋“ค๋„ ์žˆ์„ ๊ฑฐ์•ผ. ๊ฑฑ์ • ๋งˆ, ์ง€๊ธˆ๋ถ€ํ„ฐ ์ฐจ๊ทผ์ฐจ๊ทผ ์„ค๋ช…ํ•ด์ค„๊ฒŒ.

Blazor๋ž€? Microsoft์—์„œ ๋งŒ๋“  ์›น ํ”„๋ ˆ์ž„์›Œํฌ๋กœ, C#์„ ์‚ฌ์šฉํ•ด ๋Œ€ํ™”ํ˜• ์›น UI๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ๋…€์„์ด์•ผ.

์‰ฝ๊ฒŒ ๋งํ•ด์„œ, JavaScript ๋Œ€์‹  C#์œผ๋กœ ์›น ํŽ˜์ด์ง€๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฑฐ์ง€. ๐Ÿ˜ฎ ์‹ ๊ธฐํ•˜์ง€ ์•Š์•„?

Blazor์˜ ํŠน์ง•์„ ๊ฐ„๋‹จํžˆ ์ •๋ฆฌํ•ด๋ณผ๊ฒŒ:

  • C#์œผ๋กœ ํ”„๋ก ํŠธ์—”๋“œ์™€ ๋ฐฑ์—”๋“œ๋ฅผ ๋ชจ๋‘ ๊ฐœ๋ฐœํ•  ์ˆ˜ ์žˆ์–ด.
  • ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์›น UI ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์–ด.
  • .NET ์ƒํƒœ๊ณ„์˜ ๋ชจ๋“  ์žฅ์ ์„ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์ง€.
  • ์„ฑ๋Šฅ์ด ๋›ฐ์–ด๋‚˜๊ณ  ๋ฐฐ์šฐ๊ธฐ ์‰ฌ์›Œ.

์žฌ๋Šฅ๋„ท ๊ฐ™์€ ํ”Œ๋žซํผ์—์„œ Blazor๋ฅผ ํ™œ์šฉํ•˜๋ฉด ์–ด๋–จ๊นŒ? ์˜ˆ๋ฅผ ๋“ค์–ด, ์‹ค์‹œ๊ฐ„์œผ๋กœ ์—…๋ฐ์ดํŠธ๋˜๋Š” ์žฌ๋Šฅ ๊ฑฐ๋ž˜ ํ˜„ํ™ฉ ๋Œ€์‹œ๋ณด๋“œ๋‚˜, ์‚ฌ์šฉ์ž ๋งž์ถคํ˜• ์žฌ๋Šฅ ์ถ”์ฒœ ์‹œ์Šคํ…œ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์„ ๊ฑฐ์•ผ. C#์˜ ๊ฐ•๋ ฅํ•œ ๊ธฐ๋Šฅ๊ณผ Blazor์˜ ์œ ์—ฐ์„ฑ์„ ๊ฒฐํ•ฉํ•˜๋ฉด ์ •๋ง ๋ฉ‹์ง„ ์›น ์•ฑ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์„ ๊ฑฐ์•ผ! ๐Ÿš€

Blazor์˜ ๊ตฌ์กฐ Blazor C# .NET WebAssembly HTML CSS JavaScript

์œ„์˜ ๊ทธ๋ฆผ์„ ๋ณด๋ฉด Blazor๊ฐ€ ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ•˜๋Š”์ง€ ๋Œ€๋žต์ ์œผ๋กœ ์ดํ•ดํ•  ์ˆ˜ ์žˆ์„ ๊ฑฐ์•ผ. C#, .NET, WebAssembly๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜๊ณ  ์žˆ๊ณ , ์ตœ์ข…์ ์œผ๋กœ HTML, CSS, JavaScript์™€ ์—ฐ๊ฒฐ๋˜๋Š” ๊ตฌ์กฐ์•ผ. ์ด๋Ÿฐ ๊ตฌ์กฐ ๋•๋ถ„์— C# ๊ฐœ๋ฐœ์ž๋“ค์ด ์›น ๊ฐœ๋ฐœ์„ ๋” ์‰ฝ๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฑฐ์ง€.

Blazor๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ’€์Šคํƒ ๊ฐœ๋ฐœ์ด ํ•œ๊ฒฐ ์ˆ˜์›”ํ•ด์ ธ. ๋ฐฑ์—”๋“œ์™€ ํ”„๋ก ํŠธ์—”๋“œ๋ฅผ ๋ชจ๋‘ C#์œผ๋กœ ๊ฐœ๋ฐœํ•  ์ˆ˜ ์žˆ์œผ๋‹ˆ๊นŒ ๋ง์ด์•ผ. ์ด๊ฒŒ ๋ฐ”๋กœ Blazor์˜ ๊ฐ€์žฅ ํฐ ๋งค๋ ฅ ์ค‘ ํ•˜๋‚˜๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ์–ด.

์ž, ์ด์ œ Blazor๊ฐ€ ๋ญ”์ง€ ๋Œ€์ถฉ ๊ฐ์ด ์™”์ง€? ๊ทธ๋Ÿผ ์ด์ œ ๋ณธ๊ฒฉ์ ์œผ๋กœ Blazor๋กœ ์›น ์•ฑ์„ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ์•„๋ณผ๊นŒ? ๐Ÿ˜ƒ

๐Ÿ› ๏ธ Blazor ๊ฐœ๋ฐœ ํ™˜๊ฒฝ ์„ค์ •ํ•˜๊ธฐ: ์ฒซ ๊ฑธ์Œ๋ถ€ํ„ฐ ํ•จ๊ป˜!

์ž, ์ด์ œ Blazor๋กœ ๊ฐœ๋ฐœ์„ ์‹œ์ž‘ํ•ด๋ณผ๊นŒ? ๋จผ์ € ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์„ ์„ค์ •ํ•ด์•ผ ํ•ด. ๊ฑฑ์ • ๋งˆ, ์–ด๋ ต์ง€ ์•Š์•„! ํ•จ๊ป˜ ์ฒœ์ฒœํžˆ ๋”ฐ๋ผ์™€ ๋ณด์ž.

1. .NET SDK ์„ค์น˜ํ•˜๊ธฐ

Blazor๋Š” .NET์˜ ์ผ๋ถ€์ด๊ธฐ ๋•Œ๋ฌธ์—, ๋จผ์ € .NET SDK๋ฅผ ์„ค์น˜ํ•ด์•ผ ํ•ด. ์ตœ์‹  ๋ฒ„์ „์„ Microsoft ๊ณต์‹ ์›น์‚ฌ์ดํŠธ์—์„œ ๋‹ค์šด๋กœ๋“œ๋ฐ›์•„ ์„ค์น˜ํ•˜๋ฉด ๋ผ.

ํŒ: ํ•ญ์ƒ ์ตœ์‹  ๋ฒ„์ „์˜ .NET SDK๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์•„. ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ๊ณผ ์„ฑ๋Šฅ ๊ฐœ์„ , ๋ณด์•ˆ ์—…๋ฐ์ดํŠธ๋ฅผ ๋ฐ›์„ ์ˆ˜ ์žˆ๊ฑฐ๋“ !

2. Visual Studio ๋˜๋Š” Visual Studio Code ์„ค์น˜ํ•˜๊ธฐ

Blazor ๊ฐœ๋ฐœ์„ ์œ„ํ•œ IDE(ํ†ตํ•ฉ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ)๊ฐ€ ํ•„์š”ํ•ด. Microsoft์—์„œ ์ œ๊ณตํ•˜๋Š” Visual Studio๋‚˜ Visual Studio Code๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ผ. ๋‘˜ ๋‹ค ๋ฌด๋ฃŒ ๋ฒ„์ „์ด ์žˆ์–ด!

  • Visual Studio: ํ’€ ๊ธฐ๋Šฅ์„ ๊ฐ–์ถ˜ IDE๋กœ, ๋Œ€๊ทœ๋ชจ ํ”„๋กœ์ ํŠธ์— ์ ํ•ฉํ•ด.
  • Visual Studio Code: ๊ฐ€๋ณ๊ณ  ๋น ๋ฅธ ์ฝ”๋“œ ์—๋””ํ„ฐ๋กœ, ํ™•์žฅ ๊ธฐ๋Šฅ์„ ํ†ตํ•ด Blazor ๊ฐœ๋ฐœ์— ์ตœ์ ํ™”ํ•  ์ˆ˜ ์žˆ์–ด.

์žฌ๋Šฅ๋„ท์—์„œ ์ผํ•˜๋Š” ๊ฐœ๋ฐœ์ž๋ผ๋ฉด ์–ด๋–ค ๊ฑธ ์„ ํƒํ•˜๋Š” ๊ฒŒ ์ข‹์„๊นŒ? ์Œ... ํ”„๋กœ์ ํŠธ์˜ ๊ทœ๋ชจ์™€ ํŒ€์˜ ์„ ํ˜ธ๋„์— ๋”ฐ๋ผ ๋‹ค๋ฅด๊ฒ ์ง€๋งŒ, ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ Visual Studio๋ฅผ ์ถ”์ฒœํ•ด. ๋””๋ฒ„๊น… ๋„๊ตฌ์™€ ํŒ€ ํ˜‘์—… ๊ธฐ๋Šฅ์ด ๋›ฐ์–ด๋‚˜๊ฑฐ๋“ .

3. Blazor ํ”„๋กœ์ ํŠธ ํ…œํ”Œ๋ฆฟ ์„ค์น˜ํ•˜๊ธฐ

์ด์ œ Blazor ํ”„๋กœ์ ํŠธ๋ฅผ ์‰ฝ๊ฒŒ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ…œํ”Œ๋ฆฟ์„ ์„ค์น˜ํ•ด๋ณด์ž. ๋ช…๋ น ํ”„๋กฌํ”„ํŠธ(CMD)๋‚˜ PowerShell์„ ์—ด๊ณ  ๋‹ค์Œ ๋ช…๋ น์–ด๋ฅผ ์ž…๋ ฅํ•ด:

dotnet new --install Microsoft.AspNetCore.Components.WebAssembly.Templates

์ด ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜๋ฉด Blazor WebAssembly ํ”„๋กœ์ ํŠธ ํ…œํ”Œ๋ฆฟ์ด ์„ค์น˜๋ผ.

4. ์ฒซ Blazor ํ”„๋กœ์ ํŠธ ๋งŒ๋“ค๊ธฐ

์ž, ์ด์ œ ๋ชจ๋“  ์ค€๋น„๊ฐ€ ๋๋‚ฌ์–ด! ์ฒซ Blazor ํ”„๋กœ์ ํŠธ๋ฅผ ๋งŒ๋“ค์–ด๋ณผ๊นŒ? ๋‹ค์Œ ๋ช…๋ น์–ด๋ฅผ ์ž…๋ ฅํ•ด๋ด:

dotnet new blazorwasm -o MyFirstBlazorApp

์ด ๋ช…๋ น์–ด๋Š” 'MyFirstBlazorApp'์ด๋ผ๋Š” ์ด๋ฆ„์˜ ์ƒˆ Blazor WebAssembly ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•ด.

์ถ•ํ•˜ํ•ด! ๐ŸŽ‰ ์ด์ œ ๋„ˆ์˜ ์ฒซ Blazor ํ”„๋กœ์ ํŠธ๊ฐ€ ์ƒ์„ฑ๋์–ด. Visual Studio๋‚˜ VS Code๋กœ ์ด ํ”„๋กœ์ ํŠธ๋ฅผ ์—ด์–ด์„œ ์‚ดํŽด๋ณด๋ฉด, ๊ธฐ๋ณธ์ ์ธ ๊ตฌ์กฐ์™€ ๋ช‡ ๊ฐ€์ง€ ์˜ˆ์ œ ํŽ˜์ด์ง€๋“ค์ด ์ด๋ฏธ ๋งŒ๋“ค์–ด์ ธ ์žˆ๋Š” ๊ฑธ ๋ณผ ์ˆ˜ ์žˆ์„ ๊ฑฐ์•ผ.

Blazor ๊ฐœ๋ฐœ ํ™˜๊ฒฝ ์„ค์ • ๊ณผ์ • .NET SDK ์„ค์น˜ IDE ์„ค์น˜ ํ…œํ”Œ๋ฆฟ ์„ค์น˜ ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ Blazor ๊ฐœ๋ฐœ ์‹œ์ž‘!

์œ„ ๊ทธ๋ฆผ์€ Blazor ๊ฐœ๋ฐœ ํ™˜๊ฒฝ ์„ค์ • ๊ณผ์ •์„ ๋ณด์—ฌ์ฃผ๊ณ  ์žˆ์–ด. ๊ฐ ๋‹จ๊ณ„๋ฅผ ์ฐจ๊ทผ์ฐจ๊ทผ ๋”ฐ๋ผ๊ฐ€๋‹ค ๋ณด๋ฉด ์–ด๋Š์ƒˆ Blazor ๊ฐœ๋ฐœ์„ ์‹œ์ž‘ํ•  ์ค€๋น„๊ฐ€ ์™„๋ฃŒ๋˜๋Š” ๊ฑฐ์ง€!

์ž, ์ด์ œ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ ์„ค์ •์€ ๋๋‚ฌ์–ด. ์–ด๋•Œ, ์ƒ๊ฐ๋ณด๋‹ค ์‰ฝ์ง€? ๐Ÿ™‚ ์ด์ œ ๋ณธ๊ฒฉ์ ์œผ๋กœ Blazor๋กœ ์›น ์•ฑ์„ ๋งŒ๋“ค์–ด๋ณผ ์ค€๋น„๊ฐ€ ๋์–ด! ๋‹ค์Œ ์„น์…˜์—์„œ๋Š” Blazor์˜ ๊ธฐ๋ณธ ๊ตฌ์กฐ์™€ ์ฃผ์š” ๊ฐœ๋…๋“ค์— ๋Œ€ํ•ด ์•Œ์•„๋ณผ ๊ฑฐ์•ผ. ์žฌ๋Šฅ๋„ท์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ฉ‹์ง„ ์›น ์•ฑ์„ ๋งŒ๋“ค ์ƒ๊ฐ์„ ํ•˜๋‹ˆ ๋ฒŒ์จ๋ถ€ํ„ฐ ์‹ ๋‚˜์ง€ ์•Š์•„? ๐Ÿ˜„ ๊ณ„์† ๋”ฐ๋ผ์™€ ๋ด!

๐Ÿงฑ Blazor์˜ ๊ธฐ๋ณธ ๊ตฌ์กฐ์™€ ์ฃผ์š” ๊ฐœ๋…: ์‰ฝ๊ฒŒ ์ดํ•ดํ•˜๊ธฐ

์ž, ์ด์ œ Blazor์˜ ๊ธฐ๋ณธ ๊ตฌ์กฐ์™€ ์ฃผ์š” ๊ฐœ๋…๋“ค์— ๋Œ€ํ•ด ์•Œ์•„๋ณผ ๊ฑฐ์•ผ. ์ฒ˜์Œ์—๋Š” ์ข€ ๋ณต์žกํ•ด ๋ณด์ผ ์ˆ˜ ์žˆ์ง€๋งŒ, ์ฒœ์ฒœํžˆ ๋”ฐ๋ผ์˜ค๋‹ค ๋ณด๋ฉด ๊ธˆ๋ฐฉ ์ดํ•ดํ•  ์ˆ˜ ์žˆ์„ ๊ฑฐ์•ผ. ์ค€๋น„๋์–ด? ๊ทธ๋Ÿผ ์‹œ์ž‘ํ•ด๋ณผ๊นŒ! ๐Ÿš€

1. Blazor ์ปดํฌ๋„ŒํŠธ (Components)

Blazor์˜ ํ•ต์‹ฌ์€ ๋ฐ”๋กœ ์ปดํฌ๋„ŒํŠธ์•ผ. ์ปดํฌ๋„ŒํŠธ๋Š” UI์˜ ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์กฐ๊ฐ์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋ผ. ์˜ˆ๋ฅผ ๋“ค์–ด, ์žฌ๋Šฅ๋„ท์˜ '์žฌ๋Šฅ ์นด๋“œ'๋‚˜ '์‚ฌ์šฉ์ž ํ”„๋กœํ•„' ๊ฐ™์€ ๊ฒƒ๋“ค์ด ๊ฐ๊ฐ ํ•˜๋‚˜์˜ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋  ์ˆ˜ ์žˆ์–ด.

Blazor ์ปดํฌ๋„ŒํŠธ๋Š” .razor ํ™•์žฅ์ž๋ฅผ ๊ฐ€์ง„ ํŒŒ์ผ๋กœ ๋งŒ๋“ค์–ด์ ธ. ์ด ํŒŒ์ผ ์•ˆ์—๋Š” HTML, C# ์ฝ”๋“œ, ๊ทธ๋ฆฌ๊ณ  ํ•„์š”ํ•˜๋‹ค๋ฉด CSS๊นŒ์ง€ ๋ชจ๋‘ ํฌํ•จ๋  ์ˆ˜ ์žˆ์–ด. ์˜ˆ๋ฅผ ๋“ค์–ด๋ณผ๊นŒ?

@* TalentCard.razor *@
<div class="talent-card">
    <h3>@Title</h3>
    <p>@Description</p>
    <button>์ง€๊ธˆ ์˜ˆ์•ฝํ•˜๊ธฐ</button>
</div>

@code {
    [Parameter]
    public string Title { get; set; }

    [Parameter]
    public string Description { get; set; }

    private void OnBookNow()
    {
        // ์˜ˆ์•ฝ ๋กœ์ง
    }
}

์ด๋Ÿฐ ์‹์œผ๋กœ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์–ด. ์žฌ๋Šฅ๋„ท์—์„œ ์ด๋Ÿฐ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด, ๋‹ค์–‘ํ•œ ์žฌ๋Šฅ๋“ค์„ ์ผ๊ด€๋œ ๋””์ž์ธ์œผ๋กœ ์‰ฝ๊ฒŒ ํ‘œ์‹œํ•  ์ˆ˜ ์žˆ๊ฒ ์ง€?

2. Razor ๊ตฌ๋ฌธ

Blazor๋Š” Razor๋ผ๋Š” ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•ด. Razor๋Š” HTML ์•ˆ์— C# ์ฝ”๋“œ๋ฅผ ์„ž์–ด ์“ธ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ํŠน๋ณ„ํ•œ ๊ตฌ๋ฌธ์ด์•ผ. @๊ธฐํ˜ธ๋ฅผ ์‚ฌ์šฉํ•ด์„œ C# ์ฝ”๋“œ๋ฅผ ์‚ฝ์ž…ํ•  ์ˆ˜ ์žˆ์–ด.

์˜ˆ๋ฅผ ๋“ค์–ด:

<h1>@username๋‹˜, ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค!</h1>
@if (isLoggedIn)
{
    <p>๋กœ๊ทธ์ธ ์ƒํƒœ์ž…๋‹ˆ๋‹ค.</p>
}
else
{
    <p>๋กœ๊ทธ์ธ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.</p>
}

์ด๋Ÿฐ ์‹์œผ๋กœ ๋™์ ์ธ ์ฝ˜ํ…์ธ ๋ฅผ ์‰ฝ๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ์–ด. ์žฌ๋Šฅ๋„ท์—์„œ ์‚ฌ์šฉ์ž ๋งž์ถคํ˜• ํŽ˜์ด์ง€๋ฅผ ๋งŒ๋“ค ๋•Œ ์ด๋Ÿฐ ๊ธฐ๋Šฅ์ด ๋งค์šฐ ์œ ์šฉํ•  ๊ฑฐ์•ผ.

3. ๋ฐ์ดํ„ฐ ๋ฐ”์ธ๋”ฉ

Blazor์—์„œ๋Š” ๋ฐ์ดํ„ฐ ๋ฐ”์ธ๋”ฉ์„ ํ†ตํ•ด UI์™€ ๋ฐ์ดํ„ฐ๋ฅผ ์‰ฝ๊ฒŒ ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ์–ด. ๋‹จ๋ฐฉํ–ฅ ๋ฐ”์ธ๋”ฉ๊ณผ ์–‘๋ฐฉํ–ฅ ๋ฐ”์ธ๋”ฉ ๋ชจ๋‘ ์ง€์›ํ•ด.

  • ๋‹จ๋ฐฉํ–ฅ ๋ฐ”์ธ๋”ฉ: @๋กœ ํ‘œํ˜„
  • ์–‘๋ฐฉํ–ฅ ๋ฐ”์ธ๋”ฉ: @bind ์†์„ฑ ์‚ฌ์šฉ

์˜ˆ๋ฅผ ๋“ค์–ด๋ณผ๊นŒ?

<input>
<p>๊ฒ€์ƒ‰์–ด: @searchTerm</p>

@code {
    private string searchTerm;
}

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์ž…๋ ฅ ํ•„๋“œ์˜ ๊ฐ’์ด ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค searchTerm ๋ณ€์ˆ˜๊ฐ€ ์ž๋™์œผ๋กœ ์—…๋ฐ์ดํŠธ๋ผ. ์žฌ๋Šฅ๋„ท์—์„œ ์‹ค์‹œ๊ฐ„ ๊ฒ€์ƒ‰ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•  ๋•Œ ์ด๋Ÿฐ ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์„ ๊ฑฐ์•ผ.

4. ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ

Blazor์—์„œ๋Š” @on{์ด๋ฒคํŠธ์ด๋ฆ„} ํ˜•์‹์œผ๋กœ ์ด๋ฒคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด. ์˜ˆ๋ฅผ ๋“ค๋ฉด:

<button>ํด๋ฆญํ•˜์„ธ์š”</button>

@code {
    private void HandleClick()
    {
        // ํด๋ฆญ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ ๋กœ์ง
    }
}

์ด๋Ÿฐ ์‹์œผ๋กœ ๋ฒ„ํŠผ ํด๋ฆญ, ํผ ์ œ์ถœ ๋“ฑ์˜ ์ด๋ฒคํŠธ๋ฅผ ์‰ฝ๊ฒŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด. ์žฌ๋Šฅ๋„ท์—์„œ '์žฌ๋Šฅ ๋“ฑ๋ก' ๋ฒ„ํŠผ์ด๋‚˜ '๋ฆฌ๋ทฐ ์ž‘์„ฑ' ํผ ๊ฐ™์€ ๊ณณ์— ์ด๋Ÿฐ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒ ์ง€?

5. ๋ผ์šฐํŒ…

Blazor๋Š” ๋‚ด์žฅ ๋ผ์šฐํŒ… ์‹œ์Šคํ…œ์„ ์ œ๊ณตํ•ด. ์ด๋ฅผ ํ†ตํ•ด ๋‹จ์ผ ํŽ˜์ด์ง€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜(SPA)์„ ์‰ฝ๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ์–ด.

@page "/talent/{id:int}"

<h1>์žฌ๋Šฅ ์ƒ์„ธ ์ •๋ณด</h1>
<p>์žฌ๋Šฅ ID: @Id</p>

@code {
    [Parameter]
    public int Id { get; set; }
}

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด "/talent/123"๊ณผ ๊ฐ™์€ URL๋กœ ํŠน์ • ์žฌ๋Šฅ์˜ ์ƒ์„ธ ํŽ˜์ด์ง€์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์–ด. ์žฌ๋Šฅ๋„ท์˜ ๊ฐ ์žฌ๋Šฅ๋ณ„ ์ƒ์„ธ ํŽ˜์ด์ง€๋ฅผ ์ด๋Ÿฐ ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๊ฒ ์ง€?

Blazor์˜ ์ฃผ์š” ๊ฐœ๋… Blazor ์ปดํฌ๋„ŒํŠธ Razor ๊ตฌ๋ฌธ ๋ฐ์ดํ„ฐ ๋ฐ”์ธ๋”ฉ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ ๋ผ์šฐํŒ…

์œ„ ๊ทธ๋ฆผ์€ ์šฐ๋ฆฌ๊ฐ€ ์ง€๊ธˆ๊นŒ์ง€ ๋ฐฐ์šด Blazor์˜ ์ฃผ์š” ๊ฐœ๋…๋“ค์„ ๋ณด์—ฌ์ฃผ๊ณ  ์žˆ์–ด. ์ด ๋ชจ๋“  ๊ฐœ๋…๋“ค์ด ์–ด์šฐ๋Ÿฌ์ ธ ๊ฐ•๋ ฅํ•œ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ๊ฑฐ์ง€.

์ด ๋ชจ๋“  ๊ฐœ๋…๋“ค์„ ์ž˜ ํ™œ์šฉํ•˜๋ฉด, ์žฌ๋Šฅ๋„ท ๊ฐ™์€ ๋ณต์žกํ•œ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๋„ ํšจ์œจ์ ์œผ๋กœ ๊ฐœ๋ฐœํ•  ์ˆ˜ ์žˆ์–ด. ์˜ˆ๋ฅผ ๋“ค์–ด, ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ด์šฉํ•ด ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ UI ์š”์†Œ๋“ค์„ ๋งŒ๋“ค๊ณ , Razor ๊ตฌ๋ฌธ์œผ๋กœ ๋™์  ์ฝ˜ํ…์ธ ๋ฅผ ์ƒ์„ฑํ•˜๊ณ , ๋ฐ์ดํ„ฐ ๋ฐ”์ธ๋”ฉ์œผ๋กœ ์‹ค์‹œ๊ฐ„ ์—…๋ฐ์ดํŠธ๋ฅผ ๊ตฌํ˜„ํ•˜๊ณ , ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ๋กœ ์‚ฌ์šฉ์ž ์ƒํ˜ธ์ž‘์šฉ์„ ๊ด€๋ฆฌํ•˜๊ณ , ๋ผ์šฐํŒ…์œผ๋กœ ๋‹ค์–‘ํ•œ ํŽ˜์ด์ง€๋ฅผ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์ง€.

์–ด๋•Œ, Blazor์˜ ๊ธฐ๋ณธ ๊ตฌ์กฐ์™€ ์ฃผ์š” ๊ฐœ๋…๋“ค์ด ์ดํ•ด๊ฐ€ ๋์–ด? ์ฒ˜์Œ์—๋Š” ์ข€ ๋ณต์žกํ•ด ๋ณด์ผ ์ˆ˜ ์žˆ์ง€๋งŒ, ์‹ค์ œ๋กœ ์‚ฌ์šฉํ•ด๋ณด๋ฉด ์ •๋ง ์ง๊ด€์ ์ด๊ณ  ๊ฐ•๋ ฅํ•˜๋‹ค๋Š” ๊ฑธ ๋Š๋‚„ ์ˆ˜ ์žˆ์„ ๊ฑฐ์•ผ. ๋‹ค์Œ ์„น์…˜์—์„œ๋Š” ์ด๋Ÿฐ ๊ฐœ๋…๋“ค์„ ์‹ค์ œ๋กœ ์–ด๋–ป๊ฒŒ ํ™œ์šฉํ•˜๋Š”์ง€ ๋” ์ž์„ธํžˆ ์•Œ์•„๋ณผ ๊ฑฐ์•ผ. ๊ณ„์† ๋”ฐ๋ผ์™€ ์ค˜! ๐Ÿ˜Š

๐Ÿ—๏ธ Blazor๋กœ ์ฒซ ์›น ์•ฑ ๋งŒ๋“ค๊ธฐ: ์‹ค์ „ ์˜ˆ์ œ๋กœ ๋ฐฐ์›Œ๋ณด์ž!

์ž, ์ด์ œ ์šฐ๋ฆฌ๊ฐ€ ๋ฐฐ์šด ๊ฐœ๋…๋“ค์„ ์‹ค์ œ๋กœ ์ ์šฉํ•ด๋ณผ ์‹œ๊ฐ„์ด์•ผ! ์žฌ๋Šฅ๋„ท ์Šคํƒ€์ผ์˜ ๊ฐ„๋‹จํ•œ '์žฌ๋Šฅ ๋ชฉ๋ก' ํŽ˜์ด์ง€๋ฅผ ๋งŒ๋“ค์–ด๋ณผ ๊ฑฐ์•ผ. ์ด ๊ณผ์ •์„ ํ†ตํ•ด Blazor์˜ ํ•ต์‹ฌ ๊ธฐ๋Šฅ๋“ค์„ ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉํ•˜๋Š”์ง€ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ์ตํž ์ˆ˜ ์žˆ์„ ๊ฑฐ์•ผ. ์ค€๋น„๋์–ด? ๊ทธ๋Ÿผ ์‹œ์ž‘ํ•ด๋ณผ๊นŒ! ๐Ÿš€

1. ํ”„๋กœ์ ํŠธ ์ƒ์„ฑํ•˜๊ธฐ

๋จผ์ €, ์ƒˆ๋กœ์šด Blazor WebAssembly ํ”„๋กœ์ ํŠธ๋ฅผ ๋งŒ๋“ค์–ด๋ณด์ž. ๋ช…๋ น ํ”„๋กฌํ”„ํŠธ์—์„œ ๋‹ค์Œ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•ด:

dotnet new blazorwasm -o TalentNetApp

์ด ๋ช…๋ น์–ด๋Š” 'TalentNetApp'์ด๋ผ๋Š” ์ด๋ฆ„์˜ ์ƒˆ Blazor WebAssembly ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•ด.

2. ์žฌ๋Šฅ ๋ชจ๋ธ ๋งŒ๋“ค๊ธฐ

๋จผ์ €, ์žฌ๋Šฅ์„ ํ‘œํ˜„ํ•  ๋ชจ๋ธ์„ ๋งŒ๋“ค์–ด๋ณด์ž. 'Models' ํด๋”๋ฅผ ๋งŒ๋“ค๊ณ , ๊ทธ ์•ˆ์— 'Talent.cs' ํŒŒ์ผ์„ ์ƒ์„ฑํ•ด:

// Models/Talent.cs
public class Talent
{
    public int Id { get; set; }
    public string Title { get; set; }
    public string Description { get; set; }
    public string OwnerName { get; set; }
    public decimal Price { get; set; }
}

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์žฌ๋Šฅ์„ ํ‘œํ˜„ํ•˜๋Š” ๊ธฐ๋ณธ์ ์ธ ๋ชจ๋ธ์ด ๋งŒ๋“ค์–ด์กŒ์–ด.

3. ์žฌ๋Šฅ ๋ชฉ๋ก ์ปดํฌ๋„ŒํŠธ ๋งŒ๋“ค๊ธฐ

์ด์ œ ์žฌ๋Šฅ ๋ชฉ๋ก์„ ๋ณด์—ฌ์ค„ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ค์–ด๋ณด์ž. 'Pages' ํด๋”์— 'TalentList.razor' ํŒŒ์ผ์„ ์ƒ์„ฑํ•ด:

@page "/talents"
@using TalentNetApp.Models

<h1>์žฌ๋Šฅ ๋ชฉ๋ก</h1>

@if (talents == null)
{
    <p><em>Loading...</em></p>
}
else
{
    <div class="talent-grid">
        @foreach (var talent in talents)
        {
            <div class="talent-card">
                <h3>@talent.Title</h3>
                <p>@talent.Description</p>
                <p><strong>์ œ๊ณต์ž:</strong> @talent.OwnerName</p>
                <p><strong>๊ฐ€๊ฒฉ:</strong> @talent.Price.ToString("C")</p>
                <button> BookTalent(talent.Id)">์˜ˆ์•ฝํ•˜๊ธฐ</button>
            </div>
        }
    </div>
}

@code {
    private List<talent> talents;

    protected override void OnInitialized()
    {
        // ์‹ค์ œ๋กœ๋Š” API๋‚˜ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์™€์•ผ ํ•˜์ง€๋งŒ,  ์—ฌ๊ธฐ์„œ๋Š” ์˜ˆ์‹œ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ• ๊ฒŒ์š”.
        talents = new List<talent>
        {
            new Talent { Id = 1, Title = "์›น ๊ฐœ๋ฐœ", Description = "๋ฐ˜์‘ํ˜• ์›น์‚ฌ์ดํŠธ ์ œ์ž‘", OwnerName = "๊น€์ฒ ์ˆ˜", Price = 500000 },
            new Talent { Id = 2, Title = "๋กœ๊ณ  ๋””์ž์ธ", Description = "๋…ํŠนํ•˜๊ณ  ๊ธฐ์–ต์— ๋‚จ๋Š” ๋กœ๊ณ  ์ œ์ž‘", OwnerName = "์ด์˜ํฌ", Price = 300000 },
            new Talent { Id = 3, Title = "์˜์–ด ํšŒํ™”", Description = "1:1 ๋งž์ถคํ˜• ์˜์–ด ํšŒํ™” ๋ ˆ์Šจ", OwnerName = "John Doe", Price = 50000 },
        };
    }

    private void BookTalent(int talentId)
    {
        // ์—ฌ๊ธฐ์— ์˜ˆ์•ฝ ๋กœ์ง์„ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.
        Console.WriteLine($"์žฌ๋Šฅ ID {talentId}๊ฐ€ ์˜ˆ์•ฝ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.");
    }
}
</talent></talent>

์ด ์ปดํฌ๋„ŒํŠธ๋Š” ์žฌ๋Šฅ ๋ชฉ๋ก์„ ๊ทธ๋ฆฌ๋“œ ํ˜•ํƒœ๋กœ ๋ณด์—ฌ์ฃผ๊ณ , ๊ฐ ์žฌ๋Šฅ์— ๋Œ€ํ•œ '์˜ˆ์•ฝํ•˜๊ธฐ' ๋ฒ„ํŠผ๋„ ์ œ๊ณตํ•ด. @page "/talents" ์ง€์‹œ๋ฌธ์€ ์ด ์ปดํฌ๋„ŒํŠธ๋ฅผ "/talents" URL์— ์—ฐ๊ฒฐํ•ด์ค˜.

4. ์Šคํƒ€์ผ ์ถ”๊ฐ€ํ•˜๊ธฐ

์ด์ œ ์šฐ๋ฆฌ์˜ ์žฌ๋Šฅ ๋ชฉ๋ก์— ์•ฝ๊ฐ„์˜ ์Šคํƒ€์ผ์„ ์ถ”๊ฐ€ํ•ด๋ณด์ž. 'wwwroot/css/app.css' ํŒŒ์ผ์„ ์—ด๊ณ  ๋‹ค์Œ ์Šคํƒ€์ผ์„ ์ถ”๊ฐ€ํ•ด:

.talent-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
    gap: 20px;
    padding: 20px;
}

.talent-card {
    border: 1px solid #ddd;
    border-radius: 8px;
    padding: 15px;
    background-color: #f9f9f9;
    box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}

.talent-card h3 {
    margin-top: 0;
    color: #333;
}

.talent-card button {
    background-color: #3498db;
    color: white;
    border: none;
    padding: 10px 15px;
    border-radius: 5px;
    cursor: pointer;
    transition: background-color 0.3s;
}

.talent-card button:hover {
    background-color: #2980b9;
}

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์žฌ๋Šฅ ์นด๋“œ๋“ค์ด ๊น”๋”ํ•˜๊ฒŒ ์ •๋ ฌ๋˜๊ณ , ๋ณด๊ธฐ ์ข‹์€ ๋””์ž์ธ์ด ์ ์šฉ๋  ๊ฑฐ์•ผ.

5. ๋„ค๋น„๊ฒŒ์ด์…˜ ๋ฉ”๋‰ด์— ๋งํฌ ์ถ”๊ฐ€ํ•˜๊ธฐ

๋งˆ์ง€๋ง‰์œผ๋กœ, ๋„ค๋น„๊ฒŒ์ด์…˜ ๋ฉ”๋‰ด์— ์šฐ๋ฆฌ์˜ ์ƒˆ ํŽ˜์ด์ง€ ๋งํฌ๋ฅผ ์ถ”๊ฐ€ํ•ด๋ณด์ž. 'Shared/NavMenu.razor' ํŒŒ์ผ์„ ์—ด๊ณ  ๋‹ค์Œ ํ•ญ๋ชฉ์„ ์ถ”๊ฐ€ํ•ด:

<div class="nav-item px-3">
    <navlink class="nav-link" href="talents">
        <span class="oi oi-list-rich" aria-hidden="true"></span> ์žฌ๋Šฅ ๋ชฉ๋ก
    </navlink>
</div>

์ด์ œ ๋„ค๋น„๊ฒŒ์ด์…˜ ๋ฉ”๋‰ด์— '์žฌ๋Šฅ ๋ชฉ๋ก' ๋งํฌ๊ฐ€ ์ถ”๊ฐ€๋์–ด!

6. ์•ฑ ์‹คํ–‰ํ•˜๊ธฐ

๋ชจ๋“  ์ค€๋น„๊ฐ€ ๋๋‚ฌ์–ด! ์ด์ œ ์•ฑ์„ ์‹คํ–‰ํ•ด๋ณด์ž. ๋ช…๋ น ํ”„๋กฌํ”„ํŠธ์—์„œ ๋‹ค์Œ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•ด:

dotnet run

๊ทธ๋ฆฌ๊ณ  ๋ธŒ๋ผ์šฐ์ €์—์„œ https://localhost:5001๋กœ ์ ‘์†ํ•ด๋ด. '์žฌ๋Šฅ ๋ชฉ๋ก' ๋งํฌ๋ฅผ ํด๋ฆญํ•˜๋ฉด ์šฐ๋ฆฌ๊ฐ€ ๋งŒ๋“  ์žฌ๋Šฅ ๋ชฉ๋ก ํŽ˜์ด์ง€๋ฅผ ๋ณผ ์ˆ˜ ์žˆ์„ ๊ฑฐ์•ผ!

์žฌ๋Šฅ ๋ชฉ๋ก ํŽ˜์ด์ง€ ์˜ˆ์‹œ ์žฌ๋Šฅ๋„ท ํ™ˆ ์žฌ๋Šฅ ๋ชฉ๋ก ๋งˆ์ดํŽ˜์ด์ง€ ์žฌ๋Šฅ ๋ชฉ๋ก ์›น ๊ฐœ๋ฐœ ๋ฐ˜์‘ํ˜• ์›น์‚ฌ์ดํŠธ ์ œ์ž‘ ์ œ๊ณต์ž: ๊น€์ฒ ์ˆ˜ ๊ฐ€๊ฒฉ: 500,000์› ์˜ˆ์•ฝํ•˜๊ธฐ ๋กœ๊ณ  ๋””์ž์ธ ๋…ํŠนํ•œ ๋กœ๊ณ  ์ œ์ž‘ ์ œ๊ณต์ž: ์ด์˜ํฌ ๊ฐ€๊ฒฉ: 300,000์› ์˜ˆ์•ฝํ•˜๊ธฐ ์˜์–ด ํšŒํ™” 1:1 ๋งž์ถคํ˜• ๋ ˆ์Šจ ์ œ๊ณต์ž: John Doe ๊ฐ€๊ฒฉ: 50,000์› ์˜ˆ์•ฝํ•˜๊ธฐ

์œ„ ๊ทธ๋ฆผ์€ ์šฐ๋ฆฌ๊ฐ€ ๋งŒ๋“  ์žฌ๋Šฅ ๋ชฉ๋ก ํŽ˜์ด์ง€์˜ ์˜ˆ์‹œ์•ผ. ์‹ค์ œ๋กœ ์ด๋Ÿฐ ์‹์œผ๋กœ ๋ณด์ผ ๊ฑฐ์•ผ!

์ถ•ํ•˜ํ•ด! ๐ŸŽ‰ ์ด์ œ ๋„ˆ๋งŒ์˜ Blazor ์›น ์•ฑ์„ ๋งŒ๋“ค์—ˆ์–ด! ์ด ์˜ˆ์ œ๋ฅผ ํ†ตํ•ด Blazor์˜ ๊ธฐ๋ณธ์ ์ธ ์‚ฌ์šฉ๋ฒ•์„ ๋ฐฐ์› ์–ด. ์ปดํฌ๋„ŒํŠธ ์ƒ์„ฑ, ๋ฐ์ดํ„ฐ ๋ฐ”์ธ๋”ฉ, ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ, ๋ผ์šฐํŒ… ๋“ฑ ํ•ต์‹ฌ ๊ฐœ๋…๋“ค์„ ๋ชจ๋‘ ์‚ฌ์šฉํ•ด๋ดค์ง€.

์ด์ œ ์ด ๊ธฐ๋ณธ ๊ตฌ์กฐ๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ๋” ๋งŽ์€ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์–ด. ์˜ˆ๋ฅผ ๋“ค์–ด:

  • ์žฌ๋Šฅ ์ƒ์„ธ ํŽ˜์ด์ง€ ๋งŒ๋“ค๊ธฐ
  • ์žฌ๋Šฅ ๊ฒ€์ƒ‰ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ํ•˜๊ธฐ
  • ์‚ฌ์šฉ์ž ์ธ์ฆ ๊ตฌํ˜„ํ•˜๊ธฐ
  • ์‹ค์ œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€ ์—ฐ๋™ํ•˜๊ธฐ

์žฌ๋Šฅ๋„ท ๊ฐ™์€ ์‹ค์ œ ์„œ๋น„์Šค๋ฅผ ๋งŒ๋“ค๋ ค๋ฉด ์ด๋Ÿฐ ๊ธฐ๋Šฅ๋“ค์ด ๋” ํ•„์š”ํ•˜๊ฒ ์ง€? ํ•˜๋‚˜์”ฉ ์ฐจ๊ทผ์ฐจ๊ทผ ๊ตฌํ˜„ํ•ด ๋‚˜๊ฐ€๋ฉด ๋ผ. Blazor์˜ ๊ฐ•๋ ฅํ•œ ๊ธฐ๋Šฅ๋“ค์„ ํ™œ์šฉํ•˜๋ฉด, ๋ณต์žกํ•œ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๋„ ํšจ์œจ์ ์œผ๋กœ ๊ฐœ๋ฐœํ•  ์ˆ˜ ์žˆ์„ ๊ฑฐ์•ผ.

์–ด๋•Œ, Blazor๋กœ ์›น ์•ฑ ๋งŒ๋“ค๊ธฐ ์žฌ๋ฏธ์žˆ์ง€ ์•Š์•„? ์ด์ œ ์‹œ์ž‘์ผ ๋ฟ์ด์•ผ. ๊ณ„์† ์—ฐ์Šตํ•˜๊ณ  ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ๋“ค์„ ์‹œ๋„ํ•ด๋ณด๋ฉด์„œ Blazor ๋งˆ์Šคํ„ฐ๊ฐ€ ๋˜์–ด๋ณด์ž! ํ™”์ดํŒ…! ๐Ÿ’ช๐Ÿ˜„

๐Ÿš€ Blazor ๊ฐœ๋ฐœ ํŒ๊ณผ ํŠธ๋ฆญ: ํ”„๋กœ์ฒ˜๋Ÿผ ์ฝ”๋”ฉํ•˜๊ธฐ

์ž, ์ด์ œ Blazor์˜ ๊ธฐ๋ณธ์„ ๋ฐฐ์› ์œผ๋‹ˆ ์กฐ๊ธˆ ๋” ๊นŠ์ด ๋“ค์–ด๊ฐ€๋ณผ๊นŒ? ์—ฌ๊ธฐ Blazor๋กœ ๋” ํšจ์œจ์ ์ด๊ณ  ๊น”๋”ํ•œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š”๋ฐ ๋„์›€์ด ๋  ํŒ๋“ค์„ ๋ชจ์•„๋ดค์–ด. ์ด ํŒ๋“ค์„ ํ™œ์šฉํ•˜๋ฉด ์žฌ๋Šฅ๋„ท ๊ฐ™์€ ๋ณต์žกํ•œ ์›น ์•ฑ๋„ ๋” ์‰ฝ๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ์„ ๊ฑฐ์•ผ!

1. ์ปดํฌ๋„ŒํŠธ ๋ถ„๋ฆฌ์™€ ์žฌ์‚ฌ์šฉ

์ž‘์€ ๋‹จ์œ„์˜ ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ค์–ด ์‚ฌ์šฉํ•ด. ์˜ˆ๋ฅผ ๋“ค์–ด, ์šฐ๋ฆฌ๊ฐ€ ๋งŒ๋“  ์žฌ๋Šฅ ์นด๋“œ๋ฅผ ๋ณ„๋„์˜ ์ปดํฌ๋„ŒํŠธ๋กœ ๋ถ„๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด:

@* TalentCard.razor *@
<div class="talent-card">
    <h3>@Talent.Title</h3>
    <p>@Talent.Description</p>
    <p><strong>์ œ๊ณต์ž:</strong> @Talent.OwnerName</p>
    <p><strong>๊ฐ€๊ฒฉ:</strong> @Talent.Price.ToString("C")</p>
    <button>์˜ˆ์•ฝํ•˜๊ธฐ</button>
</div>

@code {
    [Parameter]
    public Talent Talent { get; set; }

    [Parameter]
    public EventCallback<int> OnBookClick { get; set; }
}
</int>

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋ฉ”์ธ ํŽ˜์ด์ง€์—์„œ ์ด ์ปดํฌ๋„ŒํŠธ๋ฅผ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด:

@foreach (var talent in talents)
{
    <talentcard talent="talent" onbookclick="() => BookTalent(talent.Id)"></talentcard>
}

2. Cascading Parameters ํ™œ์šฉํ•˜๊ธฐ

์—ฌ๋Ÿฌ ๋‹จ๊ณ„์˜ ์ค‘์ฒฉ๋œ ์ปดํฌ๋„ŒํŠธ์— ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌํ•ด์•ผ ํ•  ๋•Œ, Cascading Parameters๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํŽธ๋ฆฌํ•ด:

<cascadingvalue value="@currentUser">
    <talentlist></talentlist>
</cascadingvalue>

@code {
    private User currentUser;
}

์ด์ œ TalentList๋‚˜ ๊ทธ ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ์—์„œ currentUser๋ฅผ ์‰ฝ๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด:

[CascadingParameter]
private User CurrentUser { get; set; }

3. Code-behind ํŒจํ„ด ์‚ฌ์šฉํ•˜๊ธฐ

๋ณต์žกํ•œ ๋กœ์ง์ด ์žˆ๋Š” ๊ฒฝ์šฐ, code-behind ํŒจํ„ด์„ ์‚ฌ์šฉํ•˜๋ฉด ์ฝ”๋“œ๋ฅผ ๋” ๊น”๋”ํ•˜๊ฒŒ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด:

@* TalentList.razor *@
@page "/talents"
@inherits TalentListBase

<h1>์žฌ๋Šฅ ๋ชฉ๋ก</h1>
@* ๋‚˜๋จธ์ง€ UI ์ฝ”๋“œ *@

@* TalentList.razor.cs *@
public class TalentListBase : ComponentBase
{
    protected List<talent> talents;

    protected override async Task OnInitializedAsync()
    {
        talents = await TalentService.GetTalentsAsync();
    }

    // ๋‹ค๋ฅธ ๋ฉ”์„œ๋“œ๋“ค...
}
</talent>

4. ์ƒํƒœ ๊ด€๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์‚ฌ์šฉํ•˜๊ธฐ

์•ฑ์ด ๋ณต์žกํ•ด์ง€๋ฉด ์ƒํƒœ ๊ด€๋ฆฌ๊ฐ€ ์ค‘์š”ํ•ด์ ธ. Fluxor ๊ฐ™์€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ƒํƒœ๋ฅผ ํšจ๊ณผ์ ์œผ๋กœ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด:

@inject IState<talentstate> TalentState

<h1>์žฌ๋Šฅ ๋ชฉ๋ก (@TalentState.Value.Talents.Count)</h1>
@foreach (var talent in TalentState.Value.Talents)
{
    <talentcard talent="talent"></talentcard>
}
</talentstate>

5. ์„ฑ๋Šฅ ์ตœ์ ํ™”

ShouldRender() ๋ฉ”์„œ๋“œ๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋“œํ•ด์„œ ๋ถˆํ•„์š”ํ•œ ๋ Œ๋”๋ง์„ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ์–ด:

protected override bool ShouldRender()
{
    return talents != null && talents.Any();
}

6. ์‚ฌ์šฉ์ž ์ •์˜ ์ž…๋ ฅ ์ปดํฌ๋„ŒํŠธ ๋งŒ๋“ค๊ธฐ

์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์‚ฌ์šฉ์ž ์ •์˜ ์ž…๋ ฅ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ค์–ด ์‚ฌ์šฉํ•˜๋ฉด ํŽธ๋ฆฌํ•ด:

@* CustomInput.razor *@
<input class="@CssClass" value="@Value">

@code {
    [Parameter(CaptureUnmatchedValues = true)]
    public Dictionary<string object> AdditionalAttributes { get; set; }

    [Parameter]
    public string CssClass { get; set; }

    [Parameter]
    public string Value { get; set; }

    [Parameter]
    public EventCallback<string> ValueChanged { get; set; }

    private Task OnValueChanged(ChangeEventArgs e)
    {
        Value = e.Value.ToString();
        return ValueChanged.InvokeAsync(Value);
    }
}
</string></string>

7. JS Interop ํ™œ์šฉํ•˜๊ธฐ

JavaScript ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•  ๋•Œ JS Interop์„ ํ™œ์šฉํ•ด:

@inject IJSRuntime JSRuntime

@code {
    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            await JSRuntime.InvokeVoidAsync("initializeChart", chartData);
        }
    }
}
Blazor ๊ฐœ๋ฐœ ํŒ๊ณผ ํŠธ๋ฆญ Blazor Tips ์ปดํฌ๋„ŒํŠธ ๋ถ„๋ฆฌ ์ƒํƒœ ๊ด€๋ฆฌ ์„ฑ๋Šฅ ์ตœ์ ํ™” JS Interop Code-behind

์ด ๊ทธ๋ฆผ์€ ์šฐ๋ฆฌ๊ฐ€ ๋ฐฉ๊ธˆ ๋ฐฐ์šด Blazor ๊ฐœ๋ฐœ ํŒ๋“ค์„ ์‹œ๊ฐ์ ์œผ๋กœ ๋ณด์—ฌ์ฃผ๊ณ  ์žˆ์–ด. ์ด ํŒ๋“ค์„ ์ž˜ ํ™œ์šฉํ•˜๋ฉด ๋” ํšจ์œจ์ ์ด๊ณ  ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์‰ฌ์šด ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์„ ๊ฑฐ์•ผ.

์ด๋Ÿฐ ํŒ๋“ค์„ ํ™œ์šฉํ•˜๋ฉด ์žฌ๋Šฅ๋„ท ๊ฐ™์€ ๋ณต์žกํ•œ ์›น ์•ฑ๋„ ๋” ์‰ฝ๊ฒŒ ๊ด€๋ฆฌํ•˜๊ณ  ํ™•์žฅํ•  ์ˆ˜ ์žˆ์–ด. ์˜ˆ๋ฅผ ๋“ค์–ด, ์žฌ๋Šฅ ์นด๋“œ๋ฅผ ๋ณ„๋„์˜ ์ปดํฌ๋„ŒํŠธ๋กœ ๋ถ„๋ฆฌํ•˜๋ฉด ์žฌ์‚ฌ์šฉ์„ฑ์ด ๋†’์•„์ง€๊ณ , ์ƒํƒœ ๊ด€๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฐ์ดํ„ฐ ํ๋ฆ„์„ ๋” ์‰ฝ๊ฒŒ ์ œ์–ดํ•  ์ˆ˜ ์žˆ์ง€. ์„ฑ๋Šฅ ์ตœ์ ํ™” ๊ธฐ๋ฒ•์„ ์ ์šฉํ•˜๋ฉด ์‚ฌ์šฉ์ž ๊ฒฝํ—˜๋„ ๊ฐœ์„ ๋  ๊ฑฐ๊ณ .

Blazor๋Š” ์ •๋ง ๊ฐ•๋ ฅํ•œ ํ”„๋ ˆ์ž„์›Œํฌ์•ผ. ์ด๋Ÿฐ ๊ณ ๊ธ‰ ๊ธฐ๋Šฅ๋“ค์„ ๋งˆ์Šคํ„ฐํ•˜๋ฉด, ์›น ๊ฐœ๋ฐœ์˜ ์ƒˆ๋กœ์šด ์ฐจ์›์„ ๊ฒฝํ—˜ํ•  ์ˆ˜ ์žˆ์„ ๊ฑฐ์•ผ. ๊ณ„์† ์—ฐ์Šตํ•˜๊ณ  ์ƒˆ๋กœ์šด ๊ฒƒ์„ ์‹œ๋„ํ•ด๋ด. ๊ทธ๋Ÿผ ์–ด๋Š์ƒˆ Blazor ์ „๋ฌธ๊ฐ€๊ฐ€ ๋˜์–ด ์žˆ์„ ๊ฑฐ์•ผ! ํ™”์ดํŒ…! ๐Ÿ’ช๐Ÿ˜„