๐Ÿ‘’ Vue 3. The composition API

chloeยท2021๋…„ 9์›” 28์ผ
0

TIL

๋ชฉ๋ก ๋ณด๊ธฐ
81/81
post-thumbnail

Vue 3์—์„œ ์ƒˆ๋กœ ๋“ฑ์žฅํ•œ The composition API์— ๋Œ€ํ•ด ์•Œ์•„๋ณด์ž.

import getPosts from './getPosts'
export default{
setup(){
// data
//methods
//computed
//lifecycle hooks
const data=getPosts()
}
}

1.Group logic together in a setup function
2.Easily create reusable logic(Functions)

์˜ˆ์‹œ ์ฝ”๋“œ๋ฅผ ์‚ดํŽด๋ณด์ž.

<template>
<div class="home">
home
<p ref='p'>My name is {{name}} and my age is {{age}}</p>
<button @click="handleClick">click me </button>
<input type='text' v-model='name'> //์ธํ’‹์— ์ž‘์„ฑํ•˜๋Š”๋Œ€๋กœ name์ด ๋ณ€๊ฒฝ๋œ๋‹ค
</div>
</template>
<script>
import {ref} from'vue'
export default{
  name:'Home',
  //setup() is always runs first before created and mounted..
  setup(){
  console.log('setup')
  const p = ref(null)
  console.log(p,p.value)
  
  //These are not reactive by default
  let name='mario'
  let age=30
  //we can use refs to create reactive values!
  const name=ref('mario')
  const age=ref(30)
  
  const  handleClick=()=>{
  console.log(p,p.value);
  p.value.classList.add('test')
  p.value.textContent='hello,ninjas';// ๋ฒ„ํŠผ ๋ˆ„๋ฅด๋ฉด p ๋‚ด์šฉ์˜ ๊ฐ’์ด ๋ฐ”๋€๋‹ค.
  //name๊ณผ age์˜ ๊ฐ’์ด ๋ณ€๊ฒฝ๋œ๋‹ค(๋ฒ„ํŠผ ๋ˆ„๋ฅด๋ฉด)
name.value='loco'
age.value=29 
  }
  return {name,age,handleClick,p}
  }
  }
  </script>

๐Ÿ‘’ Refs vs Reactive

<template>
  <div class='home'>
   <h1>Home</h1>
   <h2>Refs</h2>
  <p> {{ninjaOne.name}}-{{ninjaOne.age}}</p>
  <button @click='updateNinjaOne'>Update ninja one</button>
<h2>Reactive</h2>
<p>{{ninjaTwo.name}}-{{ninjaTwo.age}}</p>
<button @click="updateNinjaTwo">Update ninja two</button>
</div>
</template>
<script>
import {ref,reactive} from 'vue'
export default {
  name:'Home',
  setup() {
    const ninJaOne=ref({name:'mario',age:30})
    const ninjaTwo=reactive({name:'luigi',age:34})
    
    const nameOne=ref('mario')
    const nameTwo=reactive('luigi');
    //luigi๊ฐ’์€ primitive value์ด๊ธฐ์— ์—…๋ฐ์ดํŠธ ๋˜์ง€ ๋ชปํ•œ๋‹ค.
    const updateNinjaOne=()=>{
      ๐Ÿ ninjaOne.value.age=40
    }
    const updateNinjaTwo=()=>{
      ๐Ÿ ninjaTwo.age=45
         nameTwo='mario' // ์ „ํ˜€ ์—…๋ฐ์ดํŠธ ๋˜์ง€ ์•Š๋Š”๋‹ค.
       
    return{ninjaOne,updateNinjaOne,ninjaTwo,updateNinjaTwo}
  }
}

ref๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ๋Š”, ๊ฐ’์— ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•ด value๋ฅผ ํ•ญ์ƒ ์ ์–ด์ค˜์•ผํ–ˆ๋‹ค.
๊ทธ๋Ÿฌ๋‚˜reactive๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ๋Š” value๋ฅผ ์‚ฌ์šฉํ•  ํ•„์š”์—†๋‹ค.
๋‘˜ ์ค‘์— ๋ฌด์–ผ ์“ฐ๋Š” ๊ฒƒ์ด ์ข‹์€๊ฐ€?reactive๋Š” ๊ฐ’์„ ์—…๋ฐ์ดํŠธํ•˜๊ธฐ ์–ด๋ ต๋‹ค. ์—ฌ๋Ÿฌ์ด์œ ๋กœ ref๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋” ์ข‹๋‹ค

๐Ÿ‘’ Computed values

<template>
  <div class='home'>
    <h1>Home</h1>
    <input type='text' v-model='search'>
     <p>search term - {{search}}</p>
    <div v-for="name in matchingNames" :key="name">{{name}}</div>
  </div>
</template>
<script>
    import {computed,ref} from'vue'
export default {
  name:'Home',
  setup(){
    const search=ref('')
   const names=ref(['mario','yoru','luigi','tod','peach'])
   const matchingNames = computed(()=>{
     return names.value.filter((name) => name.includes(search.value))
                                      
   })
    return {names,search}
  }
}
</script>

๐Ÿ‘’ Using props in setup

<template>
  <div class="home">
    <h1>Home</h1>
  ๐Ÿ‡ <PostList v-if='showPosts' :posts='posts' />
    //๋งŒ์•ฝ showPosts๊ฐ€ false์ด๋ฉด ์ด ์ปดํฌ๋„ŒํŠธ๋Š” ์–ธ๋งˆ์šดํŠธ๋˜์–ด์„œ ์•ˆ๋ณด์ด๊ฒŒ ๋  ๊ฒƒ์ด๋‹ค.
    <button @click='showPosts =!showPosts'>toggle posts</button>
<button @click="posts.pop()"> delete a post </button>
 </div>
</template>
<script>
      ๐Ÿ‡ import PostList from '../';
   import {ref} from 'vue'
  export default {
    name:'Home',
     ๐Ÿ‡ components:{PostList},
    setup(){
      const posts = ref([
        {title:'welcome',body:'lorem',id:1},
        {title:'top 5 tips', body:'Lorem',id:2}
        ])
      const showPosts = ref(true)
      return {posts,showPosts}
    }
  }
</script>

==PostList.vue===

<template>
  <div class='post-list'>
    <div v-for='post in posts :key='post.id'>
     <h3>{{post.title}}</h3>
    </div>
 </div>
</template>
<script>
 export default {
  props:['posts'],
  setup(props) {
    console.log(props.posts)
                }
                }
</script>

๐Ÿ‘’ Lifecycle hooks in setup

<template>
  <div class='post-list'>
    <div v-for='post in posts :key='post.id'>
   <SinglePost :post='post'/>
    </div>
 </div>
</template>
<script>
 import { onMounted , onUnmounted,onUpdated} from 'vue'
 import SinglePost from './SinglePost.vue'

 export default {
  props:['posts'],
   components:{SinglePost},
  ๐Ÿˆ setup(props) {
     onMounted(()=>console.log('component mounted')
     onUnmounted (()=>console.log('component unmounted')
      onUpdated(()=>console.log('component updated'))
                }
                }
</script>

๐Ÿ‘’ Fetching data in setup

<template>
  <div class='home'>
    <h1> Home</h1>
  <div v-if='error'>{{error}} </div>
<div v-if="posts.length'>
   <PostList :posts='posts' />
     </div>
<div v-else > Loading...</div>
   </div>
</template>

<script>
import PostList from '../'
import {ref} from 'vue'

export default {
  name:'Home',
  components:{PostList},
  setup(){
    const posts=ref([])
    const error=ref(null)
    ๐Ÿ•น const load=async()=>{
      try{
        let data= await fetch('http://localhost:3000/posts'
                             )
        if(!data.ok){
          throw Error('no data available')
        }
        posts.value = await data.json()
      catch(err){
        error.value=err.message
        console.log(error.value)
      }
    }
      load();
    return {posts,error}
    

๐Ÿ‘’ Composition API & TypeScript

<template>
  <div class='app'>
    <p> {{ jobs[0]/location</p>
   </div>
 </template>
<script lang='ts'>
  import {defineComponent,reactive,toRefs,ref} from 'vue';
  im
  import Job from './types/Job';
  export default defineComponent ({
    name:'App',
    components:{},
    setup(){
      //const state = reactive ({
        //name:'Link',
        //age:25 as string | number <Type Assertion>
     // })
      //state.name =99999 //cannot change type
      //If I change the name as a number,this is not gonna work.
      //state.age='26'
      //return {...toRefs(state)}
      
      const name = ref('Link')
      const age = ref<number|string>(25); //we can use generic arguments instead of using type assertion
      age.value=26 ๊ฐ€๋Šฅ
      age.value='26'๊ฐ€๋Šฅํ•ด์ง
      
      return {name,age}
      
      const jobs=ref<Job[]>([
        {title:'farm worker',location:'London' salary:30000,id:'1'}
           {title:'lawyer',location:'Newyork' salary:40000,id:'2'}
       {title:'engineer',location:'Paris' salary:30000,id:'3'}
        ])
        return {jobs}
      },
    
    methods:{
      changeName(name:string){
        this.name =name
        return name
      },
      changeAge(age:string|number){
        this.age = age
        return age
      }
    }
  });
</script>

====Job.ts==============

interface Job {
 title:string,
 location:string,
 salary:number,
 id:string
}
export default Job

์ฐธ๊ณ :Youtube_The Net Ninja

profile
Front-end Developer ๐Ÿ‘ฉ๐Ÿปโ€๐Ÿ’ป

0๊ฐœ์˜ ๋Œ“๊ธ€