插槽、动态组件和 v-once 指令

2018/12/10 Vue

一、作用域插槽使用场景

  • 当子组件需要做循环的时候
  • 某一部分 DOM 结构需要由外部传进来的时候

使用作用域插槽,子组件可以向父组件传的插槽里传递数据,父组件 传递过来的插槽如果想要接收这个数据,必须在外层使用 template,同时 需要 ` slot-scope` 对应的属性名字来接收 子组件传递过来的额数据

// 子组件向组件传递 item,父组件在作用域插槽里面接收 item,然后使用
<body>
  <div id="root">
    <body-content>
      <template slot-scope="props">
        <h1> -- hello</h1>
      </template>
    </body-content>
  </div>

  <script>
    Vue.component('body-content', {
      data: function() {
        return {
          list: [1, 2, 3, 4, 5]
        }
      },
      template: `<div>
                    <ul>
                      <slot
                        v-for="item of list"
                        :item="item"
                      >
                      </slot>
                    </ul>
                  </div>
                  `
    })

    var vm = new Vue({
      el: '#root'
    })
  </script>
</body>

二、动态组件和 v-once 指令

1. 通过 v-show 实现组件切换

<body>
  <div id="root">
    <child-one v-show="type === 'child-one'"></child-one>
    <child-two v-show="type === 'child-two'"></child-two>
    <button @click="handleBtnClick">change</button>
  </div>

  <script>
    Vue.component('child-one', {
      template: `<div>child-one</div>`
    })

    Vue.component('child-two', {
      template: `<div>child-two</div>`
    })

    var vm = new Vue({
      el: '#root',
      data: {
        type: 'child-one'
      },
      methods: {
        handleBtnClick: function() {
          this.type = this.type === 'child-one' ? 'child-two' : 'child-one';
        }
      }
    })
  </script>
</body>

2. 通过 动态组件 实现组件切换

<div id="root">
  <!-- 动态组件,会根据 is 中数据的变化,自动的加载不同的组件 -->
  <component :is="type"></component>
  <button @click="handleBtnClick">change</button>
</div>

<script>
  Vue.component('child-one', {
    template: `<div>child-one</div>`
  })

  Vue.component('child-two', {
    template: `<div>child-two</div>`
  })

  var vm = new Vue({
    el: '#root',
    data: {
      type: 'child-one'
    },
    methods: {
      handleBtnClick: function() {
        this.type = this.type === 'child-one' ? 'child-two' : 'child-one'
      }
    }
  })
</script>

3. v-once 指令的使用

我们在页面上切换组件的时候,Vue 的底层会判断当前的组件不用了,取而代之会用另外一个组件 ,然后它会把第一个组件销毁掉,再创建第二个组件。

假设第二个组件又要隐藏,第一个组件又显示的话,这个时候又要把第二个组件销毁掉,再重新创建第一个组件。

也就是说,没进行一次组件的切换,Vue 底层都需要销毁一个组件再创建一个组件。 这种操作是耗费一定的性能的。

如果我们的组件每次都一样,我们可以使用 v-once 指令,这样,当第一个组件被渲染的时候,因为组件上有 v-once 指令,所以会直接放到内存中。当我们切换到第二个组件的时候,第二个组件也被放到内存里了。

再切换会第一个组件的时候,直接从内存中拿出以前的组件就可以了。

<div id="root">
  <child-one v-show="type === 'child-one'"></child-one>
  <child-two v-show="type === 'child-two'"></child-two>
  <button @click="handleBtnClick">change</button>
</div>

<script>
  Vue.component('child-one', {
    template: `<div v-once>child-one</div>`
  })

  Vue.component('child-two', {
    template: `<div v-once>child-two</div>`
  })

  var vm = new Vue({
    el: '#root',
    data: {
      type: 'child-one'
    },
    methods: {
      handleBtnClick: function() {
        this.type = this.type === 'child-one' ? 'child-two' : 'child-one'
      }
    }
  })
</script>

v-once 指令

在第一次 DOM 时进行渲染,渲染完成后视为静态内容,跳出以后的渲染过程。

<div v-once>第一次绑定的值:</div>
<div><input type="text" v-model="message"></div>

Search

    Table of Contents