2023. 12. 29. 10:19ㆍ뷰(Vue)
이 글은 주 단위로 하던 스터디를 개인적으로 정리하는 글입니다.
이전글에서 5장까지 작성했는데 6장에는 그냥 CSS를 어떤방식으로 사용 할 수 있는지에 대한 설명이 대부분 이였다.
특정 변수값을 v-bind중 하나인 style에 넣어서 적용 시킬수도 있고 class에 추가 할 수도 있고 다양한 형태를 지원한다.
스타일(css) 적용에 대한 내용이다.
css의 적용은 기본적으로 동일하다.
요소의 기본 스타일 —> class로 명명된 순서에 따른 스타일적용 —> 인라인 스타일 적용.
ex) .test와 .over라는 클래스를 각각 명시했고 동일한 부분이 존재한다면 마지막에 명시한 스타일을 따라간다.
기본적으로 Vue에서도 인라인 스타일을 권장하지는 않는다.
그래도 사용해야하는 경우가 있다면 data 영역에 미리 명시를 해 두고 v-bind:style로 연결하여 사용한다.(06)
<div id="app">
<button id="a" :style="style1" @mouseover.stop="overEvent" @mouseout.stop="outEvent">테스트</button>
</div>
<script src="https://unpkg.com/vue"></script>
<script type="text/javascript">
var vm = Vue.createApp({
name: "App",
data() {
return {
style1: { backgroundColor: "aqua", color: "black" },
};
},
methods: {
overEvent() {
this.style1.backgroundColor = "purple";
this.style1.color = "yellow";
},
outEvent() {
this.style1.backgroundColor = "aqua";
this.style1.color = "black";
},
},
}).mount("#app");
</script>
또한 각각의 요소를 하나씩 변경하는게 아닌 여러개를 명시하여 적용이 가능하다.(06-04)
<div id="app">
<button id="btn1" :style="[ myColor, myLayout ]">버튼1</button>
</div>
<script src="https://unpkg.com/vue"></script>
<script type="text/javascript">
var vm = Vue.createApp({
name: "App",
data() {
return {
myColor: { backgroundColor: "purple", color: "yellow" },
myLayout: { width: "150px", height: "80px", textAlign: "center" },
};
},
}).mount("#app");
</script>
스타일은 다음과 같고 클래스를 적용하는건 비슷하게 동작한다. v-bind:class로 연결하여 사용하는 형태.
<style>
.buttonColor {
background-color: aqua;
color: black;
}
.buttonLayout {
text-align: center;
width: 120px;
}
.staticBorder {
border: khaki dashed 1px;
}
</style>
<div id="app">
<button class="staticBorder" :class="myColor">테스트 버튼</button>
</div>
<script src="https://unpkg.com/vue"></script>
<script type="text/javascript">
var vm = Vue.createApp({
name: "App",
data() {
return {
myColor: "buttonColor buttonLayout",
};
},
}).mount("#app");
</script>
하나씩 적용하는게 가능하여 myColor로 묶어서 여러개를 적용 시키는 모습을 볼 수 있다.
data에 지정된 true, false값을 연동하여 동적으로 class를 변경하는 형태의 코드도 제공한다. (06-07)
<head>
<meta charset="utf-8" />
<title>06-07</title>
<style>
.buttonColor {
background-color: aqua;
color: black;
}
.buttonLayout {
text-align: center;
width: 120px;
}
.staticBorder {
border: khaki dashed 1px;
}
</style>
</head>
<body>
<div id="app">
<input type="checkbox" v-model="isMyLayout" />레이아웃 적용 여부<br />
<button class="staticBorder" :class="[myColor, isMyLayout ? myLayout : '' ]">테스트 버튼</button>
</div>
<script src="https://unpkg.com/vue"></script>
<script type="text/javascript">
var vm = Vue.createApp({
name: "App",
data() {
return {
myColor: "buttonColor",
myLayout: "buttonLayout",
isMyLayout: false,
};
},
}).mount("#app");
</script>
</body>
아니면 아예 객체로 연결하여 편리하게 사용하는 형태로도 가능하다.
<head>
<meta charset="utf-8" />
<title>06-06</title>
<style>
.bColor {
background-color: aqua;
color: black;
}
.bLayout {
text-align: center;
width: 120px;
}
.bBorder {
border: khaki dashed 1px;
}
</style>
</head>
<body>
<div id="app">
<button :class="myStyle">버튼1</button>
<p>
<input type="checkbox" v-model="myStyle.bColor" value="true" />색상<br />
<input type="checkbox" v-model="myStyle.bLayout" value="true" />정렬,크기<br />
<input type="checkbox" v-model="myStyle.bBorder" value="true" />테두리선<br />
</p>
</div>
<script src="https://unpkg.com/vue"></script>
<script type="text/javascript">
var vm = Vue.createApp({
name: "App",
data() {
return {
myStyle: { bColor: false, bLayout: false, bBorder: false },
};
},
}).mount("#app");
</script>
</body>
계산된 속성(computed) 에서 특정 값의 변화에 따라 화면에 css 등의 변화를 줄 수도 있다.(06-10)
<head>
<meta charset="utf-8" />
<title>06-10</title>
<style>
.score {
border: solid 1px black;
}
.warning {
background-color: skyblue;
color: purple;
}
.warnimage {
width: 18px;
height: 18px;
top: 5px;
position: relative;
}
</style>
</head>
<body>
<div id="app">
<div>
<p>1부터 100까지만 입력가능합니다.</p>
<div>
점수 : <input type="text" class="score" v-model.number="score" :class="info" />
<img src="https://contactsvc.bmaster.kro.kr/img/error.png" class="warnimage" v-if="info.warning" title="1부터 100까지만 입력하세요." />
</div>
</div>
</div>
<script src="https://unpkg.com/vue"></script>
<script type="text/javascript">
var vm = Vue.createApp({
name: "App",
data() {
return { score: 50 };
},
computed: {
info() {
return { warning: this.score < 1 || this.score > 100 };
},
},
}).mount("#app");
</script>
</body>
data영역에 선언된 데이터들을 건드려서 DB나 비동기 없이 TODO list를 컨트롤 하는 부분이 책에 실려있다.(06-14)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>06-14</title>
<link rel="stylesheet" href="https://unpkg.com/bootstrap@5.2.3/dist/css/bootstrap.min.css" />
<style>
body {
margin: 0;
padding: 0;
font-family: sans-serif;
}
.title {
text-align: center;
font-weight: bold;
font-size: 20pt;
}
.todo-done {
text-decoration: line-through;
}
.container {
padding: 10px 10px 10px 10px;
}
.panel-borderless {
border: 0;
box-shadow: none;
}
.pointer {
cursor: pointer;
}
</style>
</head>
<body>
<div id="app" class="container">
<div class="card card-body bg-light">
<div classe="title">:: Todolist App</div>
</div>
<div class="card card-default card-borderless">
<div class="card-body">
<div class="row mb-3">
<div class="col">
<div class="input-group">
<input
id="msg"
type="text"
class="form-control"
name="msg"
placeholder="할일을 여기에 입력!"
v-model.trim="todo"
@keyup.enter="addTodo"
/>
<span class="btn btn-primary input-group-addon" @click="addTodo">추가</span>
</div>
</div>
</div>
<div class="row">
<div class="col">
<ul class="list-group">
<li
v-for="todoitem in todolist"
:key="todoitem.id"
class="list-group-item"
:class="{ 'list-group-item-success': todoitem.completed } "
@click="toggleCompleted(todoitem.id)"
>
<span class="pointer" :class="{ 'todo-done': todoitem.completed }">
{{todoitem.todo}} {{ todoitem.completed ? "(완료)" : "" }}
</span>
<span class="float-end badge bg-secondary pointer" @click.stop="deleteTodo(todoitem.id)"
>삭제</span
>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
<script src="https://unpkg.com/vue"></script>
<script type="text/javascript">
var ts = new Date().getTime();
var vm = Vue.createApp({
name: "App",
data() {
return {
todo: "",
todolist: [
{ id: ts, todo: "자전거 타기", completed: false },
{ id: ts + 1, todo: "딸과 공원 산책", completed: true },
{ id: ts + 2, todo: "일요일 애견 카페", completed: false },
{ id: ts + 3, todo: "Vue 원고 집필", completed: false },
],
};
},
methods: {
addTodo() {
if (this.todo.length >= 2) {
this.todolist.push({ id: new Date().getTime(), todo: this.todo, completed: false });
this.todo = "";
}
},
deleteTodo(id) {
let index = this.todolist.findIndex((item) => id === item.id);
this.todolist.splice(index, 1);
},
toggleCompleted(id) {
let index = this.todolist.findIndex((item) => id === item.id);
this.todolist[index].completed = !this.todolist[index].completed;
},
},
}).mount("#app");
</script>
</body>
</html>
그리고 나중에 기억에 남는 부분은 특정 컴포넌트에만 적용될 수 있도록 스코프를 지정 할 수 있는게 있었다.(8장에서 소개해주더라)
'뷰(Vue)' 카테고리의 다른 글
원쌤의 Vue.js 퀵스타트 책을 보았다(Vue3)_7 (2) | 2024.01.03 |
---|---|
원쌤의 Vue.js 퀵스타트 책을 보았다(Vue3)_6 (1) | 2024.01.03 |
원쌤의 Vue.js 퀵스타트 책을 보았다(Vue3)_4 (0) | 2023.12.20 |
원쌤의 Vue.js 퀵스타트 책을 보았다(Vue3)_3 (1) | 2023.12.20 |
원쌤의 Vue.js 퀵스타트 책을 보았다(Vue3)_2 (1) | 2023.12.05 |