본문 바로가기
게시판

(✧ ˆᴗˆ)o︻╤╦╾━ ・:*:・゚=͟͟͞͞♡ Vue 3 공부하기 (ajax, slot, mitt, Vuex, PWA, Composition API)

by Seolyu 2024. 3. 15.

 

Vue 3 공부하기 (ajax, slot, mitt, Vuex, PWA, Composition API)
뷰 공부해야해서 코딩 애플 공부하면서 정리한거

 

레이아웃 제작 후 ..

데이터는 assets 안에 postdata.js 로 넣고

 

App.vue에선

 

그리고 props 보내는건

App.vue 에선

 

ConTainer.vue 에선

 

그리고 PosT에 보내기 위해

반복문으로 하면

 

PosT.vue 에선

 

 

이미지 데이터 바인딩의 경우,

background-image: url() 

이렇게 넣는다

 

에러나서

옵셔널 체이닝 사용함


 

'더보기' 게시물 가져오기 위해 ajax 사용

 

GET, POST 요청은 URL 잘 적어서 요청하는 것이며

GET은 데이터 서버에서 가져올 때

POST는 서버로 데이터를 보낼 때 씀

 

두 요청 모두 브라우저가 새로고침됨

ajax 쓰면 새로고침 없이 요청 가능

 

ajax 요청하려면

  1. axios 라이브러리 사용
  2. 기본 fetch 함수 사용

 

npm install axios

또는

yarn add axios

 

axios 요청할 곳에

 

 

'더보기' 버튼

  1. 서버에서 추가 게시물 가져옴
  2. 가져온 게시물을 <PosT>로 보여주기

 

 

function(){} 대신

()=>{} 사용하자

 

 

 

참고로 axios의 post 요청은

axios.post()

실패 시 실행할 코드는 .catch()

 

 

만약 버튼을 한번 눌렀을 땐 more0.json

두번 눌렀을 땐 more1.json으로 요청하려면,

먼저 버튼 누른 횟수를 저장할 데이터 만들고


 

tab UI는

 

UI 현 상태 데이터로 만들기

상태에 따라 HTML 어떻게 보일지 작성

 

 

페이지 2개를 만들어보자

vue-router 써도 되지만

tab UI 써도 될 것 같다

 

ConTainer에

 

그리고

App.vue에는 현재 페이지 상태(step 이라는 이름으로) 저장하고

step이 0이면 포스트들이 보이고

step이 1이면 필터 선택 화면 보이고

step이 2이면 글 쓰는 화면 보이게 할 것이다

 

App.vue에 있는 step을 props로 보내자

 

그리고 ConTainer에서는 step 등록

 

v-if 로 가져다 쓴다

 

근데 v-for와 v-if 한 곳에 못 쓰니까(Vue 3)

위와 같이 굳이 라우터 안써도 간단한건 tab으로 구현 가능


 

이미지 업로드

HTML에서 보여주려면?

→ 업로드한걸 서버로 보내 저장시키고 해당 URL을 유저에게 보냄 (img src="")

→ 요즘은 브라우저에서 이미지 다루는 함수를 사용한다 ( FileReader(), URL.createObjectURL() )

 

input 태그에 함수 만들자

 

binary 데이터 다룰 시

BLOB 오브젝트에 담아서 다룬다

 

input 여러개 받으려면 multiple 속성 추가

 

이미지만 선택할 수 있도록(받을 수 있도록X) 하려면 accept="image/*"

실제로 이미지만 받으려면 자바스크립트로 확장자 검사해서 구현

type 찍어볼 수 있음

 

data가 아니라 methods 함수 안 변수는 어떻게 props 전송할까?

데이터 추가하고(이미지)

this.이미지 에 url 넣기

그리고 이렇게 props 보내고

 

ConTainer 컴포넌트(자식)에서는

 

이제 Next 버튼 눌렀을 땐 다음 step 가야하니까

 

글 발행 기능은

게시물 데이터에 하나 추가하면 된다

 

일단 발행 버튼 추가

step이 2일 때 보이는 발행 버튼

 

왼쪽의 array에 자료 집어넣는건 unshift

 

ConTainer.vue에 textarea 부분은

커스텀 이벤트 문법으로 App.vue에 입력한 글 전송

 

App.vue에서는,


 

필터 박스 만들기

FilterBox.vue 만들고 ConTainer.vue 에 import

 

FilterBox.vue 안에 업로드한 이미지 배경으로 넣자

ConTainer.vue 의 props 목록 안에

이미지가 있으므로

props로 보내기

 

FilterBox.vue 에서는

 

필터박스 여러개

 

CSSgram 설치해서 인스타 필터 기능 완성

(cssgram.css 파일 첨부)

<img class="인스타필터명">

 

실제 메인페이지인 index.html에

cssgram의 css 파일 첨부한다

 

필터명 채우는건

필터 보내고

 

FilterBox.vue 에서는

 

필터명도 표시해주자

props 아닌 slot 써보자

slot은 HTML 내용물을 데이터 바인딩할 때 씀 (HTML도 전송됨)

자식 컴포넌트에는 저렇게 <slot></slot> 해주고
부모에는 저렇게

 

slot을 여러개 쓸 땐

slot에 이름 주고
부모에서는 이렇게 보냄

 

여러개일 땐 slot보다 props가 나음

 

slot props는

slot 사용 시 부모가 자식데이터 쓸 때

자식 데이터 이런거 보내려면

<slot :자식데이터="자식데이터">
<template v-slot:default="작명">{{작명.자식데이터}}


 

필터 박스 클릭 시 기능 만들기

 

필터 박스 클릭 시 App.vue에 클릭한 필터명 전달하려면

custom event 2번 써야하는 상황이라

mitt 라이브러리 사용하자

 

mitt 쓰면 보내고자 하는 컴포넌트에 데이터 바로 전송 가능

 

npm install mitt

 

main.js에 mitt 라이브러리 세팅

이렇게 자주 쓰는 라이브러리 등록하면 됨

 

mitt 동작 방식은

발사(fire) - 이벤트 전송

수신(listen) - 이벤트 수신

 

발사는

this.emitter.emit()으로 발사

 

수신은

mounted 안에 작성

 

근데 많이 쓰면 관리 힘들어서

Vuex 쓴다

 

 

필더 박스 클릭 시

큰 사진에도 필터명 반영

발행한 게시물에도 반영

되어야 함

 

먼저,

필터 박스 클릭 시

App.vue로 필터명 전송하자

@click="fire"

 

App 과 Container

둘다 FilterBox 이벤트 수신하자

 

그리고 step 2인 경우에도 필터 되도록

 

App.vue에서도

 

그리고 ConTainer.vue 에서 사용했던 데이터 수신하는 코드 똑같이 작성하고

데이터 저장할 수 있는 공간 작성

 

Post.vue 에도 필터 바인딩을 한다


 

Vuex

props, custom event / mitt 은 사용하기 힘들기 때문에 Vuex 쓰자

 

js 파일 하나에 데이터들 몰아넣을 수 있다

코드는 길어진다

 

npm install vuex@next

 

세팅은

모든 컴포넌트가 쓸 수 있는 데이터(state) 저장용 js 파일 만든다

 

그리고 main.js에 등록한다

 

state는

이렇게 작성하면 된다

 

가져다 쓰는건

 

변경하는건

 

하지만 store.js에 있는 state는 이렇게 변경하면 안된다

컴포넌트 안에서 직접 수정하기 금지

 

state 수정하려면

store.js에 수정 방법을 미리 정의해둬야한다

그리고 그 방법을 컴포넌트로 가져와서 수정(store.js 에게 수정 부탁)해야한다

 

먼저 store.js에서

mutations에 저렇게 적는다

 

그리고 컴포넌트에서는

 

증가 함수에서 원하는만큼 ++ 하려면?

 

좋아요 기능은?

1. likes 라는 state 만들기

 

 

2. 사진 누르면 likes + 1

mutations 함수 만들기

 

좋아요 눌렀는지 안눌렀는지 알려면?

좋아요눌렀니 state 추가

 

3. 사진들 개별적으로 좋아요 카운트하려면?

알아서 하기

 

 

actions는 ajax 요청 or 오래걸리는 작업들 하는 곳

 

더보기 게시물 ajax 요청 하려면?

먼저 axios를 import

 

그리고

store의 state에 추가

서버에서 더보기 게시물 가져와서 more에 저장해보자

 

mutations 안에다가 ajax 요청하면 안됨

actions에다가 요청해야하고,

actions 후에 state 변경해야하는데

state 변경은 무조건 mutations가 함

 

commit은 mutations 부탁하는거고 dispatch는 actions 부탁하는거

 

 

함수만들 때

methods: {}

computed: {}

 

차이는?

 

methods 함수는 사용할 때마다 실행

computed는 사용해도 실행되지 않음

처음 실행하고 값을 간직함

컴퓨팅 파워 절약 가능

계산 결과 저장용 함수들

 

버튼 누를 때마다 p 쪽 재렌더링됨

함수 실행 여부 테스트

 

methods 안 함수는 버튼 누를 때마다 함수 재실행됨

 

반면, 

computed 안 함수는 재실행 안됨

computed 함수는 () 안붙임. 계산 결과 저장하는 곳이라

 

computed 함수는 필요할 때만 실행됨

데이터 계산 결과 저장하는 공간이라고 보면 됨

 

store에 있는 데이터 쉽게 코드 짧게 가져다쓰는 mapState 

 

state 하나 꺼내쓸 때도 computed 안에 사용

computed 함수는 return 꼭 적어야함

 

근데

코드 길어짐

 

vuex state 한번에 꺼내쓰기

...mapState(['state이름'])

위와 같이 사용하면 되는데

 

이런 식으로 사용할 수도 있다

 

vuex mutations 한번에 꺼내쓰는건

mapMutations 임포트

methods 안에

그리고

이걸

이렇게 사용하면 된다


 

지금 만든거 모바일 앱으로 

PWA (앱같지만 브라우저로 동작하는거임)

 

PWA 되려면

manifest.json

service-worker.js

필요함

 

직접 만들진 않고

pwa 기능 제공하는 라이브러리 설치하자

 

vue add pwa

 

프로젝트 build(npm run build 하면 배포용 html 생성함)할 때 저 위 2개 파일 생성해줌

 

dist 폴더에 html, css, js 완성본 담겨있고

manifest.json ← 앱 정보 담는 파일

service-worker.js

이것도 생긴다

 

service-worker.js 의 경우,

실제 모바일앱은 인터넷 없어도 사용이 가능하지만 웹 사이트는 그렇지 않은데

웹 페이지 구동에 필요한 html css js img 하드에 미리 저장해둬서 오프라인에서도 동작할 수 있도록 함

 

PWA 설정 바꾸려면,

vue.config.js 에서 설정 가능

exclude에 array로 캐싱 목록에서 제외(하드 저장X)하고 싶은 파일명 쓰면 됨

 

추가적인 설정은 workbox 라이브러리 or vue pwa 구글링

github pages에 발행해도 pwa처럼 사용 가능


 

Vue.js devtools 크롬 확장 프로그램 설치

 


 

이전에 했던건 Options API

 

프로젝트가 커지면

Composition API (setup() 안에 코드 짬) 사용한다

관련있는 코드를 한 곳에 모을 수 있다

 

setup() 안에서 데이터 생성, 조작, methods, computed, watch 만들기, hook 걸기 가능

즉 거의 모든 기능 개발 setup()에서 가능

 

ConTainer.vue에 step 3 마이페이지 만들자

 

step 3으로 바꾸고 작업

 

public 폴더에 follower.json 만들기

json 데이터는 따옴표 쳐있는 array object

 

public 폴더는 build 해도 안변한다

그래서 여기있는 파일 GET 요청 가능

 

json 데이터 axios로 가져오면

json → object 자동 변환

 

setup() 안에서 데이터 생성할 땐

ref

ref()

즉 reference data type으로 감싸야 실시간 반영 가능하다

그리고 return {} 해줘서 사용한다

 

ajax로 팔로워 데이터 가져와서 저장해보자

 

setup(){} 안에 작성하는건

created() hook 안에 작성하는 것과 비슷하다

 

Composition API 안에서

Ajax 요청하고 데이터 변경하려면 데이터.value 써야함

 

Composition API에서 라이프사이클 훅 쓸 땐

onMounted(() => {실행할코드})

vue 파일들에 있던 css는 하나로 합쳐지는데

그렇게 하는게 싫으면

<style scoped>

 

 

데이터 만들 때 ref() 말고

reactive() 도 있음

reactive()는 보통 array, object 넣음

 

toRefs() 도 있는데

ConTainer.vue → MyPage.vue

Props 보내보자

Composition API에서 props 사용하려면..

setup에 첫번째 파라미터는 props임

두번째 파라미터는 attrs, slots, emit 담겨있음

props 그냥 쓰면 실시간 반영 안될 수 있으므로 ref() 로 감싸주는데

props는 항목이 보통 여러개라 toRefs() 로 감싼다

toRefs 임포트.. { }는 Destructuring 문법

 

사용할 땐 .value

 

 

그리고 Composition API에서 watch 사용하는 방법은

watch(감시할거, ()=>{실행할코드})

watch import 하고

 

 

Composition API에서 computed 사용하는 방법은

computed import 하고

근데 follower.value에 아무것도 없어서 0 출력됨

 

 

Composition API에서 vuex store 사용하는 방법은

useStore 임포트 하고

 

Composition API에선 mapState 못 쓰는게 단점 (Vuex 5 미만)

 

 

Composition API에서 methods 함수 만들기

 

 

검색 기능의 경우,

데이터를 조작하여 구현

 

하지만 위와 같이 구현하면 원본 데이터가 손실됨

그러므로

원본 저장할 state인 followerOriginal 만듦

 

이렇게 하면 된다