Prérequis:
Exposition de cas:![Insérez la description de l'image ici](https://img-blog.csdnimg.cn/20200402234016992.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2hhZHV3aQ==,size_16,color_FFFFFF,t_70)
Affichage du code:
Partie HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<div class="container">
<my-cart></my-cart>
</div>
</div>
<script src="./js/vue.js"></script>
<script>
//插入自己写的js
</script>
</body>
partie css: (À l'avenir, écrivez des styles CSS pour écrire autant que possible des sélecteurs hiérarchiques, et ils ont une relation lourde)
<style>
.container {
width: 100%;
height: 100%;
}
.container .cart {
width: 300px;
margin: auto;
}
.container .title {
background-color: lightblue;
height: 40px;
line-height: 40px;
text-align: center;
}
.container .total {
background-color: #FFCE46;
height: 50px;
line-height: 50px;
text-align: right;
}
.container .total button {
margin: 0 10px;
background-color: #DC4c40;
height: 35px;
width: 80px;
border: 0;
}
.container .total span {
color: red;
font-weight: bold;
}
.container .item {
height: 55px;
line-height: 55px;
position: relative;
border-top: 1px solid #ADD8E6;
}
.container .item img {
width: 45px;
height: 45px;
margin: 5px;
}
.container .item .name {
position: absolute;
width: 90px;
top: 0px;
left: 55px;
font-size: 16px;
}
.container .item .change {
width: 100px;
position: absolute;
top: 0;
right: 50px
}
.container .item .change a {
font-size: 20px;
width: 30px;
text-decoration: none;
background-color: lightgray;
vertical-align: middle;
}
.container .item .change .num {
width: 40px;
height: 25px;
}
.container .item .del {
user-select: none;
/* 双击不选中 */
position: absolute;
top: 0px;
right: 0px;
width: 40px;
text-align: center;
font-size: 40px;
cursor: pointer;
color: red;
}
.container .item .del:hover {
background-color: orange;
}
</style>
partie js: (Analyse clé)
<script>
//局部定义的变量组件一定要放在 全局component前面!!!!
var CartTitle = {
props: ['uname'],
template: `
<div class="title">{{uname}}的购物车</div>
`
}
var CartList = {
props: ['lists'],
template: `
<div>
<div class="item" v-for="item in lists" :key="item.id">
<img :src="item.img"/>
<!-- 不能写成{{item.img}} 直接写item.img-->
<div class="name">{{item.name}}</div>
<div class="change">
<a href="" @click.prevent='sub(item.id)'> - </a>
<input name="" type="text" class="num" :value='item.num' @blur='changeNum(item.id,$event)'></input>
<a href="" @click.prevent='add(item.id)'>+ </a>
</div>
<div class="del" @click='del(item.id)'>×</div>
</div>
</div>
`,
methods: {
changeNum: function(id, event) {
this.$emit('change-num', {
id: id,
type: 'change',
num: event.target.value
})
},
//按+ -得到的数据也传递到changeNum
sub: function(id) {
this.$emit('change-num', {
id: id,
type: 'sub'
})
},
add: function(id) {
this.$emit('change-num', {
id: id,
type: 'add'
});
},
del: function(id) {
//把id传给父组件
this.$emit('cart-del', id);
}
},
}
//计算总价组件
var CartTotal = {
props: ['lists'],
template: `
<div class="total">
<span>总价:{{total}}</span>
<button>结算</button>
</div>
`,
computed: {
//利用计算属性来计算总价 要有return值
total: function() {
//计算商品总价
var sum = 0;
this.lists.forEach(item => {
//foeEach遍历出数据
sum += item.price * item.num;
//总价=单价x数量
})
return sum;
}
},
}
Vue.component('my-cart', {
data() {
return {
uname: 'XXW',
lists: [{
id: 1,
name: 'TCL彩电',
price: 1200,
num: 1,
img: 'img/a.jpg',
}, {
id: 2,
name: '机顶盒',
price: 800,
num: 1,
img: 'img/b.jpg',
}, {
id: 3,
name: '海尔冰箱',
price: 2200,
num: 1,
img: 'img/c.jpg',
}, {
id: 4,
name: '小米手机',
price: 1799,
num: 1,
img: 'img/d.jpg',
}, {
id: 5,
name: 'PPTV电视',
price: 1888,
num: 1,
img: 'img/e.jpg',
}, ]
}
},
template: `
<div class="cart">
<cart-title :uname="uname"></cart-title>
<cart-list :lists="lists" @change-num='changeNum($event)' @cart-del='delCart($event)'></cart-list>
<cart-total :lists="lists"></cart-total>
</div>
`,
components: {
//第一局部组件 定义太多全局组件容易起冲突
'cart-title': CartTitle,
'cart-list': CartList,
'cart-total': CartTotal
},
methods: {
changeNum: function(val) {
var reg = /^[0-9]{1,5}$/; //正则匹配不能输入中文
//分三种情况:输入域变更,加号变更,减号变更
if (val.type == 'change') {
if (reg.test(val.num)) {
console.log(reg.test(val.num)); //true
console.log(typeof val.num); //隐式迭代 变成string型
//根据子组件传递过来的数据,跟新list中对应的数据
this.lists.some(item => {
if (item.id == val.id) {
if (item.num > 0) {
//输入框不能为负值
item.num = val.num;
} else {
item.num = 0;
}
//终止遍历
return true;
}
});
} else {
console.log(reg.test(val.num)); //false
this.lists.some(item => {
if (item.id == val.id) {
item.num = 0;
//终止遍历
return true;
}
});
}
} else if (val.type == 'sub') {
//减一操作
this.lists.some(item => {
//不能减到0以下
if (item.id == val.id) {
if (item.num >= 1) {
item.num = item.num * 1 - 1;
//我的想法是给item.num*1 这样就又转number类型 直接把item.num 写成 item.Number(num)没有用 显示undefined
} else {
item.num = 0;
}
//终止遍历
return true;
}
});
} else if (val.type == 'add') {
//加一操作
this.lists.some(item => {
if (item.id == val.id) {
item.num = item.num * 1 + 1;
//终止遍历
return true;
}
})
}
},
delCart: function(id) {
this.lists = this.lists.filter(function(item) { //把筛选后的结果重新赋值给books
return item.id != id //返回那些id 不相等的对象 形成一个新的数组
})
}
},
});
var vm = new Vue({
el: '#app',
data: {}
})
</script>
analyse de code js:
1 .Les composants variables définis localement doivent être placés devant les composants globaux! ! !
2 .<img :src="item.img"/>
Ne peut pas être écrit comme {{item.img}}! ! Écrivez item.img directement
3. Utilisez computed
des attributs calculés pour avoir une valeur de retourreturn
4. Utilisez la correspondance d'expressions régulières pour que la zone de saisie ne puisse entrer que des nombres, elle est directement nulle en chinois.
Attention! ! !: Num après correspondance d'expression régulièreLe type de données a changé (itération implicite) nombre => chaîne, Conduisant à l'ajout du bouton de signe moins est l'ajout de caractères
Solution :
Le code pour l'augmentation et la diminution des boutons d'addition et de soustraction suivants est modifié comme suit
//加
item.num = item.num * 1 - 1;
//减
item.num = item.num * 1 + 1;
Mon idée est de donner item.num * 1 de cette façon, puis de transformer directement le type de nombre pour écrire item.num en item.Number (num) est inutile et le résultat n'est pas défini
5. (Traitement détaillé) Le fonctionnement de la touche moins ne peut pas le laisser <0, utilisez la condition pour juger.
6.Deux façons d'écrire le bouton Supprimer:
Le premier: (analyse voir notes)
delCart: function(id) {
this.lists = this.lists.filter(function(item) { //把筛选后的结果重新赋值给books
return item.id != id //返回那些id 不相等的对象 形成一个新的数组
})
}
Le deuxième type (analyse voir notes)
delCart: function(id) {
// 根据id删除list中对应的数据
// 1、找到id所对应数据的索引
var index = this.list.findIndex(item => {
return item.id == id;
});
// 2、根据索引删除对应数据
this.list.splice(index, 1);
}