Vue学习:20.综合案例-商品列表

学而时用之,方能融会贯通!

实例:商品列表

实现功能

要求表格组件支持动态数据渲染、自定义表头和主体。标签组件需要双击显示输入框并获得焦点,可以编辑标签信息。

思路

首先是表格组件,动态渲染需要使用组件通信-“父传子”;允许自定义可以使用具名插槽;而对于标签组件,可以使用v-if/else和自定义指令v-focus来实现双击显示输入框并自动聚焦,可以使用v-model实现回显标签信息,最后使用“子传父”修改标签信息。

代码

根组件(APP.vue)

<template>
    <MyTable :list="list">
      <template #head>
        <th>编号</th>
        <th>图片</th>
        <th>名称</th>
        <th>标签</th>
      </template>
      <!-- 插槽作用域 -->
      <template #body="{ item, index}">
        <td style="width: 100px;">{{ index+1 }}</td>
        <td style="width: 200px;">
          <img :src="item.photo">          
        </td>
        <td style="width: 300px;">{{ item.name }}</td>
        <td>
            <MyTage v-model="item.tage"></MyTage>
        </td> 
      </template>
    </MyTable>
</template>
<script>
import MyTage from './components/MyTage.vue'
import MyTable from './components/MyTable.vue';

export default {
  data(){
    return{
      list:[
        {id:101, photo:'https://img.zcool.cn/community/01811f5abc92fda801218207a45ce8.JPG@1280w_1l_2o_100sh.jpg', name:'缴费部分', tage: '红酒'},
        {id:102, photo:'https://img.zcool.cn/community/01811f5abc92fda801218207a45ce8.JPG@1280w_1l_2o_100sh.jpg', name:'缴费部分', tage: '红酒'},
        {id:103, photo:'https://img.zcool.cn/community/01811f5abc92fda801218207a45ce8.JPG@1280w_1l_2o_100sh.jpg', name:'缴费部分', tage: '红酒'}
      ]
    }
  },
  components:{
    MyTage,
    MyTable
  }
}
</script>

<style>

</style>

MyTable组件

<template>
  <div>
    <table>
        <thead>
            <tr>
                <slot name="head"></slot>
            </tr>
        </thead>

        <tbody>
            <tr v-for="(item, index) in  list" :key="item.id">
                <!-- 插槽作用域-以加属性名的方式传参 -->
                <slot name="body" :item="item" :index="index"></slot>
            </tr>
        </tbody>
    </table>
  </div>
</template>

<script>
export default {
    props:{
        list:Array
    },
}
</script>

<style scoped>
    table{
        margin: 20px auto;
        border-collapse: collapse;
        text-align: center;
    }
    th,td{
        width: 100px;
        height: 50px;
        line-height: 50px;
        border: 2px solid rgb(163, 161, 161);
    }
    th{
        background-color: blue;
        color: #fff;
    }
    img{
        width: 100px;
        height: 100px;
    }
</style>

MyTag组件

<template>
    <div>
        <input
         v-if="isEdit"
         v-focus
         :value="value"
         @blur="isEdit = false"
         @keyup.enter="handleEnter"
         placeholder="请输入标签">
         <!-- 定义双击事件 -->
        <p v-else @dblclick="handleEdit">{{value}}</p>
    </div>
</template>

<script>
export default {
    data(){
        return{
            isEdit: false
        }
    },
    methods:{
        handleEdit(){
            this.isEdit = true
        },
        handleEnter(e){
            this.$emit('input',e.target.value)
            this.isEdit = false
        }
    },
    props:{
        value:String
    }
}
</script>

<style>
    input,p{
        width: 100px;
    }
</style>

注意:这个实例中数据来回传递,咋一看好像有点晕,但是当你真正理解了,才会惊叹“牛逼!” 

效果图

  • 22
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值