๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
[๊ฐœ๋ฐœ] Practice/Vue.js

[Vue.js] ํƒญ ๋งŒ๋“ค๊ธฐ ๋ฐ ํƒญ์„ ์ด์šฉํ•œ ์‚ฌ์ง„ ์—…๋กœ๋“œ ํŽ˜์ด์ง€ ๋งŒ๋“ค๊ธฐ

by Connecting-the-dots 2022. 4. 6.
728x90
๋ฐ˜์‘ํ˜•

๐Ÿ’ก ์‹ค์Šต ํฌ์ธํŠธ!

  • ๋‹ค๋ฅธ ํŽ˜์ด์ง€๊ฐ€ ํ•„์š”ํ•˜๋‹ค๋ฉด vue-router ๋ฅผ ์‚ฌ์šฉํ•ด๋„ ๋˜์ง€๋งŒ ๊ฐ„๋‹จํ•œ UI ๋“ค์€ ํƒญ์œผ๋กœ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด ๋”์šฑ ํŽธํ•˜๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ฒŒ ๋˜์—ˆ๋‹ค.
  • ๋‹ค๋งŒ, ํŽ˜์ด์ง€ ์ด๋™(์•ž์œผ๋กœ๊ฐ€๊ธฐ, ๋’ค๋กœ๊ฐ€๊ธฐ) ์™€ ๊ฐ™์€ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ๊ฒƒ์ด๋ผ๋ฉด vue-router ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.
  • ํ•„ํ„ฐ ์„ ํƒ ํŽ˜์ด์ง€์™€ ๊ธ€ ์ž‘์„ฑ ํŽ˜์ด์ง€๋Š” ์•„์ง ๋ฐ์ดํ„ฐ๋ฐ”์ธ๋”ฉ์„ ํ•ด์ฃผ์ง€ ์•Š์•„ ๋ ˆ์ด์•„์›ƒ๋งŒ ๋œจ๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

๐Ÿ’œ step ์ด 0 ์ธ ๊ฒฝ์šฐ (๋ฉ”์ธ ํฌ์ŠคํŠธ ํŽ˜์ด์ง€)


๐Ÿ’œ step ์ด 1 ์ธ ๊ฒฝ์šฐ (ํ•„ํ„ฐ ์„ ํƒ ํŽ˜์ด์ง€/์‚ฌ์ง„ ์—…๋กœ๋“œ ํŽ˜์ด์ง€)


๐Ÿ’œ step ์ด 2 ์ธ ๊ฒฝ์šฐ (๊ธ€ ์ž‘์„ฑ ํŽ˜์ด์ง€)


๐Ÿ’œ ์‚ฌ์ง„ ์—…๋กœ๋“œ ํ™”๋ฉด ๋งŒ๋“ค๊ธฐ

  • Instagram ์„ ๋ณด๋ฉด ๊ธฐ๋ณธ์ ์œผ๋กœ posts ๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” ํŽ˜์ด์ง€๊ฐ€ ์žˆ๊ณ , ์ด๋ฏธ์ง€๋ฅผ ์—…๋กœ๋“œํ•  ๋•Œ ์ด๋ฏธ์ง€๋ฅผ ๊พธ๋ฏธ๋Š” ํŽ˜์ด์ง€ ๋ฐ ๊ธ€์„ ์ ๋Š” ํŽ˜์ด์ง€๊ฐ€ ์žˆ๋‹ค.
  • ์œ„์™€ ์œ ์‚ฌํ•˜๊ฒŒ ๊ธฐ๋Šฅ์„ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด์„œ Container.vue ํŒŒ์ผ ์•ˆ์— ๋ชจ๋“  ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ์„ ๋งŒ๋“ค์–ด ๋„ฃ์–ด๋‘” ํ›„์—, ํƒญ์„ ์„ ํƒํ•˜๋ฉด ํ•ด๋‹น ํƒญ์˜ ๋ ˆ์ด์•„์›ƒ ๋ฐ ๋‚ด์šฉ์„ ๋ณด์—ฌ์ฃผ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ํŠน์ • ์กฐ๊ฑด์ด ์ถฉ์กฑ๋  ๋•Œ ํŠน์ • ํŽ˜์ด์ง€๋ฅผ ๋ณด์—ฌ์ฃผ๋„๋ก ํ•ด์ฃผ์—ˆ๋‹ค.

๐Ÿค App.vue

// ์ „์ฒด ์ฝ”๋“œ ๋ฏธ๋ฆฌ๋ณด๊ธฐ
// ์ „์ฒด ์ฝ”๋“œ์˜ ๋‚ด์šฉ์ด ๊ธธ์–ด css ๋ถ€๋ถ„์€ ์ œ์™ธํ–ˆ๋‹ค.

<template>
  <div class="header">
    <ul class="header-button-left">
      <li>Cancel</li>
    </ul>
    <ul class="header-button-right">
      <li>Next</li>
    </ul>
    <img src="./assets/logo.png" class="logo" />
  </div>

  <Container :posts="posts" :step="step" />

  <button class="btn" @click="more" v-if="step === 0">๋”๋ณด๊ธฐ</button>

  <div class="footer">
    <ul class="footer-button-plus">
      <input type="file" id="file" class="inputfile" />
      <label for="file" class="input-plus">+</label>
    </ul>
  </div>
</template>

<script>
import Container from "./components/Container.vue";
import posts from "./assets/posts";
import axios from "axios";
export default {
  name: "App",
  data() {
    return {
      posts: posts,
      moreCnt: 0,
      step: 0,
    };
  },
  methods: {
    more() {
      axios
        .get(`https://codingapple1.github.io/vue/more${this.moreCnt}.json`)
        .then((result) => {
          this.posts.push(result.data);
          this.moreCnt++;
        })
        .catch(() => {
          console.log("GET ์š”์ฒญ์„ ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค.");
        });
    },
  },
  components: {
    Container: Container,
  },
};
</script>

<style>
</style>
  • ๋จผ์ €, data ๋ณด๊ด€ํ•จ์— step ์ด๋ผ๋Š” ํ•ญ๋ชฉ์„ ๋งŒ๋“ค์–ด์„œ 0~2๊นŒ์ง€์˜ ์ˆซ์ž๋ฅผ ์ €์žฅํ•˜๊ธฐ๋กœ ํ–ˆ๋‹ค.
  • step ์ด 0 ์ธ ๊ฒฝ์šฐ์—๋Š” ๋ฉ”์ธํ™”๋ฉด์ธ Post.vue ๋ฅผ ๋ณด์—ฌ์ฃผ๋„๋ก ํ•˜๊ณ  step ์ด 1 ์ธ ๊ฒฝ์šฐ์—๋Š” ํ•„ํ„ฐ ์„ ํƒ ํŽ˜์ด์ง€๋ฅผ, step ์ด 2 ์ธ ๊ฒฝ์šฐ์—๋Š” ๊ธ€ ์ž‘์„ฑ ํŽ˜์ด์ง€๋ฅผ ๋ณด์—ฌ์ฃผ๋„๋ก ๋ง์ด๋‹ค.
  • ๊ฐ ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ์˜ ๊ฒฝ์šฐ Container.vue ํŒŒ์ผ์— ์žˆ์œผ๋ฏ€๋กœ, step ์„ step ์ด๋ผ๋Š” ์ด๋ฆ„์œผ๋กœ props ๋ฌธ๋ฒ•์„ ์‚ฌ์šฉํ•˜์—ฌ Container.vue ๋กœ ์ „์†กํ•ด์ฃผ์—ˆ๋‹ค.
  • ์ด์™€๋Š” ๋ณ„๊ฐœ๋กœ ์‚ฌ์ง„ ์—…๋กœ๋“œ ํŽ˜์ด์ง€๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ๊ณผ๋Š” ์ƒ๊ด€ ์—†์ง€๋งŒ, "๋”๋ณด๊ธฐ" ๋ฒ„ํŠผ์˜ ๊ฒฝ์šฐ Post.vue ๋ฅผ ๋ณด์—ฌ์ค„ ๋•Œ์—๋งŒ ๋ณด์ด๋Š” ๊ฒŒ ์ž์—ฐ์Šค๋Ÿฌ์›Œ์„œ, v-if ๋ฌธ์„ ์ถ”๊ฐ€ํ•˜์—ฌ step ์ด 0 ์ธ ๊ฒฝ์šฐ์—๋งŒ ๋ณด์ด๋„๋ก ํ•ด์ฃผ์—ˆ๋‹ค.

๐Ÿค Container.vue

// ์ „์ฒด ์ฝ”๋“œ ๋ฏธ๋ฆฌ๋ณด๊ธฐ
// ์ „์ฒด ์ฝ”๋“œ์˜ ๋‚ด์šฉ์ด ๊ธธ์–ด css ๋ถ€๋ถ„์€ ์ œ์™ธํ–ˆ๋‹ค.

<template>
  <div>
    <div v-if="step === 0">
      <Post :post="post" v-for="(post, i) in posts" :key="i" />
    </div>

    <!-- ํ•„ํ„ฐ์„ ํƒํŽ˜์ด์ง€ -->
    <div v-if="step === 1">
      <div class="upload-image"></div>
      <div class="filters">
        <div class="filter-1"></div>
        <div class="filter-1"></div>
        <div class="filter-1"></div>
        <div class="filter-1"></div>
        <div class="filter-1"></div>
      </div>
    </div>

    <!-- ๊ธ€์ž‘์„ฑํŽ˜์ด์ง€ -->
    <div v-if="step === 2">
      <div class="upload-image"></div>
      <div class="write">
        <textarea class="write-box">write!</textarea>
      </div>
    </div>
  </div>
</template>

<script>
import Post from "./Post.vue";
export default {
  name: "Container",
  data() {
    return {};
  },
  components: {
    Post: Post,
  },
  props: {
    posts: Array,
    step: Number,
  },
};
</script>

<style>
</style>
  • ์ด์ œ App.vue ์—์„œ props ๋ฌธ๋ฒ•์œผ๋กœ Container.vue ๋กœ ์ „๋‹ฌ๋ฐ›์€ step ์„ props ์— ๋“ฑ๋กํ•ด์ฃผ์—ˆ๋‹ค.
  • ๊ทธ ๋‹ค์Œ์œผ๋กœ, v-if ๋ฌธ์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ step ์˜ ์ˆซ์ž์— ๋”ฐ๋ผ ๋ณด์—ฌ์ค„ ํŽ˜์ด์ง€๋“ค์„ ๋ฌถ์–ด์ฃผ์—ˆ๋‹ค.
  • ๋”ฐ๋ผ์„œ, ์ด์ œ step ์ด 0 ์ธ ๊ฒฝ์šฐ์—๋Š” ๋ฐ์ดํ„ฐ ๊ฐœ์ˆ˜๋งŒํผ Post.vue ๋ฅผ ๋ณด์—ฌ์ฃผ๊ณ , step ์ด 1 ์ธ ๊ฒฝ์šฐ์—๋Š” ํ•„ํ„ฐ ์„ ํƒ ํŽ˜์ด์ง€๋ฅผ ๋ณด์—ฌ์ฃผ๊ณ , step ์ด 2 ์ธ ๊ฒฝ์šฐ์—๋Š” ๊ธ€ ์ž‘์„ฑ ํŽ˜์ด์ง€๊ฐ€ ๋ณด์—ฌ์ง€๊ฒŒ ๋˜๋Š” ๊ฒƒ์ด๋‹ค.

 

728x90
๋ฐ˜์‘ํ˜•