728x90

열거형 : 정수 숫자 형식의 상수 집합에 멤버 이름을 지정할 수 있다. 

enum Menu
{
	Info, // 0
	Status // 1
}

 

열거된 멤버들은 첫 멤버부터 0으로 시작하는 정수를 상수로 가지고 다음 멤버들은 1씩 증가하는 정수를 상수로 가진다.

 

enum Menu
{
	Candy=1,
    	Chocolate=3,
    	Snack // 4
}

. 상수를 명시적으로 지정해 줄 수도 있고 지정하지 않은 멤버는 이전 멤버의 +1 값을 가진다.

 

열거형의 사용

Menu candy = Menu.Candy;
var choco = (Menu)3;

Console.WriteLine(candy); // Candy 
Console.WriteLine((int)Candy); // 1
Console.WriteLine(choco); // Chocolate
Console.WriteLIne((int)choco); // 3
Console.WriteLine((Menu)10); // 10

 

Enum.IsDefined : 멤버 존재 여부 확인 

IsDefined(Type enumType, object value);



Enum.IsDefined(typeof(Menu),1); // true
Enum.IsDefined(typeof(Menu),2); // false

 

'C#' 카테고리의 다른 글

C# 기초 문법  (0) 2024.04.11
728x90

함수 형식

returnType FunctionName ( parameterType parameter1, parameterType parameter2 = "default" )
{
  print(parameter1);
  print(parameter2);
  print("FunctionName 첫글자는 대문자");
  print("디폴트 값을 가지는 파라메터는 맨 뒤에 위치한다.");
  
  return data;
}

 

 

접근제한자 

 

[ private, public, protected ] 

default : private 

 

public :  모든 레벨에서 접근 가능 

private : 동일한 Class에서만 접근 가능

protected : 동일 Class 또는 상속받는 Class에서만 접근 가능 

 

반복문 

 

int i;
int j = 3;
for (i = 0, Console.WriteLine($"Start: i={i}, j={j}"); i < j; i++, j--, Console.WriteLine($"Step: i={i}, j={j}"))
{
    //...
}
// Output:
// Start: i=0, j=3
// Step: i=1, j=2
// Step: i=2, j=1

initializer에서 loop 변수를 선언하지 않는 경우 initializer 섹션에서 0개 이상의 식을 사용할 수 있다. 


int j = 3;
for (int i = 0; i < j; i++, j--, Console.WriteLine($"Step: i={i}, j={j}"))
{
    //...
}
// Output:
// Step: i=1, j=2
// Step: i=2, j=1


i와 j 두가지 변수 모두 값을 변경할 수 있다.

 

foreach

int[,] numbers = {{1, 2, 3, 4, 5},{0, 1, 2, 3, 4}};
foreach (int number in numbers)
{
    Console.Write(number+" ");
}
// Output:
// 1 2 3 4 5 0 1 2 3 4

 

 

컬렉션 

 

ArrayList

ArrayList 콜렉션은 non generic collection으로 타입을 정해두지 않고 여러 타입의 데이터를 동시에 담을 수 있다.

ArrayList arrayList = new ArrayList();
arrayList.Add("stringValue");
arrayList.Add(1);
arrayList.Add(false);

print(arrayList[0]);

// Output:
// stringValue

 

 

List<T> 

List<T> 콜렉션은 타입을 지정하여 동일한 타입의 데이터들을 담을 수 있다. 

 

ArrayList보다는 List<T> 클래스를 사용할 것을 권장하고 있다. 

 

 

HashTable / Dictionary<K, V>

Key Value 형식으로 데이터를 저장하며 Key와 Value의 타입은 동일하지 않을 수 있다.

HashTable hashTable = new HashTable();
hashTable.Add("일",1);
hashTable.Add(2,"이");

print(hashTable["일"]);
print(hashTable[2]);

 

Dictionary도 HashTable과 같지만 제네릭 지정하여 사용하기 때문에 List<T>와 마찬가지로 성능이 더 좋다.

 

Queue<T> / Stack<T>

선입선출 FIFO / 후입선출 LIFO

Queue<int> q = new Queue<int>();
q.Enqueue(1);
q.Enqueue(2);

for (; q.Count != 0; q.Dequeue())
{
    Console.WriteLine(q.Peek());
}
// Output:
// 1 2

Stack<int> st = new Stack<int>();
st.Push(1);
st.Push(2);

for(; st.Count != 0;)
{
    Console.WriteLine(st.Pop());
 }
 // Output:
 // 2 1

 

 

namespace

namespace 키워드를 사용하여 관련 파일 혹은 다른 namespace 등을 포함하는 범위를 선언할 수 있다. 

 

선언한 namespace는 using 키워드를 통해 사용할 수 있고

namespace에 alias 를 부여하여 사용할 수 있다.

 

namespace Utils
{
    struct UtilStruct { }

    enum UtilEnum { a, b }

    delegate void UtilDelegate(int i);

    namespace Calendar
    {
        static class MicroTimer { }

        interface Timer { }
    }
}

global using <fully-qualified-Utils>;
using Alias = Utils.Calendar;

 

global using 키워드는 프로젝트내의 모든 파일에서 using 이 적용된다는 것을 의미한다.

'C#' 카테고리의 다른 글

C# 열거형  (0) 2024.04.16
728x90

Spring Initializer에서 Spring Project를 생성한다.

https://start.spring.io/

Generate버튼을 클릭하면 프로젝트를 다운로드 받는다. 

 

다운로드 받은 프로젝트는압축해제하여 워크스페이스에 옮기고 IntelliJ를 실행한다.

 

Open

demo 폴더의 pom.xml을 선택

 

Open as project 

Spring 구조의 기본 프로젝트가 생성되었다.

외부 라이브러리에 initializer에서 추가한 Spring web, dev tools 가 추가되었다. 

pom.xml에도 dependency에 추가된 것을 확인할 수 있다. 

 

maven의 spring-boot:run을 실행하면 spring에 내장된 톰캣을 통해 서버를 실행시킬 수 있다. 

*터미널에서 mvn spring-boot:run 명령어를 사용해도 된다. 

728x90

개발한 웹 애플리케이션을  Apache Tomcat을 이용해 배포하고 서버를 운영하는 환경을 구축하는 방법 

 

-Application Packaging

 

mvn clean compile package

gradlew build

명령어 혹은 task 도구를 이용해 패키징한다. 

 

package를 완료하면 war 파일이 모듈의 target 폴더에 생성된다. 

 

-startup.bat 사용하기 

(windows는 배치파일, linux기반 os는 쉘스크립트)

tomcat-webapps폴더에 패키징한 war파일을 복사하여 옮겨준다.

tomcat\bin\startup.bat 파일을 실행하면 webapps의 war 파일들 압축해제하여 실행시켜준다. 

 

tomcat\webapps 폴더에 war파일이 압축해제되어 maven_begin 폴더가 생성되었다.

서버를 종료할 때는shutdown  배치파일을 실행하면된다. 

  

-Tomcat Manager 사용하기 

 

tomcat\conf\tomcat-users.xml 파일에 관리자 계정 권한 부여하기 

<tomcat-users>
  <role rolename="manager-gui"/>
  <role rolename="manager-script"/>
  <role rolename="manager-jmx"/>
  <role rolename="manager-status"/>

  <user username="admin" password="admin" roles="manager-gui,manager-script,manager-jmx,manager-status"/>
</tomcat-users>

*터미널에서 code 명령어를 사용하면 파일을 vscode로 편집할 수 있다.

 

startup.bat로 서버를 실행하고 

localhost/manager로 접속하면 

로그인할 수 있는 창이 뜨는데 여기에 아까 만들어주었던 어드민 계정으로 로그인한다.

manager에서는 톰캣이 실행중인 웹 애플리케이션들을 관리할 수 있는 gui를 제공하공하고 있다.  

 

 배치할 war파일에서 파일을 업로드하여 배치할수 있다. 

 

파일을 선택학고 배치를 클릭하면 

 maven_begin 애플리케이션이 배치되었다 .

728x90

Eclipse 와 IntelliJ 의 차이

 

Eclipse IntelliJ
Workspace Project
Project Module
Facet
Library
JRE SDK
Classpath variable Path variable

 

 

 

IntelliJ 다운로드 

https://www.jetbrains.com/ko-kr/idea/download/?section=windows

 

최고의 Java 및 Kotlin IDE인 IntelliJ IDEA를 다운로드하세요

 

www.jetbrains.com

Community Edition을 다운로드하면 제한적으로 무료로 사용할수 있다.

 

Community Edition 사용시 필요한 플러그인

- Smart Tomcat 

 

 

Maven을 이용한 Web Project 생성

-Maven Archetype(Project Template):maven-archetype-webapp

 

 

 

IntelliJ IDEA 설정

 

프로젝트에 관한 설 

 

++파일 검색

 

Shift키 두번

 

 

 

maven으로 web project를 생성하면 maven 도구를 이용해 프로젝트 작업을 수행할 수 있다.

 

IntelliJ의 터미널을 이용해 프로젝트의 작업을 수행할 수도 있다. 

 

Windows의 터미널을 가져와 사용하기 때문에 터미널이 작동하지 않는다면 다른 터미널 프로그램을 사용하면 된다.  

 

maven 명령어를 실행할 위치는 pom.xml 파일이 존재해야한다.

maven을 설치하고 환경변수를 제대로 설정해줬다면 mvn 명령어를 통해 작업을 수행할 수 있다.   

 

아래 화살표를 클릭하면 사용할 터미널을 선택하거나 터미널을 설정할 수 있다. 

Git Bash 터미널이 있기 때문에 바로 Git 명령어를 입력할 수도 있다.    

 

 

Web Project를 Tomcat Server에 실행하려면 

 메뉴바의 실행버튼 옆에 톰캣을 클릭해 Edit Configuration을 클릭하여 설정하고 실행하면 된다.     

 

실행버튼을 클릭하면

 서버를 실행하고 웹 브라우저에서 확인할 수 있다.

 

JSP 프로젝트 

pom.xml 파일에 servlet dependency 추가  

 

main의 java 폴더에 servlet 클래스 생성 

HttpServlet 을 상속한 HelloServlet 클래스에 필요한 메소드를 구현해준다. 

 

web.xml파일에서 

servlet 클래스를 등록하고 맵핑해줘야 한다.

 

<servlet> 태그 안에 name과 그 name에 해당하는 class의 주소를 등록하고 

<servlet-mapping> 태그 안에 servlet name에 url pattern을 등록해준다. 

web.xml 파일에 mapping하는 방법 이외에 어노테이션을 이용하는 방법도 있다. 

    

@WebServlet 어노테이션과 그 안에 url pattern을 입력하면 mapping을 간단하게 처리할 수 있다. 

 

JSP 파일 생성하기 

webapp폴더 안에 .jsp 파일을 생성한다. 

index.jsp 파일은 기본으로 생성된다.  

내용을 입력하고 /index.jsp url로 확인할 수 있다. 

728x90

Vue.js에서 회원가입 폼을 만들어 실습하면서 form을 통해 데이터를 전송하는 법을 알아보자

 

<template>
    <form action="" @submit.prevent="submitForm">
        <div>
            <label for="userId">아이디</label>
            <input id="userId" type="text" v-model="username">
        </div>
        <div>
            <label for="password">패스워드</label>
            <input id="password" type="password" v-model="password"> 
        </div>
        <button type="submit">회원가입</button>
    </form>
</template>

form을 만들고 input:text, label로 아이디와 패스워드를 입력 받을 폼을 만든다. 

 

submit 버튼은 디폴트로 submit 이벤트가 발생하고 페이지가 새로고침되기 때문에 새로고침을 막아야한다. 

 

새로고침을 막기 위해서 @submit 이벤트 핸들러에 .prevent를 붙여 preventDefault를 한다. 

그리고 submit 이벤트가 발생하면 폼의 input을 전송할 함수인 submitForm을 등록한다. 

 

            <input id="userId" type="text" v-model="username">

 input 태그에 v-model이라는 속성이 붙어있다. 

v-model은 input 태그의 value를 바인딩 해주는 디렉티브이다. 

만약 v-model을 사용하지 않는다면

input 태그에 input 이벤트가 발생할 때 input 태그의 value값을 가져와 v-bind: 바인딩해주는 작업을 해야한다. 

<input
  :username="text"
  @input="event => text = event.target.value">

 

data(){
	return {
    	username: '',
        password: '',
    }
}

 

그리고 data에 username과 password를 정의해준다. 

 

다음으로 비밀번호를 표시할지 password 타입으로 **처리할지 선택할 수 있는 체크박스를 만들어보자 

 <input type="checkbox" id="show" v-model="checked" @change="showPassword"> 
 
 data(){
 	return {
    	username: '',
        password: '',
        checked: '',
    }
 }
 methods:{
            showPassword(){
                if(this.checked){
                    document.querySelector('#password').type='text';
                }else{
                    document.querySelector('#password').type = 'password';
                }
            }
        }

template의 password input 태그 아래 checkbox를 추가하고 

change이벤트 핸들러에 showPassword 함수를 등록한다. 

showPassword 함수는 v-model로 받은 checked의 값에 따라 #password 태그의 type을 text와 password로 바꿔준다. 

여기서 this.checked는 data의 checked를 의미한다. 

체크박스가 해제 되었을 땐 password 타입

checked 상태에선 text 타입인 것을 확인할 수 있다. 

 

다중 checkbox, radio, select 를 사용한 input 태그를 작성

<template>
    <form action="" @submit.prevent="submitForm">
        <div>
            <label for="userId">아이디</label>
            <input id="userId" type="text" v-model="username">
        </div>
        <div>
            <label for="password">패스워드</label>
            <input id="password" type="password" v-model="password">
            <input type="checkbox" id="show" v-model="checked" @change="showPassword"> 
        </div>
        <div>
            <h3>성별</h3>
            <input type="radio" name="gender" id="M" value="남자" v-model="picked">
            <label for="M">M</label>
            <input type="radio" name="gender" id="F" value="여자" v-model="picked">
            <label for="F">M</label>
        </div>
        <div>
            <h3>기술스택</h3>
            <input type="checkbox" id="springboot" value="springboot" v-model="checkedNames">
            <label for="springboot">SpringBoot</label>
            <input type="checkbox" id="jpa" value="jpa" v-model="checkedNames">
            <label for="jpa">JPA</label>
            <input type="checkbox" id="mybatis" value="mybatis" v-model="checkedNames">
            <label for="mybatis">MyBatis</label>
            <input type="checkbox" id="vue" value="vue" v-model="checkedNames">
            <label for="vue">Vue</label>
            <input type="checkbox" id="react" value="react" v-model="checkedNames">
            <label for="react">React</label>
        </div>
        <div>
            <h3>주소</h3>
            <select name="address" id="address" v-model="selected">
                <option disabled value="">선택</option>
                <option value="서초구">서초구</option>
                <option value="관악구">관악구</option>
            </select>
        </div><br>
        <button type="submit">회원가입</button>
    </form>
</template>

 

input data를 전송하기 위한 submitForm 함수 작성 

 submitForm(){
                axios.post('https://jsonplaceholder.typicode.com/users/',{
                    username:this.username,
                    password:this.password,
                    checked:this.checked,
                    checkedNames:this.checkedNames,
                    picked:this.picked,
                    selected:this.selected
                }).then(response=>{
                    console.log(response);
                });
            },

 

axios는 비동기 요청방식 api이다. 

데이터를 서버로 전송하고 응답을 받아 처리할 수 있다. 

 

axios를 사용하기 위해 axios를 다운로드

https://github.com/axios/axios

 

GitHub - axios/axios: Promise based HTTP client for the browser and node.js

Promise based HTTP client for the browser and node.js - GitHub - axios/axios: Promise based HTTP client for the browser and node.js

github.com

 

사이트의 installing package manager에서 본인이 사용하는 패키지 매니저에 따라 명령어를 카피하고

프로젝트 디렉터리의 터미널에서 명령어를 실행한다. 

 

정상적으로 다운로드되면 package.json의 dependencies에 axios가 추가된다. 

import axios from 'axios'

App.vue에서 axios를 사용하기 위해 import 해준다. 

 

axios.post('url','data')으로 post 요청을 한다. 

 

이때 가상 서버 역할을 해줄 api가 필요하다면 

https://jsonplaceholder.typicode.com/users/를 이용할 수 있다. 

 

 data() {
            return {
                username: '',
                password: '',
                checked: '',
                checkedNames: [],
                picked: '',
                selected: ''
            }
        },
        
        
        
 axios.post('https://jsonplaceholder.typicode.com/users/',{
                    username:this.username,
                    password:this.password,
                    checked:this.checked,
                    checkedNames:this.checkedNames,
                    picked:this.picked,
                    selected:this.selected
                }).then(response=>{
                    console.log(response);
                });

 

 

data는 {객체형식으로 넘겨주면 된다.}

다중 checkbox는 배열로 넘겨주었다. 

input태그에 값을 입력하고 회원가입을 클릭하면 

users/ 요청이 날아가고 

payload를 클릭하면 요청할 때 보낸 data를 확인할 수 있다. 

 

.then은 서버로부터 응답을 받은 후의 로직을 작성할 수 있다. 

console.log(response) 에 의해 

response가 console창에 찍혔다. 

 

https://ko.vuejs.org/guide/essentials/forms.html

 

Form 입력 바인딩 | Vue.js

 

ko.vuejs.org

 

'Vue.js' 카테고리의 다른 글

Vue.js 프로젝트 생성하기  (0) 2023.11.29
Vue.js 기초 문법  (2) 2023.11.28
Vue.js Intro  (0) 2023.11.28
728x90

#vue-cli 

 

폴더구조, 라이브러리, build 등 기본 vue 개발 환경을 설정해주는 cli 도구 

 

#vue-cli 설치하기 

npm install -g @vue/cli

 

#vue 프로젝트 생성하기 

vue create projectName

vue create 명령어로 프로젝트 생성

 

* vs code terminal에서 실행되지 않는다면 windows powershell 문제로 

 

preset을 선택하면 프로젝트를 생성한다.

vue3 기본 환경으로 프로젝트를 생성하고 싶다면 vue3를 

vue2 기본 환경으로 프로젝트를 생성하고 싶다면 vue2를 

직접 라이브러리, build 등의 환경을 수동으로 설정하고 싶다면 manually를 선택하면 된다.

프로젝트가 생성되면 cd projectName, npm run serve로 프로젝트를 시작하라고 한다. 

프로젝트 디렉터리로 이동해서 서버를 실행하고 8080 포트로 접속하면 아래와 같은 화면이 나온다. 

 

**서버를 종료할 때는 ctrl+c 

 

vue-cli 로 생성된 프로젝트로 돌아가면 

workspace 안에 vue3-cli 프로젝트가 생성되어있다. 

 

먼저 package.json에는 프로젝트 정보, 프로젝트에 설치된 라이브러리 등이 있고 

package.json에 설정된 라이브러리는 node_module에 설치된 것을 확인할 수 있다. 

여기서 dependencies와 devDependencies 두가지가 있는데 

dependencies는 배포용, dev는 개발용이다. 

개발용 dependencies는 설치할 때 npm install library -D 로 설치하면 된다. 

그리고 scripts 의 serve, build, lint는 custom cli 명령어이다. 

 

 

public의 index.html 파일을 확인하면 

 

#app div가 있다. 

이 태그 안에 createApp 으로 만들어진 app 컴포넌트가 들어갈 것을 예상할 수 있다. 

그런데 index.html 파일에는 vue cdn, createApp을 하는 script등이 보이지 않는다. 

대신 주석을 보면 빌드된 파일을 자동으로 주입된다는 것을 볼 수 있다. 

 

localhost:8080 에서 개발자도구를 확인해본다. 

localhost는 index.html document이다. 

head에 app.js를 가져오는 태그가 자동으로 생성되었고 좌측에 app.js를 다운로드하였다. 

app.js는 main.js를 가져오는것을 알 수 있다. 

 

프로젝트의 main.js

package의 dependencies의 vue라이브러리의 vue로부터 createApp을 가져오고 

App.vue에서 App을 가져와 createApp(App)을 #app에 마운트하고 있다. 

 

App.vue파일은 

app(root)컴포넌트를 정의하는 파일이다. 

component패키지에 정의된 Helloworld.vue 컴포넌트를 import 하여 root 컴포넌트의 자식 컴포넌트로 정의하고 있다. 

이처럼 하위 컴포넌트들은 component 패키지에 분리하여 정의하고 root 컴포넌트를 main.js에서 import 함으로써 

main에는 큰 관심사만 모듈로서 정의하고 하위 컴포넌트들을 분리하여 유지보수와 확장성에 유리한 구조가 되었다. 

 

#Vue SFC (Single File Component)

 

싱글 파일 컴포넌트는 vue 컴포넌트의 템플릿, 스크립트, 스타일을 하나의 파일로 묶어낸 .vue 파일 형식이다. 

<template>
  <img alt="Vue logo" src="./assets/logo.png">
  <HelloWorld msg="Welcome to Your Vue.js App"/>
</template>

<script>
import HelloWorld from './components/HelloWorld.vue'

export default {
  name: 'App',
  components: {
    HelloWorld
  }
}
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

 

앞서 보았던 App.vue도 싱글 파일 컴포넌트이고 <template>, <script>, <style>로 구성된 것을 확인할 수 있다. 

 

이전 html 파일에서는 카멜케이스 사용에 관한 문제가 있었는데 

SFC 에서는 파스칼 케이스를 사용하는 것을 알 수 있다. 

물론, 카멜케이스로도 사용할 수 있지만 통일성을 위해 파스칼 케이스로 통일해주도록 한다. 

 

** vue vscode snippet 플러그인 shortcut

vbc(v-base with css) + tab : sfc 기본 구조 template, script, style 생성

vdata + tab : data() {return {}} 생성

 

 

 

https://cli.vuejs.org/

 

Vue CLI

 

cli.vuejs.org

 

'Vue.js' 카테고리의 다른 글

Vue.js form submit  (0) 2023.11.30
Vue.js 기초 문법  (2) 2023.11.28
Vue.js Intro  (0) 2023.11.28
728x90

#Vue 인스턴스 생성

 

[Vue2]

//Vue2 application instance 생성방법
new Vue({
	//component options
    el: '#app', // mount할 element
    template: '<p>{{firstName}} {{lastName}} aka {{alias}}</p>',, //화면에 표시할 요소
    data: function() {
    	return {
        	firstName: 'choi',
            lastName: 'coding',
            alias: 'choicoding'
        }
    },
    method: {
    	changeFirstName(first) {
        	this.firstName=first
        },
    }, //화면의 동작, 이벤트 handling할 메소드 
    created: function(){}, //life cycle hook (beforeCreate, beforeMount, mounted, ..)
    watch: {
    	firstName: function (val, oldVal) {
        	console.log(oldVal,'->',val);
        }
    }, //data의 변화를 감시하여 대응할 동작

});

new Vue({
    data: {
    },

}).$mount('#app');

 

[Vue3]

//Vue3 application instance 생성 방법
Vue.createApp({
	data() {
    	return {
           	a: 'adata'
        }
    }
}).mount('#app');

 

 

#Vue Directive[ v-on ]

 

이벤트함수 등록

 

v-on:이벤트="function" 

 

>> v-on:은 @으로 대체될 수 있다. 

ex) @click="function"

<div id="app">
    <button v-on:click="minus">-</button>
    <p>{{count}}</p>
    <button v-on:click="plus">+</button>
</div>
<script>
    Vue.createApp({
        data(){
            return{
                count: 0
            }
        },
        methods: {
            plus(){
                this.count++;
            },
            minus(){
                this.count--;
            }
        }
    }).mount('#app');
</script>

 

#Vue Directive[ v-for ]

 

리스트 렌더링

 

v-for="alias in list

 

<div id="app">
    <ul>
        <li v-for="item in items">{{item}}</li>
    </ul>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script>
    Vue.createApp({
        data(){
            return{
                items: ['1번','2번','3번','4번']
            }
        }
    }).mount('#app');
</script>

실행결과

 

**shortcut

ul>li +tap : ul와 하위 li 태그 동시 생성

 

 

#Vue Directive[ v-if / v-else-if / v-else ]

 

조건부 렌더링

 

v-if="조건

<body>
    <div id="app">
        <p v-if="a">a가 존재하면 렌더링될 태그</p>
        <p v-else-if="a==10">a=10이면 렌더링될 태그</p>
        <p v-else>다 아니면 렌더링될 태그</p>
    </div>
</body>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script>
    Vue.createApp({
        data(){
            return{
                a:1
            }
        }
    }).mount('#app');
</script>

 

v-show="조건"

 

 <p v-show="a">a가 존재하면 렌더링될 태그</p>

 

v-if 와 v-show의 차이점

 

v-if는 조건에 따라서 선택적으로 렌더링되고 

v-show는 일단 렌더링되고 조건이 false이면 css로 display:none 이 된다. 

 

v-if는 전환비용이 높기 때문에 만약 사용자가 v-if의 조건을 자주 바꾼다면 

v-if가 전환될 때마다 재렌더링을 해야한다. 

반면, v-show는 최초 렌더링 할때 같이 렌더링해두고 css만 전환하면 되기 전환비용이 낮다. 

대신 최초 렌더링할때 비용이 더 높기 때문에 

전환이 자주 발생한다면 v-show를, 전환비용보다 최초 렌더링시 비용이 더 크다면 v-show를 선택하는 것이 좋다. 

 

#v-if 와 v-for 함께 사용하기 

v-if와 v-for를 함께 사용하는 것은 권장되지 않는다. 

//잘못된 코드
<ul>
  <li
    v-for="user in users"
    v-if="user.isActive"
  >
    {{ user }}
  </li>
</ul>

위 코드의 목표는 v-for로 users를 순회하면서 user의 isActive로 조건을 걸어 리스팅하는것이다.

하지만 위 코드를 실행하면 user프로퍼티를 찾을 수 없어 오류가 발생한다. 

v-if가 v-for보다 우선순위가 높기 때문에

users의 user를 설정하기 전에 if의 user 프로퍼티를 먼저 찾기 때문에 찾을 수 없다는 것이다. 

 

v-if와 v-for를 함께 사용하기 위해선

users를 먼저 필터링하거나 template 태그를 이용해 for지시어를 먼저 선언해주는 방법이 있다. 

 

* computed property 사용하기

<ul>
  <li
    v-for="user in activeUsers" //계산된 프로퍼티 내를 순회한다.
  >
    {{ user }}
  </li>
</ul>

computed: {
  activeUsers() { //users를 필터링하여 activeUsers를 정의한다. 
    return this.users.filter(user => user.isActive)
  }
}

 

* template tag 사용하기 

 

<ul>
  <template v-for="user in users"> //li를 래핑하고 li의 상위 레벨에서 for지시어를 사용함으로써 if보다 우선하게 한다
    <li v-if="user.isActive">
      {{ user }}
    </li>
  </template>
</ul>

 

#Vue Directive[ v-bind ]

데이터, id, class, style 바인딩 

 

   Vue.createApp({
        data(){
            return {
                textClass: 'primary',
                sectionid: 'tab1',
                sectionStyle: {color:'red'},
                isActive:true,
                hasError:false,
                classObject:{
                    active:true,
                    'text-danger':false
                }
            }
        }
    }).mount('#app');

 

* v-bind: 은 매우 자주 사용되기 때문에 v-bind를 생략하고 :만 붙여 사용할 수 있다. 

v-bind를 이용하면 컴포넌트의 data를 바인딩 할 수 있다.

v-bind는 컴포넌트의 {{property}}뿐만 아니라 id, class, style 등 태그의 속성도 바인딩할 수 있다.

바인딩하는 data는 객체 또는 배열도 가능하다.

 

<div :class="[textClass, {active: isActive}]">클래스 바인딩</div>

 

active의 클래스 여부가 isActive에 의해 결정된다. 

isActive가 true이므로 :class="[textClass, active] 배열이 되고 

class="primary active"가 된다. 

<div :id="sectionid" :style="sectionStyle">아이디 스타일 바인딩</div>

 

아이디와 스타일 바인딩의 예시이다. 

아이디는 문자열로, 스타일은 객체로 바인딩 되었다. 

 

<div class="static" :class="classObject">클래스 객체로 바인딩</div>

 

class="static"이 이미 존재하고 classObjecct가 바인딩된다. 

이때, classObject는 true인 active만 바인딩되고 false인 'text-danger'는 바인딩 되지 않는다. 

바인딩 결과는 static active가 된다.

 

<div :class="isActive ? textClass : ''">삼항연산 클래스 토글</div>

삼항 표현식을 사용할 수도 있다.

isAcitve이면 textClass가 바인딩된다.

삼항 조건의 결과값에는 문자열 또는 바인딩될 data가 들어간다. 

 

 

#Vue Component 등록

 

app이라는 root 컴포넌트에 자식 컴포넌트들을 등록한다.

 

components: {

   컴포넌트명: {body}

}

<div id="app">
    <app-header></app-header>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script>
    Vue.createApp({
        components: {
            //'component이름' :{body}
            'app-header': {
                template: '<h1>app 하위 컴포넌트 "app-header"</h1>'
            }
        }
    }).mount('#app');
</script>

#app 태그 내에  

<component명으로 태그를 작성한다.>

실행결과

dev tool의 Vue에 

<Root> 하위 <AppHeader>컴포넌트가 등록된 것을 확인할 수 있다.

 

 

 

#Component간 통신

 

Component는 event와 props로 데이터와 신호를 주고받는다. 

 

동일 레벨의 컴포넌트 간에 직접 통신은 불가능하다. 

상위 컴포넌트에 event를 발생시켜 데이터를 전달할 다른 하위 컴포넌트로 prop을 전달하는 방식으로 통신한다. 

 

Props

 

상위 컴포넌트에서 하위 컴포넌트에 전달하는 프로퍼티

 

* 하위 프로퍼티에 props 배열을 작성한다.

* html의 컴포넌트 태그에서 props를 바인딩한다. 

 

v-bind:prop명="prop에 바인딩할 상위 컴포넌트의 프로퍼티명"

 

<div id="app">
    <app-header v-bind:prop-title="title"></app-header>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script>
    const appHeader = {
        props:['propTitle'],
        template: `<p>{{propTitle}}</p>`,
    }
    Vue.createApp({
        data(){
            return {
                title: 'Title'
            }
        },
        components: {
            'app-header': appHeader,
        }
    }).mount('#app');
</script>

 

EventEmit

 

하위 컴포넌트에서 상위 컴포넌트로 이벤트를 발생시킴

 

* 하위 컴포넌트에서 this.$emit('발생시킬이벤트명') 을 작성한다.

* html의 컴포넌트 태그에서 이벤트 핸들러로 상위 컴포넌트에 메소드를 동작하게 한다. 

 

v-on:하위컴포넌트에서 발생시킨 이벤트명="상위컴포넌트에서 동작할 메소드명"

 

<div id="app">
    <app-header :prop-title="title"></app-header>
    <app-contents @set-title="changeProp"></app-contents>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script>
    const appHeader={
        props:['propTitle'],
        template:`<p>{{propTitle}}</p>`
    }
    const appContents={
        template: `<button v-on:click="sendEvent">제목</button>`,
        methods:{
            sendEvent(){
                this.$emit('setTitle');
            }
        }
    }
    Vue.createApp({
        data(){
            return{
                title:''
            }
        },
        methods:{
            changeProp(){
                this.title='newTitle'
            }
        },
        components:{
            'app-header':appHeader,
            'app-contents':appContents
        }
    }).mount('#app');
</script>

 

동일 레벨의 컴포넌트간 통신이 이루어지는 과정

 

-> appContents내의 버튼에서 클릭이벤트가 발생하면

-> appContents 컴포넌트에 setTitle 이벤트를 발생시킨다. 

->  setTitle 이벤트 핸들러에 의해 Root 컴포넌트의 changeProp함수가 실행된다.

->  changeProp 함수가 data를 갱신하고 

->  data가 변경됨에 따라 props의 propTitle도 변경된다. 

 

 

**html 태그 작성시 주의할점 

html 파일에서 vue를 사용할 때 카멜케이스를 사용하면 인식하지 못하기 때문에 -(하이픈)을 사용한다.

이러한 문제는 .vue 파일 형식과는 관계없이 .html 파일에만 해당한다. 

.vue 파일에는 카멜케이스로 작성하여도 된다. 

 

<div id="app">
    <app-contents @set-title="changeProp"></app-contents> //setTitle을 set-title로 changeProp은 속성명이 아닌 ""내의 문자열 값이기 때문에 관계 없다.
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script>
    const appContents={
        template: `<button v-on:click="sendEvent">제목</button>`, 
        methods:{
            sendEvent(){
                this.$emit('setTitle'); //카멜케이스
            }
        }
    }
    Vue.createApp({
        methods:{
            changeProp(){ //카멜케이스
                this.title='newTitle'
            }
        },
        components:{
            'app-contents':appContents //컴포넌트명은 html에 작성될 태그명이므로 - 사용
        }
    }).mount('#app');
</script>

 

 

'Vue.js' 카테고리의 다른 글

Vue.js form submit  (0) 2023.11.30
Vue.js 프로젝트 생성하기  (0) 2023.11.29
Vue.js Intro  (0) 2023.11.28

+ Recent posts