Intel Chip Macbook Pro (2019)
MacOS Monterey 12.6.2
Vue.js 3
Visual Studio 설정에서 Default Formatter - Prettier 설정, Format On Save 체크 설정하기
.prettierrc 파일을 생성하고 { "semi": false, "bracketSpacing": true, "singleQuote": true, "useTabs": false, "trailingComma": "none", "printWidth": 80 } 내용 추가package.json 파일에서 eslintConfig 부분에 "rules": { "space-before-function-paren": "off" } 내용 추가특정 영역이 여러 군데에 재사용 가능하다면 components 폴더에 만들기
화면 전체를 차지하는 컴포넌트는 views 폴더에 만들기
visual studio 설정 > User Snippets 이동
검색창에 vue 입력 -> vue 선택
"Generate Basic Vue Code" : { "prefix": "vue-start", "body": [ "<template>\n\t<div></div>\n</template>\n<script>\nexport default {\n\tcomponents: {},\n\tdata () {\n\t\treturn {\n\t\t\tsampleData: ''\n\t\t}\n\t},\n\tsetup () {},\n\tcreated() {},\n\tmounted() {},\n\tunmounted() {},\n\tmethods: {}\n}\n</script>" ], "description": "Generate Basic Vue Code" }
import { createRouter, createWebHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'
const routes = [
{ // component 호출 방법 1: app.js에 들어감
path: '/',
name: 'home',
component: HomeView
},
{ // component 호출 방법 2: lazy load 방식
path: '/about',
name: 'about',
component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')
}
{ // component 호출 방법 3: Prefetch 방식
path: '/about2',
name: 'about2',
component: () => import(/* webpackChunkName: "about2", webpackPrefetch:ture */ '../views/AboutView.vue')
}
]
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes
})
export default router
webpackChunkName 을 같은 이름으로 설정해주면 해당하는 메뉴중 하나가 처음 로딩 될 때 그룹핑된 다른 것들도 함께 로딩됨webpackPrefetch 설정 시 초기화면 로딩 시에 설정해둔 페이지도 함께 캐싱됨{{ }}<template>
<div>
<h1>Hello {{ userName }}</h1>
<p>{{ message }}</p>
</div>
</template>
<script>
export default {
data() {
return {
userName: 'John Doe',
message: ''
}
}
}
</script>
v-html<template>
<div v-html="htmlString"></div>
</template>
<script>
export default {
data() {
return {
htmlString: '<p style="color:blue;">파란색</p>'
}
}
}
</script>
v-model<template>
<div>
<input type="text" v-model="userId" />
<button @click="myFunction">click</button>
<button @click="changeData">change</button>
<br />
<input type="text" v-model.number="num1" /> +
<input type="text" v-model.number="num2" /> =
<span>{{ num1 + num2 }}</span>
</div>
</template>
<script>
export default {
data() {
return {
userId: 'hwwwa', // default value
num1: 0,
num2: 0
}
},
methods: {
myFunction() {
console.log(this.userId)
}
}
}
</script>
<template>
<div>
<select v-model="selectedCity">
<option value=""></option>
<option value="02">Seoul</option>
<option value="051">Busan</option>
<option value="053">Daegu</option>
</select>
</div>
</template>
<script>
export default {
data() {
return {
selectedCity: '02'
}
}
}
</script>
<template>
<div>
<div>
<input type="checkbox" id="html" value="HTML" v-model="favoriteLang" />
<label for="html">HTML</label>
</div>
<div>
<input type="checkbox" id="css" value="CSS" v-model="favoriteLang" />
<label for="css">CSS</label>
</div>
<div>
<input type="checkbox" id="js" value="JS" v-model="favoriteLang" />
<label for="js">JS</label>
</div>
<div>Lang: {{ favoriteLang }}</div>
</div>
</template>
<script>
export default {
data() {
return {
favoriteLang: ['JS']
}
}
}
</script>
input type="radio"로 변경해주고 하나만 선택 가능하므로 변수도 문자열로 선언 favoriteLang: 'JS'v-bind:v-bind:로 속성 값에 데이터를 바인딩v-bind를 생략하고 :만 사용 가능<template>
<div>
<input type="text" v-bind:value="userId" readonly />
<input type="text":value="userId" readonly />
<br />
<img :src="imgSrc" alt="" style="width: 100px; height: auto" />
<br />
<input type="search" v-model="txt1" />
<button :disabled="txt1 === ''">search</button>
</div>
</template>
<script>
export default {
data() {
return {
userId: 'hwwwa',
imgSrc: 'https://upload.wikimedia.org/wikipedia/commons/f/f1/Vue.png',
txt1: ''
}
}
}
</script>
v-for<template>
<div>
<div>
<select name="" id="">
<option value=""></option>
<option :value="city.code" :key="city.code" v-for="city in cities">
{{ city.title }}
</option>
</select>
</div>
<div>
<table>
<thead>
<tr>
<th>ProductNum</th>
<th>ProductName</th>
<th>Price</th>
<th>Quantity</th>
<th>Sum</th>
</tr>
</thead>
<tbody>
<tr :key="idx" v-for="(drink, idx)in drinkList">
<td>{{ drink.drinkId }}</td>
<td>{{ drink.drinkName }}</td>
<td>{{ drink.price }}</td>
<td><input type="number" v-model="drink.qty" /></td>
<td>{{ drink.price * drink.qty }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</template>
<script>
export default {
data() {
return {
cities: [
{ title: 'Seoul', code: '02' },
{ title: 'Busan', code: '051' },
{ title: 'Daegu', code: '064' }
],
drinkList: [
{
drinkId: '1',
drinkName: 'coke',
price: 700,
qty: 1
},
{
drinkId: '2',
drinkName: 'orange juice',
price: 1200,
qty: 1
},
{
drinkId: '3',
drinkName: 'coffee',
price: 500,
qty: 2
}
]
}
}
}
</script>
<template>
<div>
<div :class="{ 'text-blue': hasError, active: isActive }">
Class Binding1
</div>
<div :class="class2">Class Binding2</div>
</div>
</template>
<script>
export default {
data() {
return {
isActive: false,
hasError: true,
class2: ['text-blue', 'hasError']
}
}
}
</script>
<style scoped>
.active {
background-color: greenyellow;
font-weight: bold;
}
.text-blue {
color: blue;
}
</style>
<template>
<div>
<div :style="style1">Style Binding: text blue, font 30px</div>
<button @click="style1.color = 'green'">color change</button>
</div>
</template>
<script>
export default {
data () {
return {
style1: {
color: 'blue',
fontSize: '30px'
}
}
}
}
</script>
<template>
<div>
<button @click="increaseCounter">Add 1</button>
<p>{{ counter }}</p>
</div>
</template>
<script>
export default {
data () {
return {
counter: 0
}
},
methods: {
increaseCounter() {
this.counter += 1
}
}
}
</script>
<template>
<div>
<!--v-on:change를 @change로 바꿔서 사용 가능-->
<select name="" id="" @change="changeCity($event)" v-model="selectedCity">
<option value="">==select city==</option>
<option :value="city.cityCode" :key="city.cityCode" v-for="city in cityList">
{{ city.title }}
</option>
</select>
<select name="" id="">
<option :value="dong.dongCode" :key="dong.dongCode" v-for="dong in selectedDongList">
{{ dong.dongTitle }}
</option>
</select>
</div>
</template>
<script>
export default {
data () {
return {
selectedCity: '',
cityList: [
{ cityCode: '02', title: 'Seoul' },
{ cityCode: '051', title: 'Busan' },
{ cityCode: '053', title: 'Daegu' }
],
dongList: [
{ cityCode: '02', dongCode: '1', dongTitle: 'Seoul 1dong' },
{ cityCode: '02', dongCode: '2', dongTitle: 'Seoul 2dong' },
{ cityCode: '051', dongCode: '1', dongTitle: 'Busan 1dong' },
{ cityCode: '051', dongCode: '2', dongTitle: 'Busan 2dong' },
{ cityCode: '053', dongCode: '1', dongTitle: 'Daegu 1dong' },
{ cityCode: '053', dongCode: '2', dongTitle: 'Daegu 2dong' }
],
selectedDongList: []
}
},
methods: {
changeCity(event) {
console.log(event.target.tagName)
this.selectedDongList = this.dongList.filter((dong) => dong.cityCode === this.selectedCity)
}
}
}
</script>
<template>
<div>
<!--방법1-->
<input type="search" @keyup="checkEnter($event)" v-model="searchText" />
<button @click="doSearch">Search</button>
<br />
<!--방법2. keyup의 다양한 기능 사용하기-->
<input type="search" @keyup.enter="doSearch" v-model="searchText" />
<button @click="doSearch">Search</button>
</div>
</template>
<script>
export default {
data () {
return {
searchText: ''
}
},
methods: {
doSearch() {
console.log(this.searchText)
},
checkEnter(event) {
if (event.keyCode === 13) {
this.doSearch()
}
}
}
}
</script>