vue 组件封装 综合案例
**创建 工程:
H:\java_work\java_springboot\vue_study
ctrl按住不放 右键 悬着 powershell
H:\java_work\java_springboot\js_study\Vue2_3入门到实战-配套资料\01-随堂代码素材\day05\准备代码\11-综合案例-商品列表
vue --version
vue create v-fengzhuang-example-demo
cd v-fengzhuang-example-demo
npm install --save-dev less-loader less
npm run serve
main.js
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
//封装全局指令 focus
Vue.directive('focus', {
// 指令所在的dom元素,被插入到页面中时触发
inserted(el) {
el.focus();
}
})
new Vue({
render: h => h(App),
}).$mount('#app')
App.vue
<template>
<div class="table-case">
<table class="my-table">
<thead>
<tr>
<th>编号</th>
<th>名称</th>
<th>图片</th>
<th width="100px">标签</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>梨皮朱泥三绝清代小品壶经典款紫砂壶</td>
<td>
<img
src="https://yanxuan-item.nosdn.127.net/f8c37ffa41ab1eb84bff499e1f6acfc7.jpg"
/>
</td>
<td>
<!-- 标签组件 -->
<MyTag v-model="tempText"></MyTag>
</td>
</tr>
<tr>
<td>1</td>
<td>梨皮朱泥三绝清代小品壶经典款紫砂壶</td>
<td>
<img
src="https://yanxuan-item.nosdn.127.net/221317c85274a188174352474b859d7b.jpg"
/>
</td>
<td>
<!-- 标签组件 -->
<MyTag v-model="tempText2"></MyTag>
</td>
</tr>
</tbody>
</table>
</div>
</template>
<script>
import MyTag from "./components/MyTag.vue";
export default {
name: "TableCase",
components: { MyTag },
data() {
return {
tempText: "水杯",
tempText2: "篮球",
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>
MyTag.vue
<template>
<div class="my-tag">
<input
v-if="isEdit"
class="input"
type="text"
placeholder="输入标签"
ref="inp"
v-focus
@blur="isEdit = false"
:value="value"
@keyup.enter="handleEnter"
/>
<div v-else @dblclick="handleClick" class="text">{{ value }}</div>
</div>
</template>
<script>
export default {
data() {
return {
isEdit: false,
};
},
props: {
value: String,
},
methods: {
handleClick() {
this.isEdit = true;
// this.$nextTick(() => {
// this.$refs.inp.focus();
// });
},
handleEnter(e) {
if (e.target.value.trim() === "") return alert("标签内容不能为空");
console.log("回车了");
console.log(e.target.value);
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>
修改后:
:src是 v-bind:src的简写方式获取data数据函数中的值