Day03-vue基础
一 列表渲染
v-for这个指令可以实现列表渲染
1 数组
<ul>
<!--
v-for遍历的时候,key必须赋唯一值
第一个参数是数组元素,第二个参数是元素下标
-->
<li v-for="(item,index) in [1,3,5,7]" :key="item">{{item}}--{{index}}</li>
</ul>
2 数字
<ul>
<li v-for="item in 10" :key="item">{{item}}</li>
</ul>
3 对象
data(){
return{
arr:[
{id:1,name:"赵日天"},
{id:2,name:"李杀神"},
{id:3,name:"王诛魔"},
{id:4,name:"刘斩仙"},
]
}
},
<ul>
<li v-for="item in arr" :key="item.id">{{item.name}}</li>
</ul>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-y9A5hvrk-1692931215463)(https://woniumd.oss-cn-hangzhou.aliyuncs.com/web/chenyun20230705101257.png)]
特点:
key值必须是唯一的。推荐大家用数组中唯一值id来作为key
index不推荐拿来作为key,数据一旦变化了,index变化
Vue底层循环节点,每个节点都有唯一key,下次数据发生变化,通过key来进行对比,发生key是没有产生变化,对比忽略指定节点。提升效率
二 图片渲染
针对要显示图片,分为本地图片和网络图片:
-
网络图片无需任何处理,正常使用。
-
本地图片:
如果图片地址是非动态的,那么直接写上地址即可
<img width="70" src="../assets/images/5.jpg" alt="">
如果图片地址是动态的(比如item.imgSrc),那么就在<script>
获取图片数据处加上require(),表示获取该图片经过打包之后的路径
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EN1e4oOs-1692931215467)(https://woniumd.oss-cn-hangzhou.aliyuncs.com/web/chenyun20230705101134.png)]
三 列表渲染实战
<template>
<div class="container">
<div class="search">
<div>
<label for="">拼团状态:</label>
<select name="" id="">
<option value="all">全部</option>
<option value="open">开启</option>
<option value="close">关闭</option>
</select>
</div>
<div>
<label for="">商品搜索:</label>
<input ref="productName" type="text" />
</div>
<button>搜索</button>
<button>查询上架商品</button>
<button>查询下架商品</button>
<button>所有数据</button>
</div>
<table class="goods_list">
<thead>
<tr>
<th>编号</th>
<th>拼团图片</th>
<th>拼团名字</th>
<th>原价</th>
<th>拼团价格</th>
<th>拼团人数</th>
<th>参与人数</th>
<th>成团数量</th>
<th>限量</th>
<th>剩余数量</th>
<th>活动状态</th>
<th>结束时间</th>
<th>上/下架</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr v-for="item in goodList" :key="item.id">
<td>{{item.id}}</td>
<td>
<img :src="item.img" alt="">
</td>
<td>{{item.name}}</td>
<td>{{item.price}}</td>
<td>{{item.spellPrice}}</td>
<td>{{item.spellPeople}}</td>
<td>{{item.joinPeople}}</td>
<td>{{item.spellNumber}}</td>
<td>{{item.limit}}</td>
<td>{{item.residue}}</td>
<td>
<span>{{item.status?"进行中":"已结束"}}</span>
</td>
<td>{{item.endTime}}</td>
<td>
<button :class="item.show?'xiajia':'shangjia'">{{item.show?"下架":"上架"}}</button>
</td>
<td>
<button>删除</button>
<button>修改</button>
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="14">
<button><<</button>
<button>1</button>
<button>2</button>
<button>3</button>
<button>>></button>
当前第 <span>1</span> 页/共 <span>3</span> 页
</td>
</tr>
</tfoot>
</table>
</div>
</template>
<script>
export default {
data() {
return {
goodList: [
{
id: 1, //编号
img: require("../assets/images/5.jpg"), //图片
name: "香氛无火香薰精油卧室助眠除臭", //拼团商品名字
price: 59, //原价
spellPrice: 48, //拼团价格
spellPeople: 3, //拼团人数
joinPeople: 6, //参与人数
spellNumber: 2, //成团数量
limit: 25, //限制数量
residue: 20, //剩余数量
status: true,
endTime: "2022-12-23 00:00:00",
show: true,
},
{
id: 2, //编号
img: require("../assets/images/b.png"), //图片
name: "小米家保温杯云米电热杯", //拼团商品名字
price: 59, //原价
spellPrice: 48, //拼团价格
spellPeople: 3, //拼团人数
joinPeople: 6, //参与人数
spellNumber: 2, //成团数量
limit: 25, //限制数量
residue: 20, //剩余数量
status: false,
endTime: "2022-12-23 00:00:00",
show: false,
},
{
id: 3, //编号
img: require("../assets/images/b.png"), //图片
name: "小米家保温杯云米电热杯", //拼团商品名字
price: 59, //原价
spellPrice: 48, //拼团价格
spellPeople: 3, //拼团人数
joinPeople: 6, //参与人数
spellNumber: 2, //成团数量
limit: 25, //限制数量
residue: 20, //剩余数量
status: false,
endTime: "2022-12-23 00:00:00",
show: false,
},
{
id: 4, //编号
img: require("../assets/images/f.jpg"), //图片
name: "Casio卡西欧女表时尚", //拼团商品名字
price: 1200, //原价
spellPrice: 1000, //拼团价格
spellPeople: 3, //拼团人数
joinPeople: 6, //参与人数
spellNumber: 2, //成团数量
limit: 10, //限制数量
residue: 4, //剩余数量
status: false,
endTime: "2022-12-23 00:00:00",
show: false,
},
{
id: 5, //编号
img: require("../assets/images/7.jpg"), //图片
name: "爱奇艺智能 奇遇LT01 投影仪", //拼团商品名字
price: 59, //原价
spellPrice: 48, //拼团价格
spellPeople: 3, //拼团人数
joinPeople: 6, //参与人数
spellNumber: 2, //成团数量
limit: 25, //限制数量
residue: 20, //剩余数量
status: false,
endTime: "2022-12-23 00:00:00",
show: false,
},
{
id: 6, //编号
img: require("../assets/images/8.jpg"), //图片
name: "TOMFORD汤姆福特唇膏4色TF口红", //拼团商品名字
price: 59, //原价
spellPrice: 48, //拼团价格
spellPeople: 3, //拼团人数
joinPeople: 6, //参与人数
spellNumber: 2, //成团数量
limit: 25, //限制数量
residue: 20, //剩余数量
status: false,
endTime: "2022-12-23 00:00:00",
show: false,
},
{
id: 7, //编号
img: require("../assets/images/9.jpg"), //图片
name: "云麦体脂秤称重女智能精准成人脂肪测量仪", //拼团商品名字
price: 59, //原价
spellPrice: 48, //拼团价格
spellPeople: 3, //拼团人数
joinPeople: 6, //参与人数
spellNumber: 2, //成团数量
limit: 25, //限制数量
residue: 20, //剩余数量
status: false,
endTime: "2022-12-23 00:00:00",
show: false,
},
{
id: 8, //编号
img: require("../assets/images/10.jpg"), //图片
name: "本来设计挂钟原木时钟创意现代简约实木", //拼团商品名字
price: 59, //原价
spellPrice: 48, //拼团价格
spellPeople: 3, //拼团人数
joinPeople: 6, //参与人数
spellNumber: 2, //成团数量
limit: 25, //限制数量
residue: 20, //剩余数量
status: false,
endTime: "2022-12-23 00:00:00",
show: false,
},
],
};
},
};
</script>
<style lang="scss" scoped>
.container {
.search {
width: 100%;
margin-bottom: 30px;
label {
color: gray;
}
select {
width: 220px;
height: 30px;
box-sizing: border-box;
}
input {
width: 220px;
height: 30px;
box-sizing: border-box;
margin: 10px 0px;
}
button {
width: 100px;
height: 35px;
background-color: #cce8eb;
border: none;
outline: none;
color: white;
border-radius: 3px;
margin-right: 5px;
color: black;
&:active {
background-color: orange;
}
}
}
table {
border: 1px black solid;
border-collapse: collapse;
text-align: center;
background-color: white;
th {
border: 1px #e5ecf1 solid;
width: 100px;
background: #d5e6e9;
}
td {
border: 1px #e5ecf1 solid;
}
tbody {
tr {
td {
> img {
width: 60px;
height: 60px;
}
}
td:nth-child(2) {
padding: 6px;
}
td:nth-child(3) {
text-align: left;
}
td:nth-child(11) {
span {
width: 40px;
height: 14px;
background: #eefdfb;
border: 1px #caede9 solid;
}
}
td:nth-child(13) {
//下架按钮样式
.xiajia {
background: #568ce3;
color: white;
width: 50px;
height: 30px;
border: none;
}
//上架按钮样式
.shangjia {
background: white;
color: #568ce3;
width: 50px;
height: 30px;
border: 1px #568ce3 dotted;
}
}
td:nth-child(14) {
button {
background: #eeeeee;
width: 40px;
height: 20px;
border: 1px #a7a7a7 solid;
}
}
}
}
tfoot {
tr {
td {
text-align: right;
height: 80px;
padding-right: 40px;
button {
width: 30px;
height: 30px;
background: white;
color: #568ce3;
border: 1px #eeeeee solid;
}
}
}
}
}
}
</style>
四 事件委托
在Vue中如果需要优化事件,我们需要采用事件委托的方式来实现。那怎么获取事件传播对象呢?
场景一:绑定函数的时候,不传递出参数
<ul @click="del">
<li>梅菜扣肉</li>
<li>土豆丝</li>
<li>红烧肉</li>
</ul>
methods:{
del(event){
console.log(event.target);
}
}
这个时候event就是Vue默认传递过来事件传播对象。
场景二:绑定函数的时候,需要传递参数
<ul @click="del($event,1)">
<li>梅菜扣肉</li>
<li>土豆丝</li>
<li>红烧肉</li>
</ul>
methods:{
del(event,id){
console.log(event.target);
console.log(id);
}
}
在调用函数的时候,我们可以在参数里面使用$event来代表事件传播对象。
五 响应式变化特性
当我们修改的不是数组元素本身,而是数组中对象的属性,Vue能够检测到数据的变化
<ul>
<li v-for="item in arr" :key="item.id">{{item.name}}</li>
</ul>
<button @click="updateData">修改数据</button>
arr:[
{id:1,name:"赵日天"},
{id:2,name:"李杀神"},
{id:3,name:"王诛魔"},
{id:4,name:"刘斩仙"},
]
updateData(){
this.arr[0].name = "赵昊"
},
当我们操作数组的时候,如果直接通过下标修改数组元素,Vue检测不到数据变化。
<ul>
<li v-for="item in arr" :key="item.id">{{item.name}}</li>
</ul>
<button @click="updateTwo">再次修改数据</button>
arr:[
{id:1,name:"赵日天"},
{id:2,name:"李杀神"},
{id:3,name:"王诛魔"},
{id:4,name:"刘斩仙"},
]
updateTwo(){
console.log("---------");
this.arr[0] = {id:1,name:"赵敏"}
console.log(this.arr);
}
六 上下架
七 删除
八 计算属性
Vue专门提供了计算属性的功能,对数据进行筛选操作。
基本语法
语法:computed
特点:
- 在computed里面写的也是属性。
- computed里面函数必须要有返回值,依赖原数据得到一个新结果
- 计算属性,依赖于data,data一旦发生变化,计算属性立即重新执行,页面跟着更新
计算属性特性:
计算属性具有缓存功能,在一个页面中重复使用这个计算属性,Vue底层默认将结果缓存起来。多次使用调用一次,其他标签再次使用默认缓存中拿结果。
完整功能
<template>
<div>
{{firstName}} -- {{username}}
<button @click="updateName">修改</button>
<button @click="updateComputed">修改计算属性的值</button>
</div>
</template>
<script>
export default {
//data跟computed里面的属性名不能重复
data(){
return{
username:"赵日天",
}
},
/**
* 计算属性
* 作用:处理data中的数据,得到新的结果,赋值给新的属性名
* 特点:当data中的数据发生变化时,computed计算属性会重新执行
*/
computed:{
firstName:{
//get函数用来给属性赋值,必须要有返回值
get(){
console.log("-------------");
const u = this.username.split("")[0]
return u
},
//set用来接收修改计算属性的值
set(val){
console.log(val);
}
}
},
methods:{
updateName(){
this.username = "刘斩仙"
},
updateComputed(){
this.firstName = "李"
}
}
}
</script>
<style>
</style>
九 DOM操作
1 给标签添加ref属性
2 获取dom元素的值
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9KxXApXj-1692931215520)(https://woniumd.oss-cn-hangzhou.aliyuncs.com/web/chenyun20230705173633.png)]
十 计算属性实战
<template>
<div class="container">
<div class="search">
<div>
<label for="">拼团状态:</label>
<select ref="sel" >
<option value="all">全部</option>
<option value="open">开启</option>
<option value="close">关闭</option>
</select>
</div>
<div>
<label for="">商品搜索:</label>
<input ref="goodsName" type="text" />
</div>
<button @click="searchByStatusAndName">搜索</button>
<button @click="searchGoodsShow('up')">查询上架商品</button>
<button @click="searchGoodsShow('down')">查询下架商品</button>
<button @click="searchGoodsShow('all')">所有数据</button>
</div>
<table class="goods_list">
<thead>
<tr>
<th>编号</th>
<th>拼团图片</th>
<th>拼团名字</th>
<th>原价</th>
<th>拼团价格</th>
<th>拼团人数</th>
<th>参与人数</th>
<th>成团数量</th>
<th>限量</th>
<th>剩余数量</th>
<th>活动状态</th>
<th>结束时间</th>
<th>上/下架</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr v-for="item in goodList" :key="item.id">
<td>{{item.id}}</td>
<td>
<img :src="item.img" alt="">
</td>
<td>{{item.name}}</td>
<td>{{item.price}}</td>
<td>{{item.spellPrice}}</td>
<td>{{item.spellPeople}}</td>
<td>{{item.joinPeople}}</td>
<td>{{item.spellNumber}}</td>
<td>{{item.limit}}</td>
<td>{{item.residue}}</td>
<td>
<span>{{item.status?"进行中":"已结束"}}</span>
</td>
<td>{{item.endTime}}</td>
<td>
<button @click="changeShow(item.id)" :class="item.show?'xiajia':'shangjia'">{{item.show?"下架":"上架"}}</button>
</td>
<td>
<button @click="deleteById(item.id)">删除</button>
<button>修改</button>
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="14">
<button><<</button>
<button>1</button>
<button>2</button>
<button>3</button>
<button>>></button>
当前第 <span>1</span> 页/共 <span>3</span> 页
</td>
</tr>
</tfoot>
</table>
</div>
</template>
<script>
export default {
data() {
return {
showState:"all", //查询商品的上下架状态, all up down
searchStatus:"all", //查询拼团状态 all open close
searchName:"", //根据名称查询商品
tempList: [
{
id: 1, //编号
img: require("../assets/images/5.jpg"), //图片
name: "香氛无火香薰精油卧室助眠除臭", //拼团商品名字
price: 59, //原价
spellPrice: 48, //拼团价格
spellPeople: 3, //拼团人数
joinPeople: 6, //参与人数
spellNumber: 2, //成团数量
limit: 25, //限制数量
residue: 20, //剩余数量
status: true,
endTime: "2022-12-23 00:00:00",
show: true,//上下架
},
{
id: 2, //编号
img: require("../assets/images/b.png"), //图片
name: "小米家保温杯云米电热杯", //拼团商品名字
price: 59, //原价
spellPrice: 48, //拼团价格
spellPeople: 3, //拼团人数
joinPeople: 6, //参与人数
spellNumber: 2, //成团数量
limit: 25, //限制数量
residue: 20, //剩余数量
status: false,
endTime: "2022-12-23 00:00:00",
show: false,
},
{
id: 3, //编号
img: require("../assets/images/b.png"), //图片
name: "小米家保温杯云米电热杯", //拼团商品名字
price: 59, //原价
spellPrice: 48, //拼团价格
spellPeople: 3, //拼团人数
joinPeople: 6, //参与人数
spellNumber: 2, //成团数量
limit: 25, //限制数量
residue: 20, //剩余数量
status: false,
endTime: "2022-12-23 00:00:00",
show: false,
},
{
id: 4, //编号
img: require("../assets/images/f.jpg"), //图片
name: "Casio卡西欧女表时尚", //拼团商品名字
price: 1200, //原价
spellPrice: 1000, //拼团价格
spellPeople: 3, //拼团人数
joinPeople: 6, //参与人数
spellNumber: 2, //成团数量
limit: 10, //限制数量
residue: 4, //剩余数量
status: false,
endTime: "2022-12-23 00:00:00",
show: false,
},
{
id: 5, //编号
img: require("../assets/images/7.jpg"), //图片
name: "爱奇艺智能 奇遇LT01 投影仪", //拼团商品名字
price: 59, //原价
spellPrice: 48, //拼团价格
spellPeople: 3, //拼团人数
joinPeople: 6, //参与人数
spellNumber: 2, //成团数量
limit: 25, //限制数量
residue: 20, //剩余数量
status: false,
endTime: "2022-12-23 00:00:00",
show: false,
},
{
id: 6, //编号
img: require("../assets/images/8.jpg"), //图片
name: "TOMFORD汤姆福特唇膏4色TF口红", //拼团商品名字
price: 59, //原价
spellPrice: 48, //拼团价格
spellPeople: 3, //拼团人数
joinPeople: 6, //参与人数
spellNumber: 2, //成团数量
limit: 25, //限制数量
residue: 20, //剩余数量
status: false,
endTime: "2022-12-23 00:00:00",
show: false,
},
{
id: 7, //编号
img: require("../assets/images/9.jpg"), //图片
name: "云麦体脂秤称重女智能精准成人脂肪测量仪", //拼团商品名字
price: 59, //原价
spellPrice: 48, //拼团价格
spellPeople: 3, //拼团人数
joinPeople: 6, //参与人数
spellNumber: 2, //成团数量
limit: 25, //限制数量
residue: 20, //剩余数量
status: false,
endTime: "2022-12-23 00:00:00",
show: false,
},
{
id: 8, //编号
img: require("../assets/images/10.jpg"), //图片
name: "本来设计挂钟原木时钟创意现代简约实木", //拼团商品名字
price: 59, //原价
spellPrice: 48, //拼团价格
spellPeople: 3, //拼团人数
joinPeople: 6, //参与人数
spellNumber: 2, //成团数量
limit: 25, //限制数量
residue: 20, //剩余数量
status: false,
endTime: "2022-12-23 00:00:00",
show: false,
},
],
};
},
methods:{
changeShow(id){
//找到要上下架的商品
const goods = this.tempList.find(e =>e.id == id)
goods.show = !goods.show
},
deleteById(id){
//根据id找到商品在数组中的下标
const index = this.tempList.findIndex(e =>e.id == id)
//根据下标删除
this.tempList.splice(index,1)
},
searchGoodsShow(val){
this.showState = val
},
//根据商品的拼团状态和名称进行搜索
searchByStatusAndName(){
//获取到下拉列表的值
this.searchStatus = this.$refs.sel.value
//获取输入框的值
this.searchName = this.$refs.goodsName.value
}
},
computed:{
goodList:{
get(){
//查询上下架
let arr = this.tempList.filter(e =>{
if(this.showState == "all"){//筛选所有商品
return e
}else if(this.showState == "up"){//筛选上架商品
if(e.show == true){
return e
}
}else if(this.showState == "down"){//筛选下架商品
if(e.show == false){
return e
}
}
})
//查询拼团状态
arr = arr.filter(e =>{
if(this.searchStatus == "all"){ //筛选所有的拼团商品
return e
}else if(this.searchStatus == "open"){//筛选正在进行的拼团商品
if(e.status == true){
return e
}
}else if(this.searchStatus == "close"){ //查询已结束的拼团商品
if(e.status == false){
return e
}
}
})
//根据商品名称查询
arr = arr.filter(e =>e.name.includes(this.searchName))
return arr
},
set(val){
console.log(val);
}
}
}
};
</script>
<style lang="scss" scoped>
.container {
.search {
width: 100%;
margin-bottom: 30px;
label {
color: gray;
}
select {
width: 220px;
height: 30px;
box-sizing: border-box;
}
input {
width: 220px;
height: 30px;
box-sizing: border-box;
margin: 10px 0px;
}
button {
width: 100px;
height: 35px;
background-color: #cce8eb;
border: none;
outline: none;
color: white;
border-radius: 3px;
margin-right: 5px;
color: black;
&:active {
background-color: orange;
}
}
}
table {
border: 1px black solid;
border-collapse: collapse;
text-align: center;
background-color: white;
th {
border: 1px #e5ecf1 solid;
width: 100px;
background: #d5e6e9;
}
td {
border: 1px #e5ecf1 solid;
}
tbody {
tr {
td {
> img {
width: 60px;
height: 60px;
}
}
td:nth-child(2) {
padding: 6px;
}
td:nth-child(3) {
text-align: left;
}
td:nth-child(11) {
span {
width: 40px;
height: 14px;
background: #eefdfb;
border: 1px #caede9 solid;
}
}
td:nth-child(13) {
//下架按钮样式
.xiajia {
background: #568ce3;
color: white;
width: 50px;
height: 30px;
border: none;
}
//上架按钮样式
.shangjia {
background: white;
color: #568ce3;
width: 50px;
height: 30px;
border: 1px #568ce3 dotted;
}
}
td:nth-child(14) {
button {
background: #eeeeee;
width: 40px;
height: 20px;
border: 1px #a7a7a7 solid;
}
}
}
}
tfoot {
tr {
td {
text-align: right;
height: 80px;
padding-right: 40px;
button {
width: 30px;
height: 30px;
background: white;
color: #568ce3;
border: 1px #eeeeee solid;
}
}
}
}
}
}
</style>