Vue案例---商品列表

App.vue

<template>
  <div class="table-case">
   <MyTable :data='goods'>
    <template #head>
       <th>编号</th>
          <th>名称</th>
          <th>图片</th>
          <th width="100px">标签</th>
    </template>
    <template #body='{item,index}'>
      <td>{{index + 1}}</td>
          <td>{{item.name}}</td>
          <td>
            <img :src="item.picture" />
          </td>
          <td>
            <!-- 标签组件 -->
            <MyTag v-model="item.tag"></MyTag>
          </td>
    </template>
   </MyTable>
  </div>
</template>

<script>
// my-tag 标签组件的封装
// 1.创建组件 - 初始化
// 2.实现功能
//  (1) 双击显示输入框,并且自动聚焦
//  (2) 失去焦点,隐藏输入框
//  (3) 双击要回显
//  (4) 内容修改了,回车=> 更改内容


// my-table 表格组件封装
// 1. 数据不能写死,动态传递表格渲染的数据 props
// 2.结构不能写死 - 多处结构自定义【具名插槽】
// (1) 表头支持自定义
// (2) 主体支持自定义
import MyTag from './components/MyTag.vue'
import MyTable from './components/MyTable.vue'
export default {
  name: 'TableCase',
  components: {
    MyTag,
    MyTable
  },
  data() {
    return {
      goods: [
        {
          id: 101,
          picture:
            'https://yanxuan-item.nosdn.127.net/f8c37ffa41ab1eb84bff499e1f6acfc7.jpg',
          name: '梨皮朱泥三绝清代小品壶经典款紫砂壶',
          tag: '茶具',
        },
        {
          id: 102,
          picture:
            'https://yanxuan-item.nosdn.127.net/221317c85274a188174352474b859d7b.jpg',
          name: '全防水HABU旋钮牛皮户外徒步鞋山宁泰抗菌',
          tag: '男鞋',
        },
        {
          id: 103,
          picture:
            'https://yanxuan-item.nosdn.127.net/cd4b840751ef4f7505c85004f0bebcb5.png',
          name: '毛茸茸小熊出没,儿童羊羔绒背心73-90cm',
          tag: '儿童服饰',
        },
        {
          id: 104,
          picture:
            'https://yanxuan-item.nosdn.127.net/56eb25a38d7a630e76a608a9360eec6b.jpg',
          name: '基础百搭,儿童套头针织毛衣1-9岁',
          tag: '儿童服饰',
        },
      ],
    }
  },
}
</script>

<style lang="less" scoped>
.table-case {
  width: 1000px;
  margin: 50px auto;
  img {
    width: 100px;
    height: 100px;
    object-fit: contain;
    vertical-align: middle;
  }

  
  
}
</style>

MyTable.vue

(1) 动态传递表格数据渲染

(2) 表头支持用户自定义

(3) 主体支持用户自定义

<template>
   <table class="my-table">
      <thead>
        <tr>
         <slot name='head'></slot>
        </tr>
      </thead>
      <tbody>
        <tr v-for="(item,index) in data" :key="item.id">
          <slot name='body' :item='item' :index='index'></slot>
        </tr>
      </tbody>
    </table>
</template>

<script>
export default {
    props:{
        data: {
            type:Array,
            required:true
        }
    }
}
</script>

<style lang='less' scoped>
.my-table {
    width: 100%;
    border-spacing: 0;
    img {
      width: 100px;
      height: 100px;
      object-fit: contain;
      vertical-align: middle;
    }
    th {
      background: #f5f5f5;
      border-bottom: 2px solid #069;
    }
    td {
      border-bottom: 1px dashed #ccc;
    }
    td,
    th {
      text-align: center;
      padding: 10px;
      transition: all 0.5s;
      &.red {
        color: red;
      }
    }
    .none {
      height: 100px;
      line-height: 100px;
      color: #999;
    }
  }
</style>

MyTag.vue

(1) 双击显示输入框,输入框获取焦点

(2) 失去焦点,隐藏输入框

(3) 回显标签信息

(4) 内容修改,回车 → 修改标签信息

<template>
  <div class="my-tag">
              <input 
                v-if='isEdit'
                v-focus
                class="input"
                type="text"
                placeholder="输入标签"
                :value="value"
                @blur="isEdit=false"
                @keyup.enter="handleEnter"
              />
              <div @dblclick="handleClick" class="text" v-else>
                {{value}}
              </div>
            </div>
</template>

<script>
export default {
    props: {
        value: String
    },
    data() {
        return {
            isEdit: false
        }
    },
    methods: {
        handleClick() {
            this.isEdit = true 
        },
        handleEnter(e) {
          if(e.target.value.trim() ===''){
            return alert('标签内容不能为空')
          }
          this.$emit('input',e.target.value)
          this.isEdit = false
            
        }
    }
}
</script>

<style lang='less' scoped>
.my-tag {
    cursor: pointer;
    .input {
      appearance: none;
      outline: none;
      border: 1px solid #ccc;
      width: 100px;
      height: 40px;
      box-sizing: border-box;
      padding: 10px;
      color: #666;
      &::placeholder {
        color: #666;
      }
    }
  }
</style>

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值