Router
Router를 사용하지 않고 CSS :Active를 사용할수있다.
<script>
import { ref, onMounted, computed } from "vue"
let path = ref("")
onMounted(() => {
path.value = "/"
})
</script>
<template>
<aside>
<ul class="menu-list">
<li :class="{ active: path === '/url/parser' }"
@click="path = '/url/parser'">
<RouterLink to="/url/parser">URL Parser</RouterLink>
</li>
<li :class="{ active: path === '/url/encoder/decoder' }"
@click="path = '/url/encoder/decoder'">
<RouterLink to="/url/encoder/decoder">URL Encoder & Decoder</RouterLink>
</li>
<li :class="{ active: path === '/base64/encoder/decoder' }"
@click="path = '/base64/encoder/decoder'">
<RouterLink to="/base64/encoder/decoder">BASE64 Encoder & Decoder</RouterLink>
</li>
<li class="feedback">Feedback</li>
</ul>
</aside>
</template>
: script부분에서 composition API 구조를 활용하여 state를 ref로 관리하고
onMount()를 사용하여 전체 랜더링 후 페이지 path만 바뀌게끔 해주었다.
그리고 css를 이용하여 사이드바 부분에 active를 주어서 @click이벤트에 path를 넣어주고
class에도 active: path를 넣어준다. 그리고 버튼을 누른경우 css를 주었다.
menu-list > li.active{ font-weight:bold}
결론적으로 사이드바 버튼을 눌렀을 경우 그 path로 이동하여 path페이지를 보여준다.
Vuex
index > App > Header > Home/About
index는 라우터 부분을 컨트롤 한다.
views폴더 안에 있는 Home.vue는 페이지 안쪽을 담당
Components폴더 안에 있는 파일을 Header.vue로 바꾸고 이부분을 컴포넌트로 사용하여 home부분보다 위에 Header부분으로 사용한다.
App.vue가 전체적인 페이지를 담당하고 App.vue에서 import를 해주고
export의 components에 header를 그리고 템플릿 부분에 Header컴포넌트를 바인딩 처리해준다.
<template>
<Header />
<router-view/>
</template>
<script>
import Header from '@/components/Header'
export default{
components:{
Header,
},
}
</script>
Pinia
전체적인 css를 관리해주는
Tailwind.config.js파일에서
module.exports = {
purge: ['./public/**/*.html', './src/**/*.{vue,js,ts,jsx,tsx}'],
darkMode: false, // or 'media' or 'class'
theme: {
extend: {},
container:{
center:true,
padding: '2rem',
}
},
variants: {
extend: {},
},
plugins: [],
}
이런식으로 App.vue에서 class=“container”를 사용한 다음
container에 전역으로 포스 css를 넣어준다.
그리고 이제 본격적으로 꾸며주기 위한 css를 넣어주고 header부터 꾸며준다.
API / Icons
https://documenter.getpostman.com/view/10808728/SzS8rjbc#00030720-fae3-4c72-8aea-ad01ba17adf8
API관련 정보와 키를 가져온다.
https://cdnjs.com/libraries?q=font
<I class=“fa fa-virus>
Icon을 사용하려면 link를 임포트하고 이런식으로 사용해준다.
Emit
부모 / 자식 컴포넌트와 서로 소통하여 함수를 호출하거나 파라미터값을 넘겨주는 이벤트 통신을 한다.
부모
-컴포넌트
<Alert @show-confirm="copyConfirm" v-show="isShow" />
-함수
function copyConfirm(showConfirm: any) {
isShow.value = showConfirm
document.body.style.pointerEvents = "auto"
}
그러면 Alert컴포넌트 선언한 부분에서 @show-confirm으로 받고 copyConfirm이라는
함수를 하나 새로 만들어서 그 함수 안에서 활용해준다.
function copyConfirm(파라미터){
isShow.value = showConfirm
이렇게 만든 함수에서 파라미터를 받아서 사용해준다.
}
자식
let showConfirm = ref(false)
<button class="close-btn" @click="$emit('show-confirm', showConfirm)"></button>
부모에게 보낼 변수를 선언해주고 버튼에 클릭이벤트가 있는경우 클릭했을때, $emit통신을 통하여
show-confirm 이라는 변수를 만들어 부모에게 올려주고 선언했던 변수 파라미터인 'showConfirm'를 올려준다.
Props / ref
부모 / 자식 컴포넌트와 서로 소통하여 함수를 호출하거나 파라미터값을 넘겨준다.
부모
-props
<Alert :title="show.alertTitle" :text="show.alertText" :show="isShow" ref="showConfirm" v-show="isShow" />
//=>props = 자식에게 넘겨줄 props 변수 title과 text를 저렇게 표현하여 사용한다.
-ref
<Alert :title="show.alertTitle" :text="show.alertText" :show="isShow" ref="showConfirm" v-show="isShow" />
//=>ref = ref를 이용하여 자식 컴포넌트에 ref를 주고 그것을 활용한다.
async function copyData() {
await navigator.clipboard.writeText(encodedUrl.value)
show.alertTitle.value = "Title"
show.alertText.value = "Copy Successful."
isShow.value = true
document.body.style.pointerEvents = "none"
showConfirm?.value?.copyConfirm(show.alertText)
}
//=>copyData함수가 호출되었을때 자식 컴포넌트에 지정해준 ref를 활용해 자식컴포넌트에 있는 copyConfirm()함수를 호출한다.
그것을 통해서 자식 함수가 호출되고 파라미터값을 props로 내려줄수도있다.
자식
import { ref, reactive, defineProps, defineExpose } from "vue"
-props
const props = defineProps({
title:Object,
text:Object,
})
let atitle = props.title
let atext = props.text
<p class="text-[12px] text-[#6B7280] font-['Ubuntu'] font-[500]">{{ atitle }}</p>
//=>위에서 props라는 오브젝트를 만들고 defineProps를 사용하여 title과 text를 받아왔다.
그리고 atitle이라는 변수에 새로 담아서 활용해준다.그리고 템플릿 안에서는 {{atitle}}이렇게 표현해준다.
-ref
function copyConfirm(wow: any) {
console.log(wow.value)
}
//=>위에서 부모가 호출한 함수인 copyConfirm이다. 그리고 호출하면서 파라미터인 show.alertText값을 자식에게 내려주어
wow라는 변수로 받아서 함수안에서 사용하거나 다른 변수에 다시 옮겨서 활용해줄수있다.
Typescript / vue.js(ComponentAPI)
Vue3와 Typescript를 쓰면서 vu2기반이 아닌 componentAPI를 사용한다.
element요소를 가져오거나 사용하여 style css를 줄 경우(setTimeout() / e.target.nextSibling)을 이용하였다.
let el = document.getElementById("modal")
Object.assign(el?.style, { display: "" })
//=>이렇게 ID값을 불러와서 그 부분에 style을 준다.
let el = ((<HTMLElement>document.querySelector(".tooltiptext")).style.visibility = "visible")
setTimeout(function () {
;(<HTMLElement>document.querySelector(".tooltiptext")).style.visibility = "hidden"
}, 1000)
//=>이렇게 setTimeout()함수를 이용해서 1초뒤에 없어지게끔 어느정도의 유지를 해줄수있다.
const ele = e.target.nextSibling
ele.style.display = ""
setTimeout(function () {
ele.style.display = "none"
}, 1000)
}
//=>아니면 이렇게 nextSibling을 이용하여 타겟된 태그 다음 태그의 style을 바꿔줄수있다.
e.target의 class를 잡아서 style을 수정해준다.
async function clickCopy(result: any, e: any) {
const ele = e.target.nextSibling
ele.style.display = ""
setTimeout(function () {
ele.style.display = "none"
}, 1000)
}
//=>아니면 이렇게 nextSibling을 이용하여 타겟된 태그 다음 태그의 style을 바꿔줄수있다.
e.target.classList.remove('class_name');
e.target.classList.add('class_name');
//=>타겟에 클레스의 css를 부여하거나 지워줄수있다.
Vue 문법(v-for / v-if등등)
만약에 vuex를 쓰는경우에 문법적인 부분이다.
v-for
<template>
<div v-for="(product, index) in products" :key="product.name">
{{product.name}}
img
<div>{{product.cost}}</div>
</div>
</template>
export default{
name: "App",
data: () => {
return{
cart: [],
products: [
{
name: "hair",
cost: "99W",
img: ~~~,
},
{
name: "hair",
cost: "99W",
img: ~~~,
},
]
}
: 이런식으로 products를 만들어주고 for문을 이용하여 index와 props부분들을 사용한다.
v-if
<template>
<div v-if="page === 'products'">
<h1>Products</h1>
</div>
</template>
export default{
name: "App",
data: () => {
return{
page: "products",
cart: [],
products: [
{
name: "hair",
cost: "99W",
img: ~~~,
},
{
name: "hair",
cost: "99W",
img: ~~~,
},
]
}
: 이런식으로 page에 값을 부여해 if문을 활용하여 router형식으로 사용한다.