• Vue.js插槽slot和作用域插槽slot-scope学习小结


    一般来说,在Vue项目中使用父子组建时,都是把通用的HTML结构提取出来写成一个子组件,需要动态展示的数据用过prop属性传递,不过有时候我们可能想给子组件传递一个HTML代码,这个时候用prop不太适用,Vue给我们提供了slot(插槽)可以实现这种应用场景.下面是自己学习后总结的几种插槽使用方式
    1. 普通使用方式
    子组件
    <template>
      <div>
        <!-- 如果有多个插槽,可以通过name命名 -->
        <div style="background-color: yellowgreen">
          <slot name="header"></slot>
        </div>
        <!-- 父组件传递过来的值会展示在slot标签中 --> 
        <slot></slot>
        <ul v-if="todo">
          <li>姓名: {{todo.name}}</li>
          <li>年龄: {{todo.age}}</li>
          <li>爱好: {{todo.hobby}}</li>
        </ul>
        <div style="color: gold">
          <slot name="footer"></slot>
        </div>
      </div>
    </template>
    
    <script>
    export default {
      name: 'child',
      props: {
        todo: Object
      },
    
      data () {
        return {
        }
      },
    
      created () {
        console.log(this.todo, 'todo')
      }
    }
    
    </script>
    
    // 父组件
    <template>
      <div>
      <!-- 引入子组件 -->
        <child :todo="list">
          <!-- 这里的内容会渲染到子组件name为header的标签中 -->
          <template slot="header">
            <p>放在头部的内容</p>
          </template>
          <!-- 子组件双标签中的内容会被渲染到子组件的slot标签里 -->
          <h3>插槽标题</h3>
          <!-- 这里的内容会渲染到子组件name为footer的标签中 -->
          <template slot="footer">
            <p>放在底部的内容</p>
          </template>
        </child>
      </div>
    </template>
    
    <script>
    import child from './child'
    export default {
      name: 'parent',
      components: {child},
    
      data () {
        return {
          list: {
            name: '灵梦', 
            age: 18, 
            text: '热爱学习', 
            hobby: '踢足球'
          }
        }
      }
    
    }
    </script>  

    渲染效果:

    2. 作用域插槽
    如果你希望从子组件获取数据,进行其他数据展示,这个时候你可以使用作用域插槽
    子组件
    <template>
      <div>
        <ul v-if="todo.length" v-for="item in todo" :key="item.id">
          <li>姓名: {{item.name}}</li>
          <li>年龄: {{item.age}}</li>
          <li>爱好: {{item.hobby}}</li>
        </ul>
      </div>
    </template>
    <script>
    export default {
      name: 'child',
      props: {
        todo: Array
      }
    
    </script>
    
    // 父组件
    <template>
      <div>
      <!-- 引入子组件 -->
        <child :todo="list">
        </child>
      </div>
    </template>
    
    <script>
    import child from './child'
    export default {
      name: 'parent',
      components: {child},
    
      data () {
        return {
          list: [
            {name: '灵梦', age: 18, text: '热爱学习', hobby: '踢足球', id: 1},
            {name: '李明', age: 13, text: '画画很棒', hobby: '画画', id: 2},
            {name: '韩梅梅', age: 25, text: '性格文静', hobby: '做手工', id: 3}
          ]
        }
      }
    
    }
    </script> 
    普通调用,渲染出来的数据就是这样,但是如果我们想在第二项渲染中把hobby改成text,这时候就需要子组件把数据传过来,父组件改变渲染方式了
     
    // 子组件
    <template>
      <div>
        <ul v-if="todo.length" v-for="(item,index) in todo" :key="item.id">
          <li>姓名: {{item.name}}</li>
          <li>年龄: {{item.age}}</li>
          <!-- 如果是第二项,就使用作用域插槽,重新展示 -->
          <li v-if="index === 1">
            <!-- 定义了content把item传递到父组件,定义的名字可以随意取,需要传递的数据写在后面 -->
            <slot :content="item"></slot>
          </li>
          <li v-else>爱好: {{item.hobby}}</li>
        </ul>
      </div>
    </template>
    <script>
    export default {
      name: 'child',
      props: {
        todo: Array
      }
    
    </script>
    
    // 父组件
    <template>
      <div>
      <!-- 引入子组件 -->
        <child :todo="list">
          <!-- 在子组件用slot-scope结收传递过来的数据,接收的名字可以随意取 -->
          <template slot-scope="scope">
          <!-- scope后接的就是你在子组件定义的传递值的名称,scope.content就拿到了传递过来的值,在这里可以直接使用 -->
              描述: {{scope.content.text}}
          </template>
        </child>
      </div>
    </template>
    
    <script>
    import child from './child'
    export default {
      name: 'parent',
      components: {child},
    
      data () {
        return {
          list: [
            {name: '灵梦', age: 18, text: '热爱学习', hobby: '踢足球', id: 1},
            {name: '李明', age: 13, text: '画画很棒', hobby: '画画', id: 2},
            {name: '韩梅梅', age: 25, text: '性格文静', hobby: '做手工', id: 3}
          ]
        }
      }
    
    }
    </script>
    渲染出来的效果是这样,第二项李明的展示内容就改变了
     
    在很多Vue的插件中也有使用作用域插槽的,比如element-ui的table组件,它就可以通过添加作用域插槽改变渲染的原始数据
  • 相关阅读:
    第八周上机作业
    第七周课后作业
    第七周上机作业
    第六周课后作业
    第六周上机
    第九周JAVA
    第八周JAVA
    第8次JAVA作业
    第七周JAVA
    第7周JAVA
  • 原文地址:https://www.cnblogs.com/steamed-twisted-roll/p/10001512.html
Copyright © 2020-2023  润新知