0


uniapp 笔记第三天(修改数组对象的某个值、watch、computed)

一、给数组绑定点击事件

在之前的学习中都是给一些基本的元素(button、view)绑定了元素 ,但从来没给每个循环元素绑定过

    <view class="box1 flexA" v-for="(item,index) in list"  @click="getItem(item,index)">
            <view class="" style="margin-left: 100rpx;">
                <view class="flexJ" style="width: 400rpx;">
                    <view class="">商品名称 </view>
                    <view class="">{{item.name}}</view>
                </view>
                <view class="flexJ" style="width: 400rpx;">
                    <view class="">数量</view>
                    <view class="">{{item.num}}</view>
                </view>
                <view class="flexJ" style="width: 400rpx;">
                    <view class="">价钱</view>
                    <view class="">¥{{item.price}}</view>
                </view>
            </view>
        </view>

        list: [{
                    name: '奥特曼1',
                    num: 6,
                    price: 50,
                    id: 1,
                    status: false,
                }, {
                    name: '奥特曼2',
                    num: 5,
                    price: 30,
                    id: 2,
                    status: false,
                }, {
                    name: '奥特曼3',
                    num: 8,
                    price: 16,
                    id: 3,
                    status: false,
                }],

上面是一组基础数据 我们要实现点击哪个组 就拿到哪组的数据 记得给谁绑定谁就会生效,绑定了点击事件 记得要在methods里面定义哈

    getItem(item, index) {
                console.log(item, index);
    },

注意在循环中 我们是可以把循环的变量当做参数传给 methods里定义的方法里的, 注意传过去的参数 和接受的参数 要对应

<view class="box1 flexA" v-for="(item,index) in list"  @click="getItem(item,index)"></view>

    getItem(item, index) {
                console.log(item, index);
    },

可以看到从上面 点击哪个值 在控制台就可以打印出对应的值

二、修改数组对象中的某个值

这时候有一个场景哈 如果让你实现点击哪一项让当前的哪一项 的价钱加1你会怎么做

先来说一种错误写法 直接修改item里面的变量 让里面的价钱+1

getItem(item, index) {
                 item.price = item.price + 1
    },

本质上是可以这么修改的,但是不推荐哈,原因就是 传过来的对象和data里面定义的对象 指向的都是同一个地址,所以可以修改,如果你去定义一个简单的数据类型

// template
    <view @click="add(num)"> {{num}} </view>

//data:
    num: 0,

// methods
    add(num) {
         num=num+1
    },

如果你试过的话 你会发现这么修改简单数据类型并没有任何作用,原因是简单数据类型没有地址的概念 现在修改的num是一个简单数据类型传过来的 num 并非data里定义的 num 传过来的只是值而已

如果你想修改变量的话 直接赋值data里的变量即可

add(num) {
                this.num = this.num + 1
        },

如果你想直接修改 复杂数据类型里的某个值 也是同理,我们既然可以拿到上面的索引 直接根据索引找某个值就好了

getItem(item, index) {
                console.log(item, index);
                // 1. 第一种写法 拿到list对应的当前项的值去+1
                 this.list[index].price = this.list[index].price + 1 
            },
    getItem(item, index) {
                console.log(item, index);
                // 2. 第二种写法  拿到item 当前项的值去+1
                 this.list[index].price = item.price + 1
            },

三、切换变量小demo

<template>
    <view class="">
        <view class="box1 flexA" v-for="(item,index) in list" >
            <view class="" @click="toggleStatus(item,index)">
                <image v-if="item.status==true" src="/static/yes.png" mode=""></image>
                <image v-else src="/static/noCur.png" mode=""></image>
            </view>
            <view class="" style="margin-left: 100rpx;">
                <view class="flexJ" style="width: 400rpx;">
                    <view class="">商品名称 </view>
                    <view class="">{{item.name}}</view>
                </view>
                <view class="flexJ" style="width: 400rpx;">
                    <view class="">数量</view>
                    <view class="">{{item.num}}</view>
                </view>
                <view class="flexJ" style="width: 400rpx;">
                    <view class="">价钱</view>
                    <view class="">¥{{item.price}}</view>
                </view>
            </view>
        </view>
    </view>
</template>

//data
list: [{
                    name: '奥特曼1',
                    num: 6,
                    price: 50,
                    id: 1,
                    status: false,
                }, {
                    name: '奥特曼2',
                    num: 5,
                    price: 30,
                    id: 2,
                    status: false,
                }, {
                    name: '奥特曼3',
                    num: 8,
                    price: 16,
                    id: 3,
                    status: false,
                }],

我们想呢 点击哪个按钮 就让谁切换它的状态,看上面的数据哈 每一项都有一个status 你就可以根据索引拿到当前的状态赋值 做法就是取反哈!

toggleStatus(item, index) {
                this.list[index].status = !item.status
            },

四、计算选中的价格

我们还是通过上面定义的点击事件哈

1.先不考虑当前选没选中 先把所有的价钱算出来

错误写法:

toggleStatus(item, index) {
                this.list[index].status = !item.status
                this.list.forEach(it=>this.allPrice = it.price*it.num)
            },

这么写的话永远拿的都是 最后一次循环的值 每次都在替换 知道替换到最后一次 变成了128

正确写法:

                 this.list.forEach(it=> this.allPrice = this.allPrice + it.price*it.num)

这样写呢 就会把之前把之前计算过的带着再算一次

这样我们就可以拿到 所有的价钱哈

2.计算选中的

我们想要的并不是所有的总价钱 肯定是拿到选中的

第一种写法

toggleStatus(item, index) {
                this.list[index].status = !item.status
                
                // 第一种写法
                 this.allPrice = 0
                 this.list.forEach((it, idx) => {
                     if (it.status == true) {
                         this.allPrice = this.allPrice + it.price * it.num
                     }
                 })
                
            },

记得每次都赋值一下初始值哈,如果 你不知道什么原因 我建议你把赋值一行代码注释了 看看有没有什么影响

第二种写法

toggleStatus(item, index) {
                this.list[index].status = !item.status
                // 思路:把选中的数组过滤出来 再去计算
                 let arr = this.list.filter(item=> item.status) // 把选中的数组过滤出来 赋值给arr
                 let sum = 0 // 算出总价钱用的
                 arr.forEach(it=> sum = sum +  it.price * it.num) //计算价钱
                 this.allPrice = sum // 赋值给上面的变量
                 console.log('总价钱',sum,'当前选中的数组',arr);
                
            },

四、computed

computed 计算属性通常适合做一些映射、多对一时进行的操作,多对一:例如 一个数组中 判断每项算出一个结果出来

语法:

    computed: {
            getAllPrice() {
                return this.num+1
            }
        },

我们来看vue 给我提供的例子

{{ message.split('').reverse().join('') }}

上面呢 在一个差值表达式里调用了很多方法 如果说在上面操作中在加一些方法会不会感觉很凌乱,所以vue提供给我们了计算属性,它会实时根据data里的变量实时映射

    {{reverseStr}}

    computed: {
            reverseStr(){
                return this.str.split('').reverse().join('')
            }
        },

例如通过上面例子中计算总价格 我们就可以通过计算属性去实现它

    getAllPrice() {
                return this.list.filter(it => it.status).reduce((acc, it) => acc + it.price * it.num, 0)
            },

reduce 的执行过程

五、watch

watch监听 他会实时监听这某一个、或某一组值的变化

简单数据类型监听

watch: {
            num(newValue, oldValue) {
                console.log('num新值:',newValue, 'num旧值',oldValue);
                // 做一些操作代码
                this.watchNum = newValue + 999
            }
}

复杂数据类型

watch: {
            list:{
                deep:true, // 开启深度监听 专门对付复杂数据类型
                immediate:true, // 首次监听 一打开页面就想监听
                handler: function (newValue, oldValue){
                    this.watchAllPrice = 0
                    this.list.forEach((it, idx) => {
                        if (it.status == true) {
                            this.watchAllPrice = this.watchAllPrice + it.price * it.num
                        }
                    })                
                }
                
            }
},

注意:handler的函数格式不要写成箭头函数,否则拿不到当前的vue实例

总结 :watch能做的computed都可以实现,如果说你发现了哪个好玩的功能点 可以考虑试一下这两个是否都能实现呢

扩展:watch和computed 的区别

标签: javascript vue 前端

本文转载自: https://blog.csdn.net/m0_61389631/article/details/126134837
版权归原作者 同学们听懂了吗 所有, 如有侵权,请联系我们删除。

“uniapp 笔记第三天(修改数组对象的某个值、watch、computed)”的评论:

还没有评论