Vue.js에서 여러 개의 접기 실현

15794 단어 Vue.js

입문


Vue.js로 응용 프로그램을 만드는 과정에서 나는 여러 개의 아코디언 설치에 푹 빠졌다.
인터넷에서 참고할 만한 기사를 찾는 것과 같이 고민하는 사람들이 곳곳에서 볼 수 있으니 누구의 참고가 될 수 있다면 좋겠다.

목표 독자


Vue.js 초보자(나 포함)

전제 조건


프런트엔드는 Vue입니다.js, 서버 측은 Rails로 제작합니다.
투고(post) 내용을 카드 형식으로 일람하고 투고의 제목 이름을 클릭하면 투고의 상세한 내용이 표시됩니다.

반한 곳


아코디언이 개폐되었을 때, 모든 아코디언이 개폐되었다.사실 카드마다 스위치를 켜고 싶은데...

코드


fetchPosts 방법으로 포스트 모델의 내용을 얻고 게시물의 제목과 사진을 표시합니다.toggleShowPost에서 show 속성의 진/위를 제어하여 게시물의 상세한 내용의 표시와 숨김을 전환합니다.
PostHome.vue
<template>
  <div class="container">
    <div class="row">
      <div class="col s7 m7" v-for="post in posts" v-bind:key="post.id">
        <div class="card">
          <div class="card-image">
            <img :src="post.image.url"/>
          </div>
          <div class="card-content" v-on:click="toggleShowPost">
            <div class="card-title">
              {{post.title}}
            </div>
            <div class="card-more">
              <div v-if="show">
                <font-awesome-icon icon="angle-up" size="lg"/>
              </div>
              <div v-else>
                <font-awesome-icon icon="angle-down" size="lg"/>
              </div>
            </div>
          </div>
          <div class="card-detail" v-show="show">
            {{post.content}}
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
  import axios from 'axios'

  export default {
    name: 'PostHome',
    data: function() {
      return{
        posts: [],
        show: false
      }
    },
    mounted: function(){
      this.fetchPosts();
    },
    methods: {
      fetchPosts(){
        axios.get(`api/v1/posts`).then(res => {
          for(var i = 0; i < res.data.posts.length; i++) {
            this.posts.push(res.data.posts[i]);
          }
        }, (error) => {
          console.log(error);
        });
      },
      toggleShowPost(){
        this.show = !this.show
      }
    }
  }
</script>
모든 아코디언이 스위치된 것은 toggle ShowPost 내의this가 전체 Vue Component를 가리키기 때문에 모든 show 속성이 전환이 적용되었기 때문이다.
즉, 모든 카드에 show 속성을 정의하고 전환해야 한다.

해결 방법


나는 구체적으로 어떻게 설치해야 할지 조사한 결과 이 글을 찾았다.
Rails x Vue.js에서 여러 개의 접기 Tech를 실현하는 datebook-비망록-
이 문장을 참고하여 수정한 코드는 여기에 있다
PostHome.vue
<template>
  <div class="container">
    <div class="row">
      <div class="col s7 m7" v-for="(post, index) in posts" v-bind:key="post.id">
        <div class="card">
          <div class="card-image">
            <img :src="post.image.url"/>
          </div>
          <div class="card-content" v-on:click="toggleShowPost(index)">
            <div class="card-title">
              {{post.title}}
            </div>
            <div class="card-more">
              <div v-if="show[index]">
                <font-awesome-icon icon="angle-up" size="lg"/>
              </div>
              <div v-else>
                <font-awesome-icon icon="angle-down" size="lg"/>
              </div>
            </div>
          </div>
          <div class="card-detail" v-show="show[index]">
            {{post.content}}
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
  import axios from 'axios'

  export default {
    name: 'PostHome',
    data: function() {
      return{
        posts: [],
        show: {}
      }
    },
    mounted: function(){
      this.fetchPosts();
    },
    methods: {
      fetchPosts(){
        axios.get(`api/v1/posts`).then(res => {
          for(var i = 0; i < res.data.posts.length; i++) {
            this.posts.push(res.data.posts[i]);
          }
        }, (error) => {
          console.log(error);
        });
      },
      toggleShowPost(key){
        this.$set(this.show, key, !this.show[key])
      }
    }
  }
</script>
변경 사항
  • show 속성을 수조로 변경하고, 수조의 아래 표시를 카드마다 유일한 값으로 변경합니다(여기는 v-for 명령의 index입니다)
  • toggleShowPost는 Show 속성에 클릭한 카드의 Boolean 값을 추가합니다.
    처음 눌렀을 때 show 속성에 키가 존재하지 않기 때문에this.show[key]은undefined이기 때문에 반전(!this.show[key])을 통해true
  • 눌렀을 때 표시하고자 하는 투고 내용(post.content)v-show="show[index].(Font Awesome 아이콘이 v-if="show[index]"v-else 사이를 전환합니다
  • 이런 느낌으로 카드 스위치를 눌러도 돼요.

    좋은 웹페이지 즐겨찾기