美文网首页
vue模拟el-table演示插槽用法

vue模拟el-table演示插槽用法

作者: 85年的大喇叭 | 来源:发表于2023-05-29 11:22 被阅读0次

    vue模拟el-table演示插槽用法

    转载自:www.javaman.cn

    很多人知道插槽分为三种,但是实际到elementui当中为什么这么用,就一脸懵逼,接下来就跟大家聊一聊插槽在elementui中的应用,并且自己写一个类似el-table的组件

    vue的slot分为三种::匿名插槽,具名插槽, 作用域插槽,主要作用:让父组件可以向子组件指定位置插入 html 结构,也是一种组件间通信的方式,适用于父组件=>子组件

    1、匿名插槽

    匿名组件相当于一个占位符,将父组件的数据传入子组件的slot标签内

    父组件:

    <template>
      <ChildSlot>父组件调用</ChildSlot>
    </template>
    
    <script>
    import ChildSlot from "@/components/ChildSlot";
    export default {
      components:{
        ChildSlot
      }
    }
    </script>
    

    子组件:

    <template>
      <h1>我是子组件</h1>
      <slot></slot>
    </template>
    
    <script>
    export default {
      name: "ChildSlot"
    }
    </script>
    

    运行结果如下:

    此时父组件中的“父组件调用”这段内容就传递到了子组件,并填入了slot挖的坑当中


    image-20230530092857777.png

    2、具名插槽

    具名插槽相当于给插槽添加了一个名字(给插槽加入name属性就是具名插槽)

    父组件:

    <template>
        <child-slot>
          <template v-slot:username>我是父组件传递的用户姓名</template>
        </child-slot>
        <child-slot>
          <template v-slot:age>我是父组件传递的年龄</template>
        </child-slot>
    </template>
    
    <script>
    import ChildSlot from "@/components/ChildSlot";
    export default {
      components:{
        ChildSlot
      }
    }
    </script>
    

    子组件:

    <template>
      <h1>我是子组件</h1>
      <slot name="username"></slot>
      <slot name="age"></slot>
    </template>
    
    <script>
    export default {
      name: "ChildSlot"
    }
    </script>
    

    运行结果如下:

    此时父组件中的根据slot的name,将内容填入了slot挖的坑当中,一个萝卜一个坑

    image-20230530094754458.png

    3、作用域插槽

    与前两者的不同 slot自定义:name="值" 子组件可向父组件传递信息

    父组件:

    <template>
        <child-slot>
          <template v-slot="{username}">我是子组件传递的用户姓名:{{username}}</template>
        </child-slot>
    </template>
    
    <script>
    import ChildSlot from "@/components/ChildSlot";
    export default {
      components:{
        ChildSlot
      }
    }
    </script>
    

    子组件:

    <template>
      <h1>我是子组件</h1>
      <slot :username="username"></slot>
    </template>
    
    <script>
    export default {
      name: "ChildSlot",
      data(){
        return{
            username:'java',
        }
      }
    }
    </script>
    

    运行结果如下:

    通过作用域插槽,我们可以将子组件中的值传入到父组件,在父组件进行数据处理后,填坑到子组件

    image-20230530101223625.png

    4、模拟写一个el-table

    先看一个el-table的例子,当需要对一行中的某一个单元格的内容进行处理的时候,需要用到slot插槽,例如下面的姓名name的处理

    <template>
      <el-table
          :data="tableData"
          style="width: 100%">
        <el-table-column
            label="姓名"
            width="180">
            <template slot-scope="scope">
              <el-popover trigger="hover" placement="top">
                <p>姓名: {{ scope.row.name }}</p>
                <p>住址: {{ scope.row.address }}</p>
                <div slot="reference" class="name-wrapper">
                  <el-tag size="medium">{{ scope.row.name }}</el-tag>
                </div>
              </el-popover>
            </template>
        </el-table-column>
        <el-table-column
            prop="address"
            label="地址">
        </el-table-column>
      </el-table>
    </template>
    

    参照el-table,实现我们自己的table组件,讲解下为什么需要用插槽,用了哪些插槽

    4.1为了传递table,首先通过匿名插槽,写一个<My-table>的组件,目的就是模拟下面这三行内容
      <el-table
      :data="tableData"
      style="width: 100%">
    
    <template>
      <div>
          <slot></slot>
      </div>
    </template>
    
    <script>
    export default {
      name: "MyTable"
    }
    </script>
    
    4.2实现el-table-column,通过作用域插槽,写我们自己的el-table-column
    <template>
      <div>
        <div>
          <!--通过传递label标签,展示表头-->
          <span v-if="label">{{ label }}</span>
        </div>
        <!--获取主页面的data值:$parent.$parent.$data.tableList-->
        <div v-for="(user,index) in $parent.$parent.$data.tableList" :key="index">
          <!--当传递prop属性的时候,就取user用户的数据-->
          <div v-if="prop">{{user[prop]}}</div>
          <!--当不传递prop属性的时候,将用户的数据通过row属性,传递到父组件当中,也就是app.vue-->
          <slot v-else :row="user"></slot>
        </div>
      </div>
    </template>
    
    <script>
    export default {
      name: "MyTableColumn",
      props: {
        prop: {type: String},
        label: {type: String}
      }
    }
    </script>
    
    
    4.2调用my-table,my-table-column

    我们通过my-table标签,将内容my-table和my-table-column放置到my-table的匿名插槽中,并通过子组件的props属性,接收prop和label。如同elementui一样,如果prop为空,子附件将父组件的user通过作用域插槽传递到父组件,并在父组件进行处理

    <template>
      <div>
        <my-table :data="tableList" style="display: flex; flex-direction: row;">
          <my-table-column prop="name" label="姓名"></my-table-column>
          <my-table-column prop="sex" label="性别"></my-table-column>
          <my-table-column label="地址">
            <template v-slot="scope">
              <span style="background-color: deepskyblue">{{scope.row.address}}</span>
            </template>
          </my-table-column>
        </my-table>
      </div>
    </template>
    
    <script>
    import MyTable from "@/components/MyTable";
    import MyTableColumn from "@/components/MyTableColumn";
    export default {
      name: 'App',
      components:{
        MyTableColumn,
        MyTable
      },
      data(){
        return{
          tableList:[
            {
              name: 'java大师1',
              sex: '男',
              address: '西藏1'
            },
            {
              name: 'java大师2',
              sex: '男',
              address: '西藏2'
            },
            {
              name: 'java大师3',
              sex: '男',
              address: '西藏3'
            },
            {
              name: 'java大师4',
              sex: '男',
              address: '西藏4'
            }
          ]
        }
      }
    }
    </script>
    

    展示结果如下:

    image-20230530105008626.png

    相关文章

      网友评论

          本文标题:vue模拟el-table演示插槽用法

          本文链接:https://www.haomeiwen.com/subject/ldujedtx.html