반응형

KaKao Map은 html script를 통해 지도를 불러올 수 있다.

Nuxt에서 html head에 script를 추가하기 위해서는  Nuxt Config에 다음을 작성하면 브라우저가 불러져 올때 script가 추가가 된다.

app: {
    head: {
      script: [
        {
          type: "text/javascript",
          src: `//dapi.kakao.com/v2/maps/sdk.js?appkey=${process.env.KAKAO_MAP_KEY}`,
        },
      ],
    },
  },
// kakaomap.vue

<script setup lang="ts">
interface IKakaoMapProps {
  width: number | string;
  height: number | string;
}
defineProps<IKakaoMapProps>();
onMounted(() => {
  //@ts-ignore
  kakao.maps.load(() => {
    const container = document.getElementById("map");
    const options = {
      //@ts-ignore
      center: new kakao.maps.LatLng(33.450701, 126.570667),
      level: 3,
    };
    //@ts-ignore
    const map = new kakao.maps.Map(container, options);
  });
});
</script>
<template>
  <div id="map" :style="`width:${width};height:${height}`"></div>
</template>
728x90

'VueJS > NUXT' 카테고리의 다른 글

Nuxt3__Data Fetch  (0) 2023.11.22
NuxtJS__app, layout, pages, components, errorpage  (1) 2023.11.14
반응형

Data Fetch 

Nuxt의 문서에서 Data Fetch와 관련한 문서를 보면$fetch /  useAsyncData / useFetch 로 나누어져 있다. 

<script setup lang="ts">
// SSR 동안 데이터는 서버에서 한 번, 클라이언트에서 한 번, 총 두 번 가져옵니다.
const dataTwice = await $fetch('/api/item')

// SSR 중에는 데이터가 서버 측에서만 가져와 클라이언트로 전송됩니다.
const { data } = await useAsyncData('item', () => $fetch('/api/item'))

//useAsyncData + $fetch의 바로가기로 Fetch를 사용할 수도 있습니다.
const { data } = await useFetch('/api/item')
</script>

 

$fetch

(https://nuxt.com/docs/api/utils/dollarfetch)

$fetch는  클라이언트 측에서만 실행되는 모든 메소드에 사용할 수 있습니다 .

또한 useAsyncData로 래핑하지 않고 구성 요소에서 $fetch를 사용하면 데이터를 두 번 가져오게 됩니다.

처음에는 서버에서, 그 다음에는 하이드레이션 중에 클라이언트 측에서 다시 가져옵니다.

$fetch가 서버에서 클라이언트로 상태를 전송하지 않기 때문입니다.

따라서 클라이언트가 데이터를 다시 가져와야 하므로 가져오기는 양쪽에서 실행됩니다.

 

클라이언트 측에서만 실행되는 모든 메소드에 사용할 수 있다.

// ./page/contact.vue
<script setup lang="ts">
function contactForm() {
  $fetch('/api/contact', {
    method: 'POST',
    body: { hello: 'world '}
  })
}
</script>

<template>
  <button @click="contactForm">Contact</button>
</template>

$fetchNuxt 2용으로 만들어진 @nuxt/http  @nuxtjs/axios 대신 Nuxt에서 HTTP 호출을 수행하는 데 선호되는 방법입니다 .

useAsyncData

(https://nuxt.com/docs/api/composables/use-async-data)

useAsyncData는 SSR 친화적인 컴포저블에서 비동기적으로 확인되는 데이터에 대한 액세스를 제공합니다.

페이지, 컴포넌트 및 플러그인 내에서 useAsyncData를 사용하여 비동기적으로 확인되는 데이터에 액세스할 수 있습니다.

<script setup>
const { data, pending, error, refresh } = await useAsyncData(
  'mountains',
  () => $fetch('https://api.nuxtjs.dev/mountains')
)
</script>

Watch 매개변수

내장 watch옵션을 사용하면 변경 사항이 감지되면 페처 기능을 자동으로 다시 실행할 수 있습니다.

<script setup>
const page = ref(1)
const { data: posts } = await useAsyncData(
  'posts',
  () => $fetch('https://fakeApi.com/posts', {
    params: {
      page: page.value
    }
  }), {
    watch: [page]
  }
)
</script>

 

매개변수

key: 데이터 가져오기가 요청 전반에 걸쳐 적절하게 중복 제거될 수 있도록 보장하는 고유 키입니다. 키를 제공하지 않으면 의 인스턴스 행 번호와 파일 이름에 고유한 키가 useAsyncData생성됩니다.

handler: 실제 값을 반환해야 하는 비동기 함수(예:  undefined 또는 null 이면 안 됨). 그렇지 않으면 요청이 클라이언트 측에서 중복될 수 있습니다.

options:

  • server: 서버에서 데이터를 가져올지 여부 (기본값은 true)
  • lazy: 클라이언트 측 탐색을 차단하는 대신 경로를 로드한 후 비동기 기능을 해결할지 여부(기본값은 false)
  • immediate: false로 설정하면 요청이 즉시 실행되지 않습니다. (기본값은 true)
  • defaultdata: 비동기 함수가 해결되기 전에 의 기본값을 설정하는 팩토리 함수 - lazy: true or immediate: false옵션 과 함께 유용함
  • transform handler: 해결 후 함수 결과를 변경하는 데 사용할 수 있는 함수
  • pick handler: 함수 결과 에서 이 배열의 지정된 키만 선택합니다.
  • watch: 자동 새로고침을 위해 반응 소스를 관찰합니다.
  • deep: 깊은 참조 객체의 데이터를 반환합니다(기본값 true). false얕은 참조 객체에 데이터를 반환하도록 설정할 수 있으며 , 이는 데이터가 깊게 반응할 필요가 없는 경우 성능을 향상시킬 수 있습니다.

 

useFetch

(https://nuxt.com/docs/api/composables/use-fetch)

SSR 친화적인 컴포저블을 사용하여 API 엔드포인트에서 데이터를 가져옵니다. 

이 컴포저블은 AsyncData와 $fetch를 사용하는 데 편리한 wrapper를 제공합니다.

URL 및 fetch 옵션을 기반으로 키를 자동으로 생성하고 서버 경로를 기반으로 요청 URL에 대한 유형 힌트를 제공하며 API 응답 유형을 추론합니다. 

useFetch는 설정 기능, 플러그인 또는 경로 미들웨어에서 직접 호출할 수 있는 합성 파일입니다. 이것은 반응형 컴포저블을 반환하고  Nuxt 페이로드에 응답을 추가하는 작업을 처리하여 페이지가 렌더링간의 조화를 공급할 때 클라이언트 측의 데이터를 다시 가져오지 않고 서버에서 클라이언트로 전달할 수 있습니다.

<script setup>
const route = useRoute()

const { data, pending, error, refresh } = await useFetch(`https://api.nuxtjs.dev/mountains/${route.params.slug}`, {
  pick: ['title']
})
</script>

 

query를 사용해 fetching을 확장시킬수 있습니다.

const param1 = ref('value1')
const { data, pending, error, refresh } = await useFetch('https://api.nuxtjs.dev/mountains', {
  query: { param1, param2: 'value2' }
})

// https://api.nuxtjs.dev/mountains?param1=value1&param2=value2

Interceptors 사용이 가능하다

const { data, pending, error, refresh } = await useFetch('/api/auth/login', {
  onRequest({ request, options }) {
    // Set the request headers
    options.headers = options.headers || {}
    options.headers.authorization = '...'
  },
  onRequestError({ request, options, error }) {
    // Handle the request errors
  },
  onResponse({ request, response, options }) {
    // Process the response data
    localStorage.setItem('token', response._data.token)
  },
  onResponseError({ request, response, options }) {
    // Handle the response errors
  }
})

커스텀fetch 관련(https://nuxt.com/docs/examples/advanced/use-custom-fetch-composable)

매개변수

URL: 가져올 URL입니다.

Options( unjs/ofetch 옵션 및 AsyncDataOptions 확장 ):

모든 fetch option에는 computed와 ref의 값을 줄 수 있다. 이를 감시하고 업데이트된 경우 새 값으로 자동으로 새 요청이 수행된다.

 

options: useAsyncData의 옵션을 사용할수 있다. 

  • server: 서버에서 데이터를 가져올지 여부 (기본값은 true)
  • lazy: 클라이언트 측 탐색을 차단하는 대신 경로를 로드한 후 비동기 기능을 해결할지 여부(기본값은 false)
  • immediate: false로 설정하면 요청이 즉시 실행되지 않습니다. (기본값은 true)
  • defaultdata: 비동기 함수가 해결되기 전에 의 기본값을 설정하는 팩토리 함수 - lazy: true or immediate: false옵션 과 함께 유용함
  • transform handler: 해결 후 함수 결과를 변경하는 데 사용할 수 있는 함수
  • pick handler: 함수 결과 에서 이 배열의 지정된 키만 선택합니다.
  • watch: 자동 새로고침을 위해 반응 소스를 관찰합니다.
  • deep: 깊은 참조 객체의 데이터를 반환합니다(기본값 true). false얕은 참조 객체에 데이터를 반환하도록 설정할 수 있으며 , 이는 데이터가 깊게 반응할 필요가 없는 경우 성능을 향상시킬 수 있습니다.
//동일 문

const {data: items} = await useFetch('/api/params')


const {pending, data: items} = useFetch('/api/params',{
  lazy: false
  server: false // 클라이언트 사이드 렌더링 이 됨
})

const {pending, data: items} = await useLazyFetch('/api/params')

Transform Handler

const {data: items} = useFetch('/api/params',
 {
  lazy:false,
  transform:(items)=>{
    return items.map((item) => ({
      id: item.id
      title: item.title
      image: item.image
     }));
    }
  }
)

Pick Handler

const {data: items} = useFetch('/api/params',
 {
  lazy:false,
  pick:['id','title','image]
)

 

useAsyncData & useFetch 의 반환값

반환 값

  • data: 전달된 비동기 함수의 결과입니다.
  • pending: 데이터를 아직 가져오는 중인지 여부를 나타내는 부울입니다.
  • refresh/ execute: 함수에서 반환된 데이터를 새로 고치는 데 사용할 수 있는 함수입니다 handler.
  • error: 데이터 가져오기에 실패한 경우 오류 개체입니다.
  • status: 데이터 요청 상태를 나타내는 문자열( "idle", "pending", "success", "error").
  • 기본적으로 Nuxt는 refresh가 다시 실행되기 전에 완료될 때까지 기다립니다.
<script setup>
  const param1 = ref('value1')
  const { data:items, pending, error, refresh } = await useFetch('https://api.nuxtjs.dev/mountains', {
    query: { param1, param2: 'value2' }
  })
</script>

<template>
  <div v-if="pending">
    <p>로딩중</p>
  </div>
  
  <div v-else-if="error">
    <p>Error Code {{ error?.message }}</p>
  </div>
  
  <div v-else>
   <button @click="refresh"> 새로고침 </button>
   	<div>
     <div v-for="item in items" :key="item.id">
      {{item}}
     </div>
    </div>
  </div>
</template>

다중 Fetching

<script setup lang="ts">
const {
  pending,
  data: productInfo,
  refresh,
} = useAsyncData(
  "productInfo",
  async () => {
    const [products, catagories]: any = await Promise.all([
      $fetch("/api/products"),
      $fetch("/api/products/categories"),
    ]);
    return {
      products,
      catagories,
    };
  },
  {
    lazy: false,
    transform: (productInfo) => {
      return {
        catagories: productInfo.catagories,
        products: productInfo.products.map((product: any) => ({
          id: product.id,
          title: product.title,
          image: product.image,
        })),
      };
    },
  }
);
</script>
728x90

'VueJS > NUXT' 카테고리의 다른 글

Nuxt Kakao Map 연동  (0) 2024.08.25
NuxtJS__app, layout, pages, components, errorpage  (1) 2023.11.14
반응형

Nuxt 프로젝트 생성

npx nuxi@latest init <project-name>

 

Nuxt 설치 후 
https://nuxt.com/docs/guide의 Directory Structure를 참고하여 자기가 필요한 기능들을 폴더로 만들고 해당파일을 만들면 그 기능이 활성화된다. 폴더를 만들땐 위의 링크에 나와있는데로 작성해야한다.

 

1.  app.vue

초기 파일에 app.vue파일에 내용을 다 지우고 작업을 시작하면된다.

//app.vue

<template>
  <NuxtLayout>
    <NuxtPage />
  </NuxtLayout>
</template>

 

2.  Layouts

layouts 관련 내용 (https://nuxt.com/docs/guide/directory-structure/layouts)

레이아웃을 만들기 위해 Root에 layouts라는 폴더를 만들고 기본이 되는 레이아웃을 파일을 만든다.ㅓ

기본이 되는 파일명은 default.vue가 되어야 한다.

//default.vue
<template>
  <div>
    <HeaderComp />
    <h1>this is layout</h1>
    <NuxtPage />
    <FooterComp />
  </div>
</template>

 

커스텀 레이아웃은 커스텀명.vue로 만들어야하고

//pages/페이지이름.vue

<script setup lang="ts">
definePageMeta({
  layout: 'custom'
})
</script>

레이아웃을 불러내야한다.

 

직접 불러내어 전체 레이아웃을 바꿀 수도 있다.

//app.vue

<script setup lang="ts">
// You might choose this based on an API call or logged-in status
const layout = "custom";
</script>

<template>
  <NuxtLayout :name="layout">
    <NuxtPage />
  </NuxtLayout>
</template>

클릭이벤트를 주어 레이아웃을 바꿀 수 있다.

<script setup lang="ts">
function enableCustomLayout () {
  setPageLayout('custom')
}
definePageMeta({
  layout: false,
});
</script>

<template>
  <div>
    <button @click="enableCustomLayout">Update layout</button>
  </div>
</template>

해당페이지에서만 바꿀수도 있다.

//pages/index.vue

<script setup lang="ts">
definePageMeta({
  layout: false,
})
</script>

<template>
  <div>
    <NuxtLayout name="custom">
      <template #header> Some header template content. </template>

      The rest of the page
    </NuxtLayout>
  </div>
</template>

//layouts/custom.vue

<template>
  <div>
    <header>
      <slot name="header">
        Default header content
      </slot>
    </header>
    <main>
      <slot />
    </main>
  </div>
</template>

3.  Pages

pages 관련 내용(https://nuxt.com/docs/guide/directory-structure/pages)

pages/index.vue는 ' / ' Route 이다. 

Dynamic Route & Nested Routes

 Dynamic Route는 pages의 폴더 경로를 이용해 활용한다. NextJS의 Route를 생각하면 쉽게 이해할 수 있다.

Directory Structure (폴더구성)
-| pages/
---| index.vue  => "/"

---| login.vue  => "/login"

---| haha/
-----| index.vue  => "/haha"

---| usersprofile/
---| index.vue =>"/userprofile" index가 우선권이 있다.
-----| [id].vue  => "/userprofile/유저의 id혹은 고유번호 기타 등등"

---| board-[group]/
-----| [id].vue  => "/board-게시판의종류 혹은 기타/게시물 번호"

 

 아래의 사례로 라우팅에 대한 확인도 할 수 있다.

<script setup lang="ts">
const route = useRoute()

if (route.params.group === 'admins' && !route.params.id) {
  console.log('Warning! Make sure user is authenticated!')
}
</script>

Page Metadata

페이지의 메타데이터를 활용하려면

<script setup lang="ts">
definePageMeta({
  title: 'My home page'
})
</script>

<script setup lang="ts">
const route = useRoute()

console.log(route.meta.title) // My home page
</script>

그밖의 메타데이터 활용은 문서 참조.

Navigation

페이지간 이동은  <NuxtLink>를 사용한다.

<template>
  <NuxtLink to="/about">
    About page
  </NuxtLink>
</template>

 

또한 이벤트로는 navigateTo 함수를 사용해서 이용할수도 있다.

<script setup lang="ts">
useTitle("메인");
const name = ref("");
const type = ref(1);

function navigate() {
  return navigateTo({
    path: "/search",
    query: {
      name: name.value,
      type: type.value,
    },
  });
}
</script>
<template>
  <div>
    <p>메인페이지 인디용~~</p>
    <button @click="navigate()">gogo</button>
  </div>
</template>
<style scoped>
h1 {
  color: red;
}
</style>

 

4. Components

Root폴더에 components폴더를 만든다. 또한 Nuxt에서는 따로 import하지 않고 바로 불러 올 수 있다.

// /components/KingBtn.vue

<template>
  <div>
    <button>im the king</button>
  </div>
</template>


// /pages/search.vue

<script setup lang="ts">
import 컴포넌트 이름 from '컴포넌트경로'
const show = ref(false);
</script>

<template>
  <div>
    <h1>search</h1>
    
    <LazyKingBtn v-if="show" />
    <!-- Component앞에 Lazy 접두사를 붙이면 컴포넌트가 지연 로딩이 되로록 설정할수 있다. 
    이를 통해 초기 로드시 컴포넌트를 불러오지 않고 컴포넌트가 실제로 필요한 시점에 
    비로소 로드되게끔 만드는 기능이다. -->
    
    <button @click="show = !show">King BTN</button>
    
    <component :is="import한 component이름"/>
  </div>
</template>

 

Client Component를 사용하기 위해서는 

[파일명.client.vue]로 파일이름을 지어주면 된다.

 

5. Error Page

에러페이지를 커스텀하기 위해서는 Root폴더에 error.vue를 만들어준다.

728x90

'VueJS > NUXT' 카테고리의 다른 글

Nuxt Kakao Map 연동  (0) 2024.08.25
Nuxt3__Data Fetch  (0) 2023.11.22
반응형

Props

  • 컴포넌트에 데이터를 넘겨줄 수 있는 사용자 지정 속성
  • 컴포넌트 생성 시 넘겨 받을 데이터 결정
  • 일반적으로 props 옵션에 키와 값을 배열로 지정하여 사용
  • props : ['name,'age','job']
  • 특정한 props나 정해진 데이터 타입이 필요한 컴포넌트는 props 옵션의 값을 배열 대신 객체로 변경하고 상세 내용 지정

Props 속성

type 데이터 타입 정리
default 해당 props가 들어오지 않을 경우 사용할 기본값
데이터 타입이 Object인 경우 반드시 팩토리 함수를 이용해 값 반환
required true로 설정
props가 들어오지 않은 경우 콘솔에 경고 출력
default 설정 시 기본값이 적용(에러 출력되지 않음)
validator 잘못 들어온 인자를 개발자 코드로 직접 겈사해 콘솔창에 경고 출력

Non-Prop 속성

  • Class 나 Style, id 속성 등 대상 컴포넌트의 props나 emits 옵션에 정의되어 있지는 않으나 대상 컴포넌트에 전달되어 필요한 역할을 수행하는 컴포넌트 속성
  • 스크립트의 $attr로 접근가능
  • <p> {{$attr.title}} </p>
  • 컴포지션 API의 setup 함수를 이용하는 경우 두번째 인자(context) 활용
  • context 매개 변수는 attrs 속성을 가지고 있으며 non-prop의 정보를 가지고 있음
  • setup(props, context){ const title = context.attrs.title }
  • 템플릿 내 루트 노드에 상속

사용자 이벤트 생성

더보기

Chat GPT

 

Vue에서 $emit과 $attr은 컴포넌트 간에 데이터를 전달하고 속성을 동적으로 설정하는 데 사용되는 두 가지 중요한 기능입니다.

$emit은 부모 컴포넌트에서 자식 컴포넌트로 데이터를 전달하기 위해 사용됩니다. 부모 컴포넌트에서 $emit을 사용하여 이벤트를 발생시키고, 자식 컴포넌트에서는 그 이벤트를 감지하고 데이터를 받을 수 있습니다. 예를 들어, 부모 컴포넌트에서 "update"라는 이벤트를 발생시키고 데이터를 함께 전달하고 싶을 때, $emit('update', data)와 같이 사용할 수 있습니다. 자식 컴포넌트에서는 @update="handleUpdate"와 같이 이벤트를 감지하고 handleUpdate 메서드에서 전달된 데이터를 사용할 수 있습니다.

$attr은 컴포넌트에 동적으로 속성을 추가하거나 속성 값을 가져오는 데 사용됩니다. 예를 들어, 부모 컴포넌트에서 <child-component foo="bar"></child-component>와 같이 자식 컴포넌트에 foo라는 속성을 동적으로 추가하고 싶을 때, 자식 컴포넌트에서 $attrs.foo를 사용하여 bar 값을 가져올 수 있습니다. 또한, 자식 컴포넌트에서 $attrs를 통해 모든 동적으로 추가된 속성을 가져올 수도 있습니다.

요약하자면, $emit은 부모 컴포넌트에서 자식 컴포넌트로 데이터를 전달하고, $attr은 컴포넌트에 동적으로 속성을 추가하거나 가져올 때 사용됩니다. 이러한 기능을 사용하여 Vue 컴포넌트 간에 유연하게 데이터를 전달하고 속성을 설정할 수 있습니다.

사용자 이벤트 생성

  • 컴포넌트의 emits 옵션에 이벤트명 지정
  • emits: ['myevent-1','myevent-2']
  • 이벤트명 작성시 케밥 케이스 형식의 소문자로 작성
  • props와 마찬가지로 객체 형식을 이용하여 이벤트 전달값이 올바른지 판단 가능
  • emits:{ //검증함수의 인자는 해당 이벤트가 생성하는 이벤트 값 입력 'myevent-1' :({name, value}) => { //name과 value값이 반드시 존재해야 이벤트 처리 return name && value } }

v-model과 이벤트 결합

  • v-model : 양방향 데이터 결합
  • v-model 디렉티브에 연동된 변수는 컴포넌트의 props 속성과 연동
  • <Component v-model:msg='Message'></Excomponent> props:{msg:String}
  • v-model로 전달된 변수의 값은 컴포넌트 안에서 업데이트되어 변수를 전달한 부모 컴포넌트와 동기화
  • 업데이트를 위해서 접두사와 변수명을 ":"으로 결합한 이벤트명 사용
  • emits:['update:msg'] $emit('update:msg',$event.garget.value)
  • vue3에서는 여러 개의 v-model 디렉티브 지원
  • props에 v-model 디렉티브를 위한 변수를 여러 개 설정하고 emits에도 동일하게 설정하여 여러 개의 값을 양방향으로 결합
  • props:{msg: String, type:String} #emit('update:msg',$event.target.value) #emit('update:type',$event.target.value)

provide & inject

provide & inject

  • 컴포넌트 간 데이터 전달에 사용
  • vue2에서 컴포넌트 간 데이터 전달을 위해 비표준 방식의 Event Bus를 생성하는 방식 대신 사용
  • 비 반응성 형식이지마 ref, reactive, computed와 같은 함수를 이용해 반응성을 가지는 변수를 provide 할 경우 inject된 값도 반응성 유지

provide

  • 부모 컴포넌트에서 자식 컴포넌트들과 공유할 데이터 정의

inject

  • 부모 컴포넌트가 가지고 있는 데이터를 접근할 때 사용
<script>
import Header_Comp from './components/Header_Comp.vue'
import Footer_Comp from './components/Footer_Comp.vue'
export default {
  provide: {
    msg: '데이터 공유하기',
    msg2: 'hoooooo'
  },
  components: {
    Header_Comp
  }
}
</script>

<template>
  <Header_Comp />
  <div>
    <h1>HELLO</h1>
  </div>
</template>
///////

Header_comp
|
|
<script>
export default {
  inject: ['msg', 'msg2']
}
</script>
<template>
  <header>
    <h1>아하하하</h1>
    <h2>{{ msg }}</h2>
    <h2>{{ msg2 }}</h2>
  </header>
</template>

Mixins

mixins

  • 여러 컴포넌트 간에 공통으로 사용하고 있는 로직, 기능들을 재사용
  • vue3에서 컴포지션 함수로 대체 가능해져 사용성 축소
  • 컴포넌트의 옵션과 동일한 옵션들을 모두 정의 가능하므로 mixins를 호출하는 컴포넌트와 충돌 발생할 수 있음
  • mixins는 컴포넌트보다 우선 호출
  • 컴포넌트의 변수나 함수의 이름과는 충돌하는 것을 방지하기 위해 이름 변경 필요
  • 예) 컴포넌트 변수명 : title => mixins 변수명: mixins_title
  • var HelloMixins = { // 컴포넌트 옵션 (data, methods, created 등) } new Vue({ mixins:[HelloMixins] })

 

728x90

'VueJS > VueJS' 카테고리의 다른 글

2023/06/28__VueJS(Vue3)  (0) 2023.06.28
2023/06/27__VueJS(Vue3)  (0) 2023.06.27
2023/06/22__VueJS(cache 관련 및 firebase)  (0) 2023.06.23
2023/06/19__VueJS(Vue && PWA && Firebase)  (0) 2023.06.20
2023/06/15__VueJS(vuetify)  (0) 2023.06.15
반응형

v-pre 디렉티브

v-pre

  • 해당 엘리먼트를 포함한 모든 자식 엘리먼트들의 컴파일 생략
  • 머스태시를 사용하여도 문자열로 출력
<div v-pre>
{{vhtml}}
</div>

 

 

데이터 결합 디렉티브

v-bind

  • 단방향 결합
  • 변수의 값이 템플릿으로만 결합
  • 템플릿의 HTML태그가 변경한 값이 변수에 반환되지 않음
  • 디렉티브 생략가능
< element v-bind:속성='변수명'></div>
< element :속성='변수명'></div>

v-model

  • 양방향 결합
  • 변경된 변수의 값이 DOM에 업데이트
  • 템플릿에서 변경된 값이 변수의 값을 변경
  • 양방향이 가능한 모든 태그에서 사용 가능
  • 별도의 속성을 정의하지 않으며 반드시 value 속성과 결합
  • Vue3에서는 하나의 엘리먼트에 여러 개의 v-model디렉티브 사용 가능
  • 디렉티브 생략 불가능
<div v-model='변수명'></div>

v-bind VS v-model

<div v-bind:속성='변수명'></div>
<div v-model='변수명'></div>

ref 함수

  • vue에서 함수를 import 한 후 사용 = > import {ref} from. 'vue'
  • setup 함수에서는 반응형 변수 선언 시 값을 ref 함수의 인자로 입력
  • ref또는 reactive함수를 이요하여 데이터를 프록시 객체로 생성하면 데이터의 변겨이 프록시 객체가 아닌 원래의 데이터에서 수행
  • const로 선언된 변수도 프록시의 변화는 없이 데이터만 변경 가능
  • 반환된 값은 템플릿과 결합하기 위해 return 사용

문법적 sugar (Syntax Sugar, Syntactic Sugar)

  • 문법적인 기능은 그대로 유지하되 사람이 이해하고 표현하기 쉽게 디자인된 프로그래밍 언어 문법. 또는 프로그래밍 언어를 더욱 더 간결하고 명확하게 표현이 가능하도록 도와주는 문법 

ref 함수의 문법적 슈가

  • <script> 선언문에 setup속성을 추가
  • components 옵션 생략
  • setup 함수 생략
  • 변수를 명시적으로 반환하지 않음
  • ref를 value속성 없이 사용가능
<script setup>
	ref:title = 'DIY'
    const change()=>{title='DO It Yourself'}
</script>

이벤트 리스너

v-on 디렉티브

  • HTML 태그가 발생시키는 이벤트를 캡처하여 저장된 스크립트를 수행하거나 함수를 호출하는 디렉티브
  • 사용자 정의 컴포넌트에서 발생된 이벤트에도 사용가능
  • v-on:click = '스크립트 코드 또는 함수'
  • '@'로 줄여서 사용가능
  • @click='스크립트코드 또는 함수'

Composition API

  • 함수 선언 시 return 문을 통해 값 반환
  • ref함수를 통해 선언된 변수는 프록시(반응성) 객체로 변환됨
  • 함수 값을 변경하기 위해 .value 속성을 사용 => counter2.value++
  • setup 함수에서 생성된 데이터 변수는 setup 함수 내에서만 사용가능

Options API

  • methods 옵션 내부에 함수 생성
  • methods 옵션에 선언된 함수는 data

이벤트 수식어

  • 이벤트의 동작을 변형하기 위한 함수
  • v-on 디렉티브는 이벤트 함수 호출을 이벤트 핸들러 메서드에서 하지 않고 이벤트를 받는 태그에서 직접 사용 가능

v-if 디렉티브

  • 일반적으로 스크립트 문법 사용
  • 디렉티브를 큰따옴표로 구성한 경우 내부의 문자열에는 작은따옴표 사용
  • v-if / v-else-if / v-else
  • 빠르게 어플리케이션의 그림을 그려주지만 조건이 변경될 때마다 해당 엘리먼트를 다시 그림 (<-> v-show 디렉티브)
  • 조건이 자주 변경되지 않는 경우에 유리
  • v-if='count>0' // v-if='text == text'

v-show 디렉티브

  • v-if와 유사한 역할 수행
  • 모든 조건의 DOM 엘리먼트를 그린 후 조건에 맞지 않는 엘리먼트를 hide 처리
  • 처음 렌더링은 느린편이지만 조건이 변경되는 경우 빠르게 전환됨
  • 조건이 자주 변경되는 경우 유리

v-for 디렉티브

  • 동일한 문장 또는 규칙을 가지는 문장을 반복하는 경우에 사용
  • 배열, 객체, 데이터베이스 등 많은 데이터를 가지고 있는 변수의 값을 출력할 때 용이
  • 자바스크립트의 loop를 이용해 HTML 태그를 포함한 문자열을 반환하고 해당 문자열을 v-html 디렉티브로 표현 가능
v-for='값 in 배열'
v-for='(값, 인덱스) in 배열'

v-for='값 in 객체'
v-for='(값,키) in 객체'
v-for='(값,키, 인덱스) in 객체'
  • key 속성과 같이 사용하는 것이 좋음
  • 변수를 반응성으로 만들기 위해 프록시 객체를 생성하는 ref를 사용하지만 배열이나 객체는 reactive 함수 사용

computed 속성

  • 반응형 애플리케이션 구현의 중요한 기능 중 하나
  • ref, reactive, watcher는 실시간으로 데이터의 변경을 감시하지만 computed는 원하는 대로 데이터를 변경
  • 간단한 데이터의 조작은 v-if, v-for 등으로 비슷하게 구현 가능하지만  computed는 복잡한 연산이나 기능의 구현 가능
  • 호출이 되면 반드시 새롭게 계산을 진행하고 DOM을 업데이트하는 함수와는 다르게 내부 반응성 변수의 값이 변하지 않으면 결과를 캐시에서 가져와 사용하며 DOM에 업데이트 하지 않음
  • Options API - computed 속성 사용
  • Composition API - Vue 패키지에서 computed 컴포지션 API 호출하여 사용

map()  메서드

  • 배열 내의  모든 요소를 돌면서 주어진 함수의 결과를 모아 새로운 배열을 리턴
  • 결과를 return으로 추출
  • 실행문이 한 개만 반환될 경우 , return 키워드와 {}를 생략가능
const a = numbers.map(number => {
	return number < 3
}

//리팩토링(간결한 코드)
const a = numbers.map(number => number < 3)

배열의 .map() 메소드와 .filter 메소드

filter() 메서드

  • 배열 내의 모든 요소를 돌면서 주어진 함수의 조건에 맞는 요소만을 모아 새로운 배열을 리턴

filter() 구문

let newArray = arr.filter(callback(currentValue[,index,[array]]){
	//return element for newArray, if true
}[,thisArg]);
  • currentValue: 배열 내 현재 값
  • index : 배열 내 현재 값의 인덱스
  • array : 현재 배열
  • thisArg : callbackFunction 내에서 this로 사용될 값
728x90

'VueJS > VueJS' 카테고리의 다른 글

2023/06/30__VueJS(Vue3)  (0) 2023.06.30
2023/06/27__VueJS(Vue3)  (0) 2023.06.27
2023/06/22__VueJS(cache 관련 및 firebase)  (0) 2023.06.23
2023/06/19__VueJS(Vue && PWA && Firebase)  (0) 2023.06.20
2023/06/15__VueJS(vuetify)  (0) 2023.06.15
반응형

컴포지션 API

기존 Vue의 특징

  • Options API 기반으로 하나의 객체를 하나의 모듈로 생성(컴포넌트)
  • 각 객체를 변수, 메소드 등 특정한 옵션 기능으로 구성
  • 주로 중, 소규모의 웹앱 제작에 활용
  • 하나의 SFC(single file component)에서 많은 기능과 변수들이 산포되어 가독성 저하

컴포넌트 API

  • 컴포넌트 작성 시 함수 기반의 작성방법제시
  • 기능별 함수 분리
  • 가독성 향상
  • 컴포넌트 재활용성 향상
  • 기존 vue버전에 사용되던 Mixins 대체

Suspense

Suspense

  • 컴포넌트가 데이터를 받아오기 전까지 기본(Fallback) 콘텐트 표시 예) 데이터 로딩 시 스켈레톤 UI 출력후 데이터 로딩 완료 시 실제 화면 출력
  • 기존 버전의 v-if, v-show 디렉티브를 간단하게 해결

Teleport

Teleport

  • vue는 UI와 관련 동작을 은닉화하여 컴포넌트로 만들어 사용
  • 컴포넌트는 다른 컴포넌트에 중첩 가능
  • DOM 노드 트리 구조 상 CSS 작성 시 잘못된 UI발생 가능
  • poratl-vue 서드파티 플러그인을 이용하여 특정 DOM 엘리먼트 렌더링
  • teleport로 portal-vue 서드파티 플러그인과 동일한 기능 제공
  • 어느 컴포넌트이든 원하는 위치에 렌더링

다중 v-model 디렉티브

v-model

  • 양방향 결합 모델
  • 기존 vue에서는 하나의 사용자 컴포넌트는 하나의 v-model만 사용 가능
  • 여러 개의 v-model 디렉티브가 필요한 경우 v-bind, v-on 디렉티브를 함께 사용하거나 변수를 객체나 배열로 만들어 사용
  • vue3에서는 여러개의 v-model 디렉티브를 하나의 DOM엘리먼트에 할당가능

기존 vue

<Mycomponent v-bind:param1 v-on:update="updateParam1" v-bind:param2 v-on:update="updateParam2"/>

Vue3

<Mycomponent v-mode="param1" v-model="param2"/>

프록시(Proxies)

기존 Vue의 반응성

  • vue는 내부적으로 객체의 속성을 setter와 getter로 변환하여 반응성 구현
  • 미리 정의되지 않은 속성의 추가는 getter와 setter 호출이 아닌 단순 아이템 추가
  • 기존 vue의 watch옵션은 자바스크립트 객체의 속성 또는 배열의 아이템이 추가되는 경우 객체 변겨에 반응하지 않음

예)

obj = {item:0}

//객체에 속성 추가
obj.item = 1 -- 추가된 아이템 인식 안 함

반응성 향상

  • 프록시
  • ES6에서 추가
  • 데이터와 프레임워크 사이 데이터 전달 및 변환, 관리를 담당
  • Vue3는 컴포지션 API를 통해 데이터를 프록시로 변환하여 사용
  • 반으성이 향상 되지만 하위 버전 브라우저에서 지원되지 않음
  • 프록시 사용 시 대상 객체는 프록시 객체 내부로 들어가고 프록시의 getter/setter로 관리되면서 모든 데이터의 변화에 대해 반응성 구현
  • ref또는 reactive함수 사용

예)

const obj = reative({})
obj.item1 = 2

Fragments

기존 vue

  • 기본적으로 하나의 컴포넌트에 하나의 루트 노드 사용
  • 컴포넌트에 전달되는 Non-Props 속성을 컴포넌트에 정의된 루트 노드에 전달되도록 설계
  • 여러 개의 루트 노드를 컴포넌트에  할당 가능하지만 속성을 전달해야 할 노드가 명확하지 않아 경고 발생
<template>
	<div>
		<header></header>
		<main></main>
		<footer></footer>
	</div>
</template>

Fragments

  • 하나의 컴포넌트가 여러 개의 루트 노드를 가지는 것
  • Non-Props 속성의 전달이 필요한 경우 어느 노드가 전달 받을지 명확하게 작성
<template>
	<header></header>
	<main></main>
	<footer></footer>
</template>

Emits Option

$emit()

  • 하나의 컴포넌트가 부모컴포넌트에 이벤트를 전달하기 위해 사용

기존 Vue

함수 사용에 제약없음

 

Vue3

  • 컴포넌트 옵션 emits를 이용해 전송할 이벤트 정의
  • 해당 컴포넌트에서 발생하는 이벤트명 기술
  • 해당  이벤트의 데이터에 대해 사전 검증하는 기능 제공

미리 정의된 이벤트명을 emits 옵션에 선언하지 않을 경우, 같은 이름의 네이티브 이벤트가 존재한다면 네이티브 이벤트를 호출

예)

<template>
	<button v-on:click="$emit('click',$event)">
    	OK
	</button>
</template>

export default {emits :[]}
  • 기존버전에서 native 이벤트 사용시 '@click.native'처럼 사용
  • vue3에서는 native 수식어를 사용하지 않음
  • emit 옵션에 명시되지 않은 이벤트는 모두 native로 처리

createRenderer

createRenderer

  • 사용자가 렌더링의 동작을 정의할 수 있게 해주는 함수
  • vue3가 제공하는 runtime-dom, runtime-core 패키지에서 제공
  • Host 환경의 node와 element를 gerneric인자로 받아 해당 노드와 엘리먼트의 렌더링 동작을 변경
  • 하나의 객체를 인자로 받고 해당 객체 내에 개발자가 재정의하고자 하는 함수 선언
const {createApp} = createRenderer({
....
insert : (child, parent, anchor) =>{
// 엘리먼트 추가 시 재정의하고 싶은 코드 입력
}
...
})

렌더링 방식

  • jquery 명령형 렌더링
  • vue, react 선언형 렌더링

선언형 렌더링

  • 데이터 변수로 선언된 값을 템플릿 내에 특정 방식으로 접근
  • DOM엘리먼트를 무조건 다시 렌더링하지 않고 DOM과 연결된 상태와 속성이 변경될 때 자동으로 DOM 엘리먼트를 업데이트

NPM / Vite를 이용한 프로젝트 생성

패키지 설치를 이용한 프로젝트 생성

  • 실제 프로젝트 개발에 사용
  • npm을 이요하여 관련 라이브러리들을 프로젝트 코드들과 함께 컴파일 한 후 코드 축소
  • 결과물은 하나의 js파일로 생성
  • 결과물의 크기가 큰 경우 비동기식으로 필요할 때 필요한 코드를 불러오는 Lazy로딩 방식 이요
  • vue ES 패키지를 다운로드 받아 개발
  • npm i vue@next

vite

  • vue3에서 별다른 번들 생성 없이 ES Modules를 바로 웹 브라우저에 렌더링 할 수 있도록 만든 개발 툴
  • 매우 빠른 HMR(Hot Module Replacement)제공
  • 번들 생성 과정이 필요 없어 서버의 시작 속도 빠름
  • 개발자가 번들 없이 모듈화된 컴포넌트의 수정사항을 브라우저로 확인가능

vite를 이용한 프로젝트 생성

  • npm create vite@latest
  • npm init vite / npm create vite@latest
  • 각 파일의 경로 간소화 / npm install path

Vue3 핵심

SFC(single file component)

SFC

  • Vue의 컴포넌트를 하나의 파일로 제작
  • 코드가 간결하고 관리가 쉬움
  • <template> <script> <style>로 구분

template

  • 렌더링 될 html 코드

script

  • 컴포넌트에 적용될 스크립트 코드 작성
  • setup 속성 사용 시 LOC(Line of Code) 절약 가능

Style

  • 컴포넌트에 적용될 스타일 작성
  • scoped 속성 추가 시 해당 컴포넌트에만 스타일 적용

setup(컴포지션 함수)

기존 vue버전

  • Options API만 제공
  • 컴포넌트 생성 시  data, methods, computed 옵션 작성

setup

  • 기존 자바스크립트 문법과 동일
  • setup 함수는 객체 반환
  • 반환된 객체에는 HTML에서 사용할 변수가 포함되어야 함
setup(){
	const data = 1
    return {
    	data
    }
}

setup(){
	const foo = () =>{
    		data = 2
        }
        return {
        	foo
        }
}

컴포넌트 Life Cycle(생명주기)

생명주기

  • 컴포넌트 생성 - DOM 노드에 마운트 - 불필요한 엘리먼트를 제거하는 일련의 과정
  • 생명주기 훅(Hook) 제공 - 각 생명주기를 후킹(Hooking)할 수 있는 방법 제공
EX)
// Options API

update(){
	//Update Action
}

// Composition API

setup(){
	onUpdate(()=> { // Update Action }
}

beforeCreate

  • 컴포넌트를 생성하기 전에 호출
  • 컴포지션 API의 setup() 함수는 beforeCreate를 대체
  • 컴포넌트 생성 전에 호출되므로 생성된 data, data관찰을 위한 watch 등이 동작하지 않음

created

  • 컴포넌트가 생성되면 호출
  • 컴포지션 API의 setup() 함수가 beforeCreate와 create를 함께 대체
  • 컴포넌트의 옵션에 접근이 가능하므로 data 옵션에 선언한 데이터 초기화 시 많이 사용

mounted(onMounted)

  • 실제로 컴포넌트의 구성요소들이 DOM엘리먼트로 마운트된 후에 호출
  • 실제 엘리먼트 참조 가능
  • onRenderTracked라는 생명주기 훅에서 관찰 가능
  • 실제 엘리먼트에 동적으로 변화 주고자 하는 경우 활용
  • 이후 onRenderTriggered 훅 호출됨

beforeUpdate(onBeforeUpdate)

  • 데이터가 변경되었지만 아직 DOM에 반영되지 않은 경우 호출
  • 변경 사항이 DOM에 반영되지 않았으므로 실제 엘리먼트를 참조하는 변수값 사용불가

updated(onUpdated)

  • 데이터가 변경되어 DOM이 적용된 시점에  호출
  • 실제 DOM이 업데이트 되면서 참조된 변수를 이용한 다양한 역할 수행 가능
  • 해당 컴포넌트만 수정을 보장하며 자식 노드들의 없데이트를 보장하지 않음
  • 자식 컴포넌트들의 수정까지 보장하기 위해  nextTick 사용
update(){
	this.$nextTick(function(){
    	// 모든 자식 요소 업데이트 완료
    })
}

beforeUnmount(onBeforeUnmount)

  • 컴포넌트가 탈착되기 직전에 호출
  • 모든 기능의 사용 가능한 상태이므로 컴포넌트가 분리되기 전에 수행해야 될 내용 작성

activated(onActivated)

  • keep-alive 태그: 컴포넌트가 다시 렌더링 되는 것을 방지하고 상태를 유지 시킴
  • v-is와 함께 사용되며 v-is 디렉티브가 컴포넌트를 변경할 때 기존 컴포넌트의 형태가 사라지지 않게 하기 위해 사용
  • keep-alive 태그로 컴포넌트의 상태가 보존되기 시작하면 onActivated 훅 호출
<keep-alive>
	<component v-is="currentComponent">
</keep-alive>

deactivated(onDeactivated)

  • keep-alive로 상태가 유지되던 컴포넌트가 효력 상실 시 호출
  • 소스코드 수정 후 저장하면 Vite의 HMR이 해당 컴포넌트를 다시 렌더링하는데 이 때 keep-alive로 activated 된 컴포넌트에 deactivated 호출 확인 가능

renderTracked(onRenderTracked)

  • Virture DOM이 변경될 때마다 관찰을 목적으로 호출
  • 이 함수로 DebuggerEvent 객체를 확인하여 Virture DOM의 변경 이유 확인 가능
  • DebuggerEvent는 target 속성으로 Virture DOM 변경 추적
renderTracked((e){
	console.log(e.target)
}

renderTriggered(onRenderTriggered)

  • VirtureDOM이 실제 DOM에 반영되어야 할 때 호출
  • onMounted, onActivated, onUpdated와 같이 실제 DOM이 변경되기 직전에 호출
  • DebuggerEvent로 호출이유 파악 가능
  • EX) 새로운 값이 추가된 경우  - DebuggerEvent의 type 속성에 'add', newValue 속성에 추가된 값 입력 확인 가능

errorCaptured(onErrorCaptured)

  • 자손 컴포넌트에 에러가 발생한 경우 어느 컴포넌트에서 발생했는지 확인
  • 실제 동작 중에 에라가 발생되면 안되므로 개발 중 에러를 캡처하기 위해 사용

선언적 렌더링

선언적 렌더링

  • 변수를 선언하고 값을 입력하면 자동으로 DOM 갱신

Options API

  • data 옵션에 변수 선언

Composition API

  • setup 함수 생성 후 내부에 자바스크립트 방식으로 변수 선언
  • 선언된 변수는 반드시 객체 형식으로 반환

머스태시(이중 중괄호{{}}) 표기법

  • 템플릿 객체 내에서 변수의 값 출력

ES6 단축 속성(Shorthand Property)

단축 속성

  • setup 함수에서 반환할 때 객체의 키 값과 동일한 변수면을 값으로 사용하는 경우 값을 생략하여 짧은 코드로 작성가능
setup(){
	const date2 = Date().toString()
    return{
    	date2 : date2 //   ||  date2,
    }
}

//////

v-html 디렉티브

머스태시 & v-text

  • 머스태시와 v-text 디렉티브는 HTML 엘리먼트의 textContent를 업데이트
  • 문자열을 변수로 대입하더라도 변수에 저장된 값이 아닌 변수 명이 문자열로 반환

v-html

  • HTML엘리먼트의 innerHTML로 값 전닮되므로 문자열을 HTML 마크업 언어로 표현
  • 변수 값이 반드시 HTML 평문이어야 함
  • Vue 문법을 사용해도 컴파일 되지 않음
<div v-html='<i>HTML MAKRUP</i>'></div>
728x90

'VueJS > VueJS' 카테고리의 다른 글

2023/06/30__VueJS(Vue3)  (0) 2023.06.30
2023/06/28__VueJS(Vue3)  (0) 2023.06.28
2023/06/22__VueJS(cache 관련 및 firebase)  (0) 2023.06.23
2023/06/19__VueJS(Vue && PWA && Firebase)  (0) 2023.06.20
2023/06/15__VueJS(vuetify)  (0) 2023.06.15
반응형

워크박스로 런타임 캐시 관리

서비스 워커의 런타임 캐시 설정

  • 앱을 실행하는 중간에 필요한 내용을 캐시하는 것을 의미

 

워크박스의 5가지 캐시전략

프리 캐시(pre-cache)

  • 서비스 워커가 등록될 때 미리 원하는 파일만 지정하여 캐시하는 것
  • 빠르고 손쉬운 방법

런타임(runtime) 캐시

  • 브라우저의 HTTPS 요청처럼 프로그램 로직에 따라 앱 실행 중에 캐시해야 하는 경우 적용
  • '캐시전략'이라는 사용방식을 결정해야 함

 

워크박스 5가지 '캐시전략'지원

  • Network-First, Cache-First, Stale-while-revalidate,Network-only, Cache-only

1. Network-First 캐시전략

인터넷 접속을 먼저 요청

  • 인터넷 접속이 성공하면 결과를 보여주고 그 내용을 캐시에 반영

항상 새로운 내용이 중요할 때 적합

예)인터넷 기사

 

2. Cache-First 캐시 전략

1 단계로 캐시에 먼저 요청

  • 만약 내용이 있으며 성공적으로 결과 보여줌

바뀔 경우가 거의 없는 파일에 적합

예)폰트, 아이콘, 이미지

 

3.Stale-while-revalidate 캐시 전략

1단계에서 캐시에 먼저 요청

  • 내용이 있으면 성공적으로 결과 표시
  • 동시에 서비스 워커는 인터넷에 접속하여 캐시된 내용이 원본과 같은지 확인
  • 만약 다르면 캐시를 새로운 원본으로 업데이트

가끔 업데이트가 발생할 경우 적용

예) 아바타 이미지

 

4. Network-Only 전략

필요한 파일이 있으면 무조건 인터넷에 접속해서 가져오는 방식

  • 데이터 변경이 너무 빈번해서 캐시가 의미가 없을 때 사용

5. Cache-Only 전략

필요한 파일이 있으면 무조건 캐시에서 가져오는 방법

  • 데이터 변경이 전혀 없고 오프라인 작업만으로 실행이 가능할 때 사용

프리캐시(pre-cache) 옵션지정

프리캐시(pre-cache)

옵션 의미 적용사례
include 프리캐시에서 사용할 파잉를 지정한다. 이것은 파일이름을 토대로 하므로 대량으로 찾는 정규식을 함께 활요하면 유용하다. include:[/].css$/, /\.js$/]
exclude 프리캐시에서 제거할 파일을 지정하다. 사용법은 include처럼 정규식을 함께 활요한다. 그런데 유의할 점은 제거할 파일이 없어도 exclude:[]처럼 반드시 명시해 주어야 제대로 동작한다. exclude : [/\.json$/, /\.png$/]

런타임 캐시옵션 지정

설정 의미 적용 사례
handler 앞에서 설명한 5가지 캐시 전략 중  한 가지 사용 Cache-First 전략 사용
handler : 'cacheFirst'
urlPattern 정규식 사용해서 캐시하려는 파일이나 URL경로 지정 *.png 이미지 파일 캐시
urlPattern :/\.png$/
구글폰트 URL 캐시
/^https:\/\/fonts\.gstatic\.com/
options cacheName 개발자 도구에 표시할 캐시 제목 cacheName :'png-cache'
expiration 캐시제약지정
maxEntries : 캐시할 개수
maxAgeSeconds: 캐시가 유지될 총 시간(초)
총 파일 10개까지 캐시 maxEntries:10
1년 캐시 maxAgeSeconds : 60 * 60 * 24 * 365
cacheableResponse HTTP응답 코드를 통해서 캐시 여부 결정 응답 코드가 200(성공) , 404(파일 없음)면 캐시
cacheableResponse:{statuses:[200,404]}

 

카메라 사진 갤러리 앱 구경하기

카메라로 촬영한 사진을 바로 올려 게시하는 카메라 갤러리

싱글페이지앱의 라우터 사용법

마스터 디테일 구조학습

최종목표

  1. 카메라로 촬영하기
  2. 파이어베이스 사진 저장하기
  3. 촬영한 사진을 카메라 갤러리에 가져오기

파이어베이스 스토리지 DB준비하기

파이어베이스 스토리지란?

  • iOS, 안드로이드 기기나 사용자 생성 콘텐츠인 이미지, 비디오 파일을 서버가 없이도 웹에 저장할 수 있는 클라우드 서비스 의미
  • 콘솔에서 직접 폴더를 관리, 파일을 업로드할 수 있어서 편리

파이어베이스 스토리지 서비스

  • 카메라로 촬영한 이미지를 서버에 업로드
  • 파이어베이스 DB와 함께 사용 가능
  • 백엔드 관리 용이

워크박스로 서비스 워커에서 캐시관리하가

워크박스의 InjectManifest 모드 학습

  • 카메로 직접 찍은 사지은 기본 캐시가 되지 않음
  • InjectManifest 모드 캐시 적용
728x90

'VueJS > VueJS' 카테고리의 다른 글

2023/06/28__VueJS(Vue3)  (0) 2023.06.28
2023/06/27__VueJS(Vue3)  (0) 2023.06.27
2023/06/19__VueJS(Vue && PWA && Firebase)  (0) 2023.06.20
2023/06/15__VueJS(vuetify)  (0) 2023.06.15
2023/06/14__VueJS(Vuetify)  (0) 2023.06.14
반응형

매개변수만으로 상태값 관리하기

1. 프로젝트 생성 => vue create . => babel과 Router

2. vuetify 설치

    src => App.vue
<template> 
    <v-app>
    
        <!-- 툴바 테마를 primary(파란색)로 설정 -->
        <v-app-bar app color="primary" dark>
           <!-- 좌측에 메뉴 아이콘 생성 -->
      		<v-app-bar-nav-icon></v-app-bar-nav-icon>
      		<v-toolbar-title>Vuex 활용하기</v-toolbar-title>
      		<v-spacer></v-spacer>
      		<v-btn icon>
       			<v-icon>mdi-dots-vertical</v-icon>
      		</v-btn>
        </v-app-bar>
        
        <v-main>
        	<!-- 페이지 장면전환 효과 -->
			<v-slide-x-transition mode="out-in">
    			<router-view></router-view>
			</v-slide-x-transition>
        </v-main>
        
        <!-- footer 여역 테마를 secondary로 설정 -->
        <v-footer color="secondary" fixed dark>
        	<div class="mx-auto">Create By VueJS</div>
        </v-footer>
    </v-app>
</template>
Router => index.js


import Vue from "vue";
import VueRouter from "vue-router";
import mainPage from "../components/main_page.vue";
import subPage from "../components/sub_page.vue";

Vue.use(VueRouter);

const routes = [
   {
    path: "/",
    name: "home",
    component: mainPage,
  },
  {
    path: "/main",
    name: "main",
    component: mainPage,
  },
  {
    path: "/sub",
    name: "subpage",
    component: subPage,
  },
];

const router = new VueRouter({
  mode: "history",
  base: process.env.BASE_URL,
  routes,
});

export default router;
=> component/main_page.vue

<template>
  <v-container>
        <div class="text-center display-3 my-4">메인페이지입니다</div>
    <v-row>
      <v-col sm="10" offset-sm="1">
        <!-- 제목을 입력받으면 sParam 데이터와 바인딩시켜 저장 -->
        <v-text-field label="매개변수1" v-model="sParam1"></v-text-field>
        <v-text-field label="매개변수2" v-model="sParam2"></v-text-field>
      </v-col>
    </v-row>
    <div class="text-center">
      <!-- 확인 단추를 누르면 매개변수값을 가지고 서브페이지로 이동 -->
      <v-btn large class="mt-5" color="purple" dark @click="fnGoSub">
        확인
      </v-btn>
    </div>
  </v-container>
</template>

<script>
export default {
  // 두개의 매개변수 데이터를 저장
  //App.vue 를 제외한 모든 컴포넌트 data는 함수 형식으로 만든다.
data() {
    return {
      sParam1: "",
      sParam2: "",
    };
  },
  methods: {
    fnGoSub() {
      this.$router.push({
        name: "subpage", // =>라우터에 있는 이름과 동일하게
        params: {
          p_param1: this.sParam1,
          p_param2: this.sParam2,
        },
      });
    },
  },
};
</script>
component/sub_page.vue

<template>
  <v-container>
    <v-main>
      <div class="textcenter display-1 my-4">서브페이지입니다</div>
      <v-divider></v-divider>
      <!-- 라우터로 전달받은 두개의 매개변수 값을 데이터 속성에 저장한 뒤에 가져와서 출력 -->
      <div class="text-center display-3 my-4">{{ sTitle1 }}</div>
      <div class="text-center display-3 my-4">{{ sTitle2 }}</div>
      <div class="text-center">
        <v-btn fab large class="mt-5" color="teal" dark to="/main">
          <v-icon>mdi-arrow-right</v-icon>
        </v-btn>
      </div>
    </v-main>
  </v-container>
</template>

<script>
export default {
  // 라우터로 전달받은 값을 가져와서 데이터 속성에 저장함
  data() {
    return {
      sTitle1: this.$route.params.p_param1,
      sTitle2: this.$route.params.p_param2,
    };
  },
};
</script>

뷰 프레임워크로 PWA 만들기

1. pwa by VueJS 미리보기

node.js 필요

npm install -g serve

npm install -g firebase-tools

 

npm run serve

npm run build (배포)

 

2. 프로젝트 제작하기

vue create .

vue add vuetify

public 폴더에 manifest.json파일 생성

manifest.json
{
  "name": "Hello, World~ PWA By VueJS!!",
  "short_name": "PWA by VueJS",
  "icons": [
    {
      "src": "./img/icons/android-chrome-192x192.png",
      "size": "192x192",
      "tyep": "image/png"
    },
    {
      "src": "./img/icons/android-chrome-512x512.png",
      "size": "512x512",
      "tyep": "image/png"
    }
  ],
  "start_url": "./index.html",
  "display": "standalone",
  "orientaion": "portrait",
  "background_color": "#ffffff",
  "theme_color": "#ffffff"
}
=> public/index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width,initial-scale=1.0" />
    <meta name="theme-color" content="#ffffff" />
    <link rel="icon" href="<%= BASE_URL %>favicon.ico" />
    <link rel="manifest" href="manifest.json" />
    <title>Hello, pwa by vue js</title>
    <link
      rel="stylesheet"
      href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900"
    />
    <link
      rel="stylesheet"
      href="https://cdn.jsdelivr.net/npm/@mdi/font@latest/css/materialdesignicons.min.css"
    />
  </head>
  <body>
    <noscript>
      <strong
        >We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work
        properly without JavaScript enabled. Please enable it to
        continue.</strong
      >
    </noscript>
    <div id="app"></div>
    <!-- built files will be auto injected -->
  </body>
</html>
=> src/App.vue
<template>
  <v-app>
    <v-main>
      <!-- fill-height는 브라우저 높이를 100%, 수직으로 가운데 정렬 -->
      <v-container fluid fill-height>
        <v-row>
          <!-- text-center는 수평 가운데 정렬 -->
          <v-col class="text-center" cols="12">
            <!-- 타이포 스타일은 title, 글자색은 흰색으로 설정 -->
            <h1 class="title white--text">Hello!</h1>
            <p class="caption">By Vue.JS</p>
            <img src="./assets/logo.png" alt="" />
          </v-col>
        </v-row>
      </v-container>
    </v-main>
  </v-app>
</template>

<script>
export default {
  name: "App",
  created() {
    //배경색을 다크모드로 함
    //라이브싸이클..실행되는 시점
    this.$vuetify.theme.dark = true;
  },
};
</script>

npm run build 후 npm serve로 확인

 

3. 워크박스로 오프라인 관리하기

워크박스란 무엇인가?

  • 구글에서 제공하는 워크박스는 웹앱의 오프라인 기능을 지원하는 오픈소스 기반의 자바스크립트 라이브러리
  • Vue-CLI 3부터는 워크박스를 기본으로 포함
  • 반복적인 것은 자동화하고 상황에 따라 캐시를 손쉽게 사용할 수 있도록 많은 기능을 제공하여 편리성 제공
  • 예: 스타벅스, 핀터레스트 , WIRED, Forbes

워크박스의 3가지 캐시 전략 이해하기

  • Cache First, staleWhileRevalidate, Network First
캐시전략 방법 용도 대상
Cache First 캐시먼저사용 => 
캐시에 없으면 그때 온라인 사용
캐시가 유용한 폰트, 이미지처럼 바뀔 가능성이 작을때 폰트, 이미지
State While revalidate 캐시먼저사용 =>
캐시 내용이 변경되면 온라인에 접속해 변경된 것으로 교체
캐시가 유용하지만 사용자가 가끔씩 변경할 때 아바타 이미지, CSS, JS
Network First 온라인에 먼저 접속해 사용 =>
오프라인일때 캐시 사용
인터넷 기사처럼 항상 최신 내용이 가장 중요할 때 HTTP요청 URL

4. 파이어베이스 호스팅에 HTTPS로 PWA 배포하기 (구글에서 제공하는 aws 같은 기능)

파이어베이스란

실전에서 사용 가능한 높은 품질의 모바일 앱과 웹앱을 쉽고 빠르게 개발할 수 있도록 서버단에서 필요한 다양한 긴으을 클라우드 서비스로 지원하는 구글의 통합 플랫폼

예) 실시간 데이터베이스, 오픈 인증, 스토리지, 호스팅, 푸시알람서비스, 광고, 분석 등

 

파이어베이스 가격 정책

  • spark 요금제 : 무료
  • 사용 데이터가 일정 기준을 이상 늘어나면 : 유료
  • 스타트업 기업처럼 비용을 아끼면서 초기에 테스트 서버 플랫폼이 필요할 때 유용
  • 10개까지 못만들고 새로운걸 만들시 지우지말고 바꿔 써야함 삭제하면 추가할수 없음

firebase.google.com

console - 

firebase login

firebase init

firebase deploy => git의 push와 같다고 생각하면 됨...

코드수정시 npm run build => firebase deploy 순으로 진행

5. PWA 성능 테스트하기

PWA의 성능을 테스트하는 방법

  • 웹 성능, 웹 접근성, SEO 등
  • 웹앱 매니페스트, HTTPS같은 PWA 서비스 요건을 평가에 집중

라이트하우스(LightHouse)

  • 웹앱 성능을 분석하는 오픈 소스 자동화 도구
  • 웹 사이트의 일반적인 성능과 PWA의 기능을 평가한 후 최고의 성능을 내기 위한 방법 분석 및 보완 목적

 

////////////////////

01. TO_DO 앱 구경하기

To-Do 앱 제작 목적 (CRUD)

할 일을 새로 만들고(C) 읽어오고(R) 수정하고(U) 삭제하는(D) 기능 구현

 

뷰 파이어란

  • 뷰와 파이어베이스를 연결하여 손쉬운 코드만으로 실시간 데이터 기반의 동적인 웹 ui를 빠르게 렌더링 할 수 있도록 해주는 최적의 파이어베이스 데이터바인딩 라이브러리
  • 파이어베이스를 이용해서 최신 웹 애플리케이션의 데이터 관리의 CRUD(Create, Read, Update, Delete)를 쉽고 빠르게 작업하도록 도와주는 솔루션

뷰를 통해서 생성된 PWA 템플릿

  • 워크박스를 사용해 캐시를 체계적으로 관리
  • 자동으로 index.html, css, js, txt 캐시

직접 원하는 파일만 캐시해야 할 상황 발생 시

  • 워크박스 플러그인 모드 활용

워크박스가 제공하는 방식

  • 서비스 워커 파일은 자동 생성 시, 작성한 로직을 서비스 워커에 추가할지 아니면 직접 코드를 함께 포함시킬지를 설정으로 결정

예) GenerateSW 플러그인 모드, InjectManifest 플러그인 모드

플러그인 모드 설명
GenerateSW 자동으로 생성되는 서비스 워커에 워크박스 옵션 지정
InjectManifest 서비스 워커에 자신의 코드를 직접 넣어 최종 서비스 워커 파일 생성

캐시의 종류

  • 프리 캐시(pre-cache) : 실행 전에 미리 지정
  • 런타임 캐시(runtime-cache) : 프로그램이 실행 중에 원하는 부분만 지정

캐시 플러그인 모드

  • GenerateSW 플러그인 모드 : 프리캐시, 런타임 캐시를 간단한 설정값으로 처리
  • InjectManifest 플러그인 모드 : 직접 캐시 정책과 프로그램 로직 추가

CRUD(Create,Read,Update, Delete)

  • 데이터베이스의 기초 기능

CRUD를 간편하게 구현

  • 파이어베이스에서 쉽게 구현할 수 있도록 뷰파이어를 적용

 

 

-- 기타 사항

윈도우 파워쉘로 지정

Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope CurrentUser

Set-ExecutionPolicy RemoteSigned

 

 

728x90

'VueJS > VueJS' 카테고리의 다른 글

2023/06/27__VueJS(Vue3)  (0) 2023.06.27
2023/06/22__VueJS(cache 관련 및 firebase)  (0) 2023.06.23
2023/06/15__VueJS(vuetify)  (0) 2023.06.15
2023/06/14__VueJS(Vuetify)  (0) 2023.06.14
2023/06/13__VueJS(router)  (0) 2023.06.13

+ Recent posts