个人自学前端30-Vue7-动态组件,缓存组件

一. 动态组件

挂载时,可以通过is属性知道组件名来挂载
动态组件 => 动态修改is属性的值,实现动态挂载不同的组件。
动态组件在切换过程中,会频繁的创建和销毁.
显示时创建,隐藏时销毁.

  <script>
    const box = {
      template: `<li>111111111111</li>`
    }
    const item = {
      template: `<li>222222222222</li>`
    }
    const App = {
      template: `
        <div>
          <h3>App组件</h3>
          <button @click='fn'>按钮</button>
          <ul>
            <li :is='cn'></li>
          </ul>
        </div>
      `,
      data() {
        return { cn: 'box'}
      },
      methods: {
        fn() {
          if (this.cn === 'box') {
            this.cn = 'item';
          } else {
            this.cn = 'box';
          }
        }
      },
      components: { box, item }
    }
    new Vue({
      render: h => h(App),
    }).$mount('#app')
  </script>

二. 缓存组件keep-alive

动态组件默认无法保留组件状态,每次切换都是初始状态.

要保留组件状态,可以使用keep-alive包裹动态组件.
keep-alive是一个抽象的内置组件.
包裹之后,组件就不会重复的创建和销毁.created和destroyed只触发一次.

keep-alive默认缓存所有渲染过的动态组件.
keep-alive如何实现部分缓存?
利用属性include => 包含某某组件 => 只缓存某某组件
利用属性exclude => 不包含某某组件 => 除了某某组件都缓存.

keep-alive对v-if也生效.

  <script>
    const box = {
      template: `<li>111<input type='text' /></li>`,
    }
    const item = {
      template: `<li>222<input type='text' /></li>`
    }
    const App = {
      template: `
        <div>
          <h3>App组件</h3>
          <button @click='flag = !flag'>按钮</button>
          <ul>
            <keep-alive>
              <box v-if='flag'></box>
              <item v-else></item>
            </keep-alive>
          </ul>
        </div>
      `,
      data() {
        return { flag: true }
      },
      components: { box, item }
    }
    new Vue({
      render: h => h(App),
    }).$mount('#app')
  </script>

三. 缓存组件的生命周期

如果动态组件缓存了.如何知道动态组件发生了切换?
如何知道当前显示的是哪个组件?
activated和deactivated是被缓存的动态组件特有的生命周期钩子函数.
不被缓存的组件是没有这两个钩子函数.

  <script>
    const box = {
      template: `
        <li>
          <input type='text' v-model='msg' />
          <span>{{msg}}</span>
        </li>
      `,
      data() {
        return { msg: '' }
      },
      // 激活了
      activated() {
        console.log('box显示了')
      },
      // 失活了
      deactivated() {
        console.log('box隐藏了')
      }
    }
    const item = {
      template: `
        <li>
          <input type='text' />
        </li>
      `,
      created() {
        console.log('item创建')
      },
      destroyed() {
        console.log('item销毁')
      }
    }
    const App = {
      template: `
        <div>
          <h3>App组件</h3>
          <button @click='fn'>按钮</button>
          <ul>
            <keep-alive>
              <li :is='cn'></li>
            </keep-alive>
          </ul>
        </div>
      `,
      data() {
        return { cn: 'box'}
      },
      methods: {
        fn() {
          // this.cn = 'item';
          if (this.cn === 'box') {
            this.cn = 'item';
          } else {
            this.cn = 'box';
          }
        }
      },
      components: { box, item }
    }
    new Vue({
      render: h => h(App),
    }).$mount('#app')
  </script>
posted @ 2021-10-07 19:26  暗鸦08  阅读(40)  评论(0)    收藏  举报