Vue 计算属性的问题

loser
  • 325
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app"></div>
    <template id="a">
        <table>
            <thead>
                <th>序号</th>
                <th>书籍名称</th>
                <th>出版日期</th>
                <th>价格</th>
                <th>购买数量</th>
                <th>操作</th>
            </thead>
            <tbody>
                <tr v-for="(book,index) in fliterBooks">
                    <td>{{index+1}}</td>
                    <td>{{book.bookName}}</td>
                    <td>{{book.date}}</td>
                    <td>{{book.price}}</td>
                    <td>
                        <button :disabled="book.count<=1" @click="decrement(index)">-1</button>
                        <span>{{book.count}}</span>
                        <button @click="increment(index)">+1</button>
                    </td>
                    <td>
                        <button @click="removeBook(index)">删除</button>
                    </td>
                </tr>
            </tbody>
        </table>
        <h2>总价格:{{totalPrice}}</h2>
    </template>
    <script src="../vue3.js"></script>
    <script>
        Vue.createApp({
            template:"#a",
            data()
            {
                return {
                    books:[
                        {
                            bookName:"算法导论",
                            date:"2006-9",
                            price:85,
                            count:1
                        },
                        {                            
                            bookName:"编程艺术",
                            date:"2006-2",
                            price:59,
                            count:1
                        },
                        {
                            bookName:"编程珠玑",
                            date:"2008-10",
                            price:39,
                            count:1
                        },
                        {
                            bookName:"代码大全",
                            date:"2006-3",
                            price:128,
                            count:1
                        }
                    ]
                }
            },
            methods:{
                decrement(index)
                {
                    this.books[index].count--;
                },
                increment(index)
                {
                    this.books[index].count++;
                },
                removeBook(index)
                {
                    this.books.splice(index,1);
                } 
            },
            computed:{
                totalPrice()
                {
                    return this.books.reduce((pre,cur)=>
                    {
                        return pre+cur.price*cur.count;
                    },0);
                },
                fliterBooks()
                {
                    return this.books.map(item=>{
                        const newItem=Object.assign({},item);
                        newItem.price="$"+item.price;
                        console.log(item);
                        return newItem;
                    });
                }

            }
        }).mount("#app");
    </script>
</body>
</html>




fliterBooks()
                {
                    return this.books.map(item=>{
                        const newItem=Object.assign({},item);
                        newItem.price="$"+item.price;
                        console.log(item);
                        return newItem;
                    });
                }

我就很奇怪,为什么<tr v-for="(book,index) in fliterBooks">
为什么这个计算属性,在button点击(+1 -1)的时候,数据也会发生改变,明明没有进入响应式。
totalPrice()引用的是books这个数组,可是点击的时候使用的是fliterBooks这个计算属性自己产生的对象,可是他也会发生改变,为什么啊?

回复
阅读 464
2 个回答
✓ 已被采纳

官网的说明:image.png

你深度监听下books,会发现button点击(+1 -1)的时候都会被监听到的,你的computed设置了totalPrice和fliterBooks,Vue知道它们都依赖于books,所以会触发computed。

fliterBooks()和totalPrice()都是计算属性,他们也都依赖于this.books,当this.books发生变化时,计算属性也会跟着发生改变。

你可以像绑定普通属性一样在模板中绑定计算属性。Vue 知道 vm.reversedMessage 依赖于 vm.message,因此当 vm.message 发生改变时,所有依赖 vm.reversedMessage 的绑定也会更新。而且最妙的是我们已经以声明的方式创建了这种依赖关系:计算属性的 getter 函数是没有副作用 (side effect) 的,这使它更易于测试和理解。
宣传栏