programing

다른 어레이로 이동할 때 Vue Keep Alive 구성 요소

procenter 2023. 2. 2. 22:01
반응형

다른 어레이로 이동할 때 Vue Keep Alive 구성 요소

바인딩된 항목 개체를 다른 데이터 배열로 이동할 때 구성 요소를 활성 상태로 유지하려고 합니다.이동하기 때문에 기본 keep-alive 태그는 작동하지 않습니다.

앱의 동적 구성 요소가 외부 라이브러리를 사용할 때 로드 시간을 단축하기 위해 필요합니다.

간단한: (https://jsfiddle.net/eywraw8t/24419/)

HTML:

<div id="app">
  <div v-for="list in lists">
    <h1>{{ list.title }}</h1>
    <ul>
      <draggable v-model="list.items" :options="{group: 'list-items'}">
        <list-item 
           v-for="item in list.items" 
           :key="item.key" 
           :content="item.content">
        </list-item>
      </draggable>
    </ul>
  </div>
</div>

JS:

Vue.component('list-item', {
  props: {
    content: {
        required: true
    }
  },
  mounted () {
    document.body.insertAdjacentHTML('beforeend', 'Mounted! ');
  },
  template: '<li>{{ content }}</li>'
})

new Vue({
  el: "#app",
  data: {
    lists: [
        {
        title: 'List 1',
        items: [
            { key: 'item1', content: 'Item 1' },
          { key: 'item2', content: 'Item 2' },
          { key: 'item3', content: 'Item 3' }
        ]
      },
      {
        title: 'List 2',
        items: [
            { key: 'item4', content: 'Item 4' },
          { key: 'item5', content: 'Item 5' },
          { key: 'item6', content: 'Item 6' }
        ]
      }
    ]
  }
})

고가의 html 빌드를 캐싱하는 데만 문제가 있는 경우,list-item템플릿에서 컴포넌트를 생성하여 사전에 구축합니다.app.mounted().

실제 시나리오에서 이것이 얼마나 잘 작동하는지는item.content라이프 사이클입니다.

console.clear()
const ListItem = Vue.component('list-item', {
  props: {
    content: {
      required: true
    }
  },
  mounted () {
    document.body.insertAdjacentHTML('beforeend', 'Mounted! ');
  },
  template: '<li>{{ content }}</li>'
})

new Vue({
  el: "#app",
  methods: {
    getHtml(content) {
      const li = new ListItem({propsData: {content}});
      li.$mount()
      return li.$el.outerHTML
    }
  },
  mounted () {
    this.lists.forEach(list => {
      list.items.forEach(item => {
        const cacheHtml = this.getHtml(item.content)
        Vue.set( item, 'cacheHtml', cacheHtml )
      })
    })
  },
  data: {
    lists: [
    	{
      	title: 'List 1',
        items: [
        	{ key: 'item1', content: 'Item 1' },
          { key: 'item2', content: 'Item 2' },
          { key: 'item3', content: 'Item 3' }
        ]
      },
      {
      	title: 'List 2',
        items: [
        	{ key: 'item4', content: 'Item 4' },
          { key: 'item5', content: 'Item 5' },
          { key: 'item6', content: 'Item 6' }
        ]
      }
    ]
  }
})
ul {
  margin-bottom: 20px;
}

li:hover {
  color: blue;
  cursor: move;
}

h1 {
  font-size: 20px;
  font-weight: bold;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Sortable/1.6.0/Sortable.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Vue.Draggable/15.0.0/vuedraggable.min.js"></script>

<div id="app">
  <div v-for="list in lists">
    <h1>{{ list.title }}</h1>
    <ul>
      <draggable v-model="list.items" :options="{group: 'list-items'}">
        <div v-for="item in list.items" :key="item.key">
          <li v-html="item.cacheHtml"></li>   
        </div>
      </draggable>
    </ul>
  </div>
</div>

반응성 항목.내용

반응성을 유지하기 위해item.content조금 더 코드가 필요합니다.

  • 복사본을 추가하다item.content캐시에
  • 내용이 변경된 경우 새로 고침을 사용하여 캐시된 html을 가져오는 메서드를 추가합니다.

(파라미터화된 계산 속성을 사용하면 좀 더 우아하게 이 작업을 수행할 수 있습니다).

item.content 변경을 시뮬레이트하기 위해 set Timeout을 mounted()에 추가했습니다.

console.clear()
const ListItem = Vue.component('list-item', {
  props: {
    content: {
      required: true
    }
  },
  mounted () {
    document.body.insertAdjacentHTML('beforeend', 'Mounted! ');
  },
  template: '<li>{{ content }}</li>'
})

new Vue({
  el: "#app",
  methods: {
    getHtml(content) {
      const li = new ListItem({
        propsData: { content }
      });
      li.$mount()
      return li.$el.outerHTML
    },
    cacheHtml(item) {
      if (item.cache && item.cache.content === item.content) {
        return item.cache.html
      } else {
        const html = this.getHtml(item.content)
        const cache = {content: item.content, html} 
        Vue.set(item, 'cache', cache)
      }
    }
  },
  mounted () {
    this.lists.forEach(list => {
      list.items.forEach(item => {
        this.cacheHtml(item)
      })
    })
    setTimeout(() => 
      Vue.set( this.lists[0].items[0], 'content', 'changed' )
    ,2000)      
  },
  data: {
    lists: [
    	{
      	title: 'List 1',
        items: [
        	{ key: 'item1', content: 'Item 1' },
          { key: 'item2', content: 'Item 2' },
          { key: 'item3', content: 'Item 3' }
        ]
      },
      {
      	title: 'List 2',
        items: [
        	{ key: 'item4', content: 'Item 4' },
          { key: 'item5', content: 'Item 5' },
          { key: 'item6', content: 'Item 6' }
        ]
      }
    ]
  }
})
ul {
  margin-bottom: 20px;
}

li:hover {
  color: blue;
  cursor: move;
}

h1 {
  font-size: 20px;
  font-weight: bold;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Sortable/1.6.0/Sortable.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Vue.Draggable/15.0.0/vuedraggable.min.js"></script>

<div id="app">
  <div v-for="list in lists">
    <h1>{{ list.title }}</h1>
    <ul>
      <draggable v-model="list.items" :options="{group: 'list-items'}">
        <div v-for="item in list.items" :key="item.key">
          <li v-html="cacheHtml(item)"></li>   
        </div>
      </draggable>
    </ul>
  </div>
</div>

당신의 문제를 조사해 보았습니다.해결책을 찾을 수 있을 것 같습니다.저는 jsfeeld로는 할 수 없지만 설명하겠습니다.

js 바이올린에서 마운트된 것은 목록 항목 구성요소에 잠기므로 실제로 해당 상태가 변경될 때마다(끌 때) 이벤트가 트리거됩니다.

메인 템플릿 구성 요소(componentX)와 마운트된 기능을 사용하여 설정을 만들고 분리된 목록 항목 구성 요소를 만듭니다.

제 샘플에서는 처음에 마운트된 것이 두 번 표시됩니다.이것은 2개의 리스트가 있기 때문에 정상입니다.그러나 드래그 앤 드롭을 시작하면 마운트된 이벤트가 더 이상 표시되지 않습니다.

다음 사이트에서 zip으로 솔루션을 다운로드할 수 있습니다.

http://www.bc3.eu/download/test-vue.zip

vue cli 프로젝트이기 때문에npm run dev로컬 서버를 기동하다

언급URL : https://stackoverflow.com/questions/49732777/vue-keep-alive-component-when-moving-to-other-array

반응형