项目需求:将如下图标签一栏点击效果处理
效果解释:
- 双击显示输入框,输入框获取焦点
- 失去焦点,隐藏输入框
- 第2步之后显示标签信息
- 内容修改,回车,实现修改标签信息
效果实现:
1.页面整体架构:
此页面为基本的表格页面,包括头部,和元素主要内容呈现,主要实现的功能是在标签一栏内容实现修改。
2.组件元素:
表格整体组件MyTable.vue,包括头部,和元素主要内容呈现。
标签一栏功能组件MyTag.vue,主要是input标签效果实现。
3.根组件App.vue引用组件MyTable.vue,MyTag.vue,main.js文件实现封装获取焦点指令。
代码演示:
App.vue
<template>
<div class="table-case" id="app">
<Mytable :list="goods">
<template #head>
<th>编号</th>
<th>名称</th>
<th>图片</th>
<th width="100px">标签</th>
</template>
<!-- {item,index}也可写为{obj},
#tbody="{item,index}",直接使用引用组件中数组元素和下标 -->
<template #tbody="{item,index}">
<!-- 在MyTable组件中使用具名插槽,
调用插槽使用,还原内部标签写法,td -->
<td>{{ index + 1 }}</td>
<td>{{ item.name }}</td>
<td>
<img :src="item.picture" />
</td>
<td>
<!-- 此处进行了组件封装,好处:多次复用 -->
<Mytag v-model="item.tag"></Mytag>
<!-- <Mytag v-model="item.tag"></Mytag>
<Mytag v-model="item.tag"></Mytag>
<Mytag v-model="item.tag"></Mytag> -->
</td>
</template>
</Mytable>
</div>
</template>
<script>
// 导入组件
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;
}
.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>
main.js
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
// 自定义封装全局指令focus
//全局指令设置directive
Vue.directive('focus', {
// 指令所在的dom元素,被插入到页面中时被触发
inserted(el) {
el.focus();
}
})
new Vue({
render: h => h(App),
}).$mount('#app')
MyTable.vue
<template>
<!-- table表格标签 -->
<table class="my-table">
<thead>
<tr>
<!-- 表格头部标签使用具名插槽,使用name属性进行区分 -->
<slot name="head"></slot>
</tr>
</thead>
<tbody>
<!-- tbody标签,遍历数组,使用具名插槽,使用name属性进行区分 -->
<tr v-for="(item,index) in list" :key="item.id">
<slot name="tbody" :item="item" :index="index"></slot>
</tr>
</tbody>
</table>
</template>
<script>
export default {
// 接收根组件App.vue传值,此处写法是props校验规范,确认传过来的值是一个数组
props:{
list:Array
}
}
</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
<template>
<!-- table表格标签 -->
<table class="my-table">
<thead>
<tr>
<!-- 表格头部标签使用具名插槽,使用name属性进行区分 -->
<slot name="head"></slot>
</tr>
</thead>
<tbody>
<!-- tbody标签,遍历数组,使用具名插槽,使用name属性进行区分 -->
<tr v-for="(item,index) in list" :key="item.id">
<slot name="tbody" :item="item" :index="index"></slot>
</tr>
</tbody>
</table>
</template>
<script>
export default {
// 接收根组件App.vue传值,此处写法是props校验规范,确认传过来的值是一个数组
props:{
list:Array
}
}
</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>
暂且分享到这,有问题欢迎一起讨论!共同进步。