programing

목록에서 선택한 요소를 변경하면 Vue.js가 전환됩니다.

goodcopy 2022. 8. 10. 00:08
반응형

목록에서 선택한 요소를 변경하면 Vue.js가 전환됩니다.

프로필 편집 화면을 여는 프로필 목록이 있습니다.이 화면은 왼쪽에서 옆으로 미끄러져 들어왔다.프로파일을 선택할 때 이미 선택된 화면이 있으면 먼저 슬라이드하여 선택한 프로파일 데이터를 변경한 후 슬라이딩합니다.

여기서의 조작은, 1개의 요소를 처음 선택하면, 화면이 슬라이딩 됩니다.선택한 요소를 변경하면 화면은 그대로 유지되고 슬라이드되었다가 다시 삽입되지 않습니다.

다음은 동작 상황을 보여주는 gif입니다.

여기에 이미지 설명 입력

암호는 다음과 같습니다.

Vue 방법:

editProfile: function (index){
    // this.editingProfile = false;
    this.setProfile(index);
    this.editingProfile = true;

}

Html 보기:

        <transition name="fade" mode="out-in">
            <div v-if="editingProfile" id="edit-profile">
                <input placeholder="Profile Name" v-model="synced.profiles[synced.selectedProfile].name">
            </div>
        </transition>

CSS:

.fade-enter-active, .fade-leave-active {
   transition: all .2s;
   /* transform:translateX(0); */
  }
  .fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ {
    opacity: 0;
    transform:translateX(-100%);
  }

프로파일을 변경할 때 올바르게 슬라이드되었다가 다시 삽입하려면 어떻게 해야 하나요?

제 말이 틀린 것 같아요.이를 가능하게 하는 한 가지 방법은:key및 av-if패널을 선택한 경우 Vue에게 패널을 렌더링하도록 지시한 다음 패널 간에 전환하도록 지시할 수 있습니다.필요한 것은 없습니다.transition-group그리고나서.

중요한 건:keyVue에게 모든 게 변했다는 걸 말해주는 거야Vue는 그것을 끄면 가능한 한 많이 재활용하려고 합니다.다음의 문서를 참조해 주세요.요소 간의 이행

태그 이름이 동일한 요소 간에 전환할 때는 Vue에 고유 요소를 지정하여 서로 다른 요소임을 알려야 합니다.key특성.그렇지 않으면 Vue 컴파일러는 효율화를 위해 요소의 내용만 대체합니다.기술적으로 불필요한 경우에도 컴포넌트 내에서 항상 여러 항목을 핵심으로 하는 것이 좋습니다.

다음의 최소한의 예를 검토해 주세요.

const panels = [{
    title: "Hello"
  },
  {
    title: "World"
  },
  {
    title: "Foo"
  },
  {
    title: "Bar"
  }
];

const app = new Vue({
  el: "#app",
  data() {
    return {
      panels,
      activePanel: null
    };
  },
  computed: {
    titles() {
      return this.panels.map(panel => panel.title);
    }
  },
  methods: {
    handleTitleClick(idx) {
      if (this.activePanel === idx) {
        this.activePanel = null;
        return;
      }
      this.activePanel = idx;
    }
  }
});
body {
  margin: 0;
  padding: 0;
}

#app {
  display: flex;
  align-items: stretch;
  height: 100vh;
}

#panel-set {
  flex: 1 0 70%;
  display: flex;
}

#side-panel {
  flex: 1 0 30%;
}

.panel {
  padding: 1em;
  flex: 1 0;
  background-color: rgba(0, 0, 0, 0.2);
}

.slide-fade-enter-active,
.slide-fade-leave-active {
  transition: transform 500ms ease-in-out;
}

.slide-fade-enter,
.slide-fade-leave-to {
  transform: translateX(-100%);
}
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.min.js"></script>


<div id="app">
  <div id="panel-set">
    <transition name="slide-fade" mode="out-in">
      <div class="panel" v-if="activePanel !== null" :key="activePanel">
        <h2>{{panels[activePanel].title}}</h2>
        <p>Lorem ipsum</p>
      </div>
    </transition>
  </div>
  <div id="side-panel">
    <ul>
      <li v-for="(title, idx) in titles" @click="handleTitleClick(idx)">{{title}}</li>
    </ul>
  </div>
</div>

근본 원인은v-if="editingProfile"코드에 하나의 프로파일을 표시한 후에는 항상 true입니다.

1개의 솔루션은 처음에 false로 설정되고 다음으로 in으로 설정합니다.this.$nextTick다시 현실로 만들기 위해서요.하지만 넌 그걸 넣어야 해this.editingProfile = true내면에setTimeout및 지연 시간 = 전환 시간.그렇지않으면,slide out효과가 덮어쓰게 됩니다.

아래와 같은 데모:

new Vue({
  el: '#emit-example-simple',
  data() {
    return {
      editingProfile: false,
      synced : {
        profiles: [{'name':'A'}, {'name':'B'}, {'name':'C'}],
        selectedProfile: 0
      },
    }
  },
  methods: {
    editProfile: function (index){
      this.editingProfile = !this.editingProfile
      this.$nextTick(() => {
        setTimeout(()=> {
        this.synced.selectedProfile = index
        this.editingProfile = true
        }, 1200)
      })
    }
  }
})
.fade-enter-active, .fade-leave-active {
   transition: all 1.2s;
   /* transform:translateX(0); */
  }
.fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ {
  opacity: 0;
  transform:translateX(-100%);
  border: 1px solid white;
}
<script src="https://unpkg.com/vue/dist/vue.js"></script>

<div id="emit-example-simple">
  <button @click="editProfile(0)">Profile 1</button>
  <button @click="editProfile(1)">Profile 2</button>
  <button @click="editProfile(2)">Profile 3</button>
  <transition name="fade" mode="out-in">
      <div v-if="editingProfile" id="edit-profile">
          <input style="border: 5px solid red;" placeholder="Profile Name" v-model="synced.profiles[synced.selectedProfile].name">
      </div>
  </transition>
</div>

또는 다음 중 하나를 사용할 수도 있습니다.Group transition다음과 같은 간단한 데모:

new Vue({
  el: '#emit-example-simple',
  data() {
    return {
      editingProfile: false,
      profileContainers: [true, false],
      synced : {
        profiles: [{'name':'A'}, {'name':'B'}, {'name':'C'}],
        selectedProfile: 0
      },
    }
  },
  methods: {
    editProfile: function (index){
      this.synced.selectedProfile = index
      this.profileContainers = this.profileContainers.map((x)=>!x)
    }
  }
})
.list-items-enter-active {
 transition: all 1.2s;
}
.list-items-leave-active {
 transition: all 1.2s;
}
.list-items-enter, .list-items-leave-to /* .fade-leave-active below version 2.1.8 */ {
  opacity: 0;
  transform:translateX(-100%);
  border: 1px solid white;
}

.list-item {
  display: inline-block;
  border: 6px solid red;
}
<script src="https://unpkg.com/vue/dist/vue.js"></script>

<div id="emit-example-simple">
  <button @click="editProfile(0)">Profile 1</button>
  <button @click="editProfile(1)">Profile 2</button>
  <button @click="editProfile(2)">Profile 3</button>
  <transition-group name="list-items" tag="p">
    <div v-for="(item, index) in profileContainers" :key="index" v-if="item">
        <input style="border: 5px solid red;" placeholder="Profile Name" v-model="synced.profiles[synced.selectedProfile].name">
    </div>
  </transition-group>
</div>

언급URL : https://stackoverflow.com/questions/51827316/vue-js-transition-on-changing-selected-element-from-a-list

반응형