效果图:
拓展:在一个组件实例中,只有在data里初始化的数据才是响应的,Vue2不能检测到对象属性的添加或删除,没有在data里声明的属性不是响应的。Vue不允许在已经创建的实例上动态添加根级响应式属性,但是可以使用$set方法将相应属性添加到嵌套的对象上。
数组数据变动,使用某些方法操作数组,变动数据时,有些方法无法被vue监测 push(),pop(),shift(),unshift(),splice(),sort(),reverse()可被vue检测到 filter(), concat(), slice()。这些不会改变原始数组,但总是返回一个新数组。当使用非变异方法时,可以用新数组替换旧数组。
vue2不能检测以下变动的数组:
1、当你利用索引直接设置一个项时,vm.items[indexOfItem] = newValue
2、当你修改数组的长度时,例如:vm.items.length = newLength
<template>
<div>
<div class="main" @click="open">
<text>点击</text>
</div>
<!-- 遮罩层 -->
<div class="mask" v-if="show" @touchmove.prevent.stop @click="close">
<div class="screen" @touchmove.prevent.stop>
<div class="screen-title">
<text class="screen-word">筛选</text>
</div>
<div v-for="(item,index) in skuNameList" :key="index">
<text class="condition">{{item.skuName}}</text>
<div class="types" >
<text class="time" v-for="(a,b) in item.skuValues" :key="b" :class="[b == skuNameList[index].selectIndex ? 'bgc' : '']" @click="selectTime(index,b)">{{a.name}}</text>
</div>
</div>
<div class="btn">
<text class="common" @click="reset">重置</text>
<text class="common sure" @click="confirm">确定</text>
</div>
</div>
</div>
</div>
</template>
<script>
import Light from "light";
const modal = Light.requireModule("modal");
export default {
data() {
return {
show: false,
skuNameList: [
{
id: "1",
skuName: "颜色",
skuValues: [
{ name: "红色", id: "1-1" },
{ name: "蓝色", id: "1-2" }
]
},
{
id: "2",
skuName: "尺寸",
skuValues: [
{ name: "大", id: "2-1" },
{ name: "小", id: "2-2" },
{ name: "中", id: "2-3" }
]
},
{
id: "3",
skuName: "风格",
skuValues: [{ name: "波西米亚", id: "3-1" }]
}
],
confirmList: []
};
},
mounted() {
//页面加载给数据遍历添加selectIndex 属性
this.skuNameList.forEach(element => {
element.selectIndex = -1;
});
},
methods: {
// 打开弹窗
open() { this.show = true; },
// 关闭
close() { this.show = false; this.reset(); },
//选择
selectTime(index, b) {
// this.skuNameList[index].selectIndex = b;
//vue中修改了数组或对象某条数据的某个属性,数据变了,页面不渲染
var josn = this.skuNameList[index];
josn.selectIndex = b;
this.$set(this.skuNameList, index, josn);
//$set可以触发更新视图
console.log(this.skuNameList);
},
// 确定
confirm() {
this.confirmList = [];
this.skuNameList.map(item => {
item.skuValues.map((element, index) => {
if (item.selectIndex == index) {
this.confirmList.push(element);
}
});
});
console.log(this.confirmList);
if (this.confirmList.length == 0) {
console.log("请选择筛选条件");
return;
}
},
// 重置
reset() {
this.confirmList = [];
this.skuNameList.map((item, index) => {
item.selectIndex = -1;
this.$set(this.skuNameList, index, item); //$set可以触发更新视图
});
console.log(this.skuNameList);
}
}
};
</script>
<style scoped>
.main { margin-top: 200px; margin-left: 100px; width: 400px; border-style: solid; border-width: 1px; border-color: #ccc; height: 200px; justify-content: center; align-items: center;}
.mask { position: fixed; left: 0; bottom: 0; right: 0; top: 0; min-height: 100vh; background-color: rgba(1, 1, 1, 0.5);}
.screen { position: fixed; left: 0; right: 0; bottom: 0px; height: 600px; background-color: #fff; padding: 20px 20px 0px 20px;}
.screen-title { align-items: center; font-weight: 700;}
.condition { font-weight: 700; font-size: 28px;}
.types { flex-direction: row; flex-wrap: wrap; padding: 10px; width: calc(100% + 24px);}
.time { width: 200px; height: 50px; text-align: center; line-height: 50px; font-size: 24px; border-color: #ccc; border-style: solid; border-width: 1px; margin-right: 20px; margin-top: 10px;}
.bgc { background-color: red;}
.btn { position: fixed; left: 0; bottom: 0; right: 0; flex-direction: row; justify-content: space-between; height: 130px; background-color: aquamarine;}
.common { height: 130px; line-height: 130px; text-align: center; background-color: #ccc; flex: 1;}
.sure { background-color: firebrick; color: #fff;}
</style>