current position:Home>Vue computed computing and watch monitoring

Vue computed computing and watch monitoring

2022-09-23 06:42:36kind amumu

目录

computed计算,从现有数据计算出新的数据

案例:Filter by fruit name

computed计算总价

监听

案例 计算

案例

案例-watch监听todolist本地存储

localStorage的使用

在AThe page is stored first: 

在B页面中使用:

 类的绑定

数组语法

样式绑定

Style内联样式 

回顾js数组 方法


watch,computed和methods 的关系

1. watch和computed都是以Vue的依赖追踪机制为基础 的,它们都试图处理这样一件事情:当某一个数据(称它为依赖数据)发生变化的时候,所有依赖这个数据的“相关”数据“自动”发生变化,也就是自动调用相关的函数去实现数据的变动.

2.对methods:methods里面是用来定义函数的,很显然,它需要手动调用才能执行.而不像watch和computed那样,“自动执行”预先定义的函数

watch和computed各自处理的数据关系场景不同

1. watch 擅长处理的场景: 一个数据影响多个数据

2. computed擅 长处理的场景: 一个数据受多个数据影响

watch和computed的区别

1、功能上:computed是计算属性,watch是监听一个值的变化,然后执行对应的回调.
2、是否调用缓存:computed中的函数所依赖的属性没有发生变化,那么调用当前的函数的时候会从缓存中读取,而watch在每次监听的值发生变化的时候都会执行回调.
3、是否调用return:computed中的函数必须要用return返回,watch中的函数不是必须要用return.
4、computed默认第一次加载的时候就开始监听;watch默认第一次加载不做监听,如果需要第一次加载做监听,添加immediate属性,设置为true(immediate:true)
5、使用场景:computed----当一个属性受多个属性影响的时候,使用computed-----购物车商品结算.watch–当一条数据影响多条数据的时候,使用watch-----搜索框.

computed计算,从现有数据计算出新的数据

computed是计算属性,主要作用是把数据存储到内存中,减少不必要的请求,还可以利用computed给子组件的data赋值.

computed用来监控自己定义的变量,该变量不在data里面声明,直接在computed里面定义,然后就可以在页面上进行双向数据绑定展示出结果或者用作其他处理.

<body>
    <div id="app">
        <input type="text" v-model.number="n1">

        <input type="text" v-model.number="n2">
        <p>{
   {n3}}</p>
        <p>{
   {rstr}}</p>
    </div>
</body>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script>
    new Vue({
        el: "#app",
        computed: {
            //从现有的n1与n2计算出n3
            "n3": function () {
                return this.n1 + this.n2;
            },
            //rstr是从现有的str算出
            rstr() {
                return this.str.split('').reverse().join("");
            }
        },
        data() {
            return {
                n1: 1,
                n2: 2,
                str: "明天放假15天"
            }
        }
    })

</script>

案例:Filter by fruit name

<body>
    <div id="app">
        <h1>search for fruit</h1>
        <input type="text" v-model="keyword">
        <div v-for="(item,index) in flist" :key="index">{
   {item}}</div>
    </div>
</body>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script>
    new Vue({
        el: "#app",
        computed: {
            flist() {
                // 如果搜索关键字为空,返回所有的水果
                if (this.keyword.trim() === "") {
                    return this.list;
                } else {
                    var temp = this.list.filter(item => {
                        // 当fruit里面个某一项文字包含keyword文字那么就把当前数据保留
                        // filter过滤,遍历返回为真 保留,为false就过滤掉
                        // 当通过indexOf查字符串时候返回-1 代表找不到
                        // 不等于-1代表找到了
                        if (item.indexOf(this.keyword) != -1) {
                            return true;
                        } else {
                            return false;
                        }
                    });
                    return temp;
                }
            }

        },
        data() {
            return {
                keyword: "",
                list: ["苹果", "沙果", "海棠", "野樱莓", "枇杷", "欧楂", "山楂", "香梨", "雪梨 等)", "温柏", "蔷薇果", "花楸", "杏", "樱桃", "桃", "水蜜桃", "油桃", "蟠桃", "李子", "梅子(青梅)", "西梅", "白玉樱桃 ", "黑莓", "覆盆子", "云莓", "罗甘莓", "白里叶莓", "草莓", "菠萝莓", "橘子", "砂糖桔", "橙子", "柠檬", "青柠", "柚子", "金桔", "葡萄柚", "香橼", "佛手", "指橙", "黄皮果", "哈密瓜", "香瓜", "白兰瓜", "刺角瓜"]
            }
        },
    });
    // 通过计算 keyword与list 算出flist
	// 如果list中的某一项包含 keyword关键字,在flist保留该项
	// includes检测是否包含某个字符串 indexOf()不等于-1
	// filter过滤数组
	// trim 移除字符串两端的空格

</script>

computed计算总价

<body>
    <div id="app">
        <table border="1">
            <tr>
                <th>选择</th>
                <th>商品名称</th>
                <th>价格</th>
                <th>数量</th>
            </tr>
            <tr v-for="item in goods" :key="item.name">
                <!-- 选项框 -->
                <td><input type="checkbox" v-model="item.sel"></td>
                <!-- 商品名称 -->
                <td>{
   {item.name}}</td>
                <!-- 价格 -->
                <td>{
   {item.price}}</td>
                <!-- 数量 -->
                <td><button @click="item.num++">{
   {item.num}}</button></td>
            </tr>
        </table>
        <p>总价:{
   {total}},共{
   {count}}件</p>
    </div>
</body>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script>
    new Vue({
        el: "#app",
        data() {
            return {
                goods: [{
                    name: "javacript入门",
                    price: 20,
                    num: 2,
                    sel: true,
                }, {
                    name: "vue实战",
                    price: 80,
                    num: 5,
                    sel: false,
                }]
            }
        },
        computed: {
            total() {
                //The default total price to return
                var n = 0;
                this.goods.forEach(item => {
                    //累加数量 * 加载
                    if (item.sel)
                        n += item.price * item.num;
                })
                //返回
                return n;
            },
            count() {
                //Returns the default number of pieces
                var n = 0;
                this.goods.forEach(item => {
                    //累加数量
                    if (item.sel)
                        n += item.num;
                })
                //返回
                return n;
            }
        }
    });

</script>

监听

定义:监听数据的变化,执行回调函数

值类型监听

    watch:{
     "num":function(){
        ......
      }
    }

案例 计算

<body>
    <div id="app">
        <h1>watch监听-计算</h1>
        <input type="text" v-model.number="obj.pre">
        <select name="" id="" v-model="obj.type">
            <option value="+">+</option>
            <option value="-">-</option>
            <option value="*">*</option>
            <option value="/">/</option>
        </select>
        <input type="text" v-model.number="obj.next">
        ={
   {obj.result}}


    </div>
</body>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script>
    new Vue({
        el: "#app",
        data() {
            return {
                obj: {
                    pre: 1,
                    type: "+",
                    next: 1,
                    result: 2,
                }
            }
        },
        watch: {
            //Reference type data monitoring needs to be addeddeep选项
            //oval和nval都是最新的值
            "obj": {
                handler(nval, oval) {
                    // 只要objChanges are recalculatedresult的值
                    this.obj.result = eval(`${this.obj.pre}${this.obj.type}${this.obj.next}`)
                },
                deep: true,

            }
        }

    });

</script>

引用类型监听
        nval The latest value of the data
        oval The value before the data

    watch:{
      obj:{
        handler(nval){...},
        deep:true
      }
    }

案例

<body>
    <div id="app">
        <h1>watch监听</h1>
        <button @click="obj.pre++">{
   {obj.pre}}</button>
    </div>
</body>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script>
    new Vue({
        el: "#app",
        data() {
            return {
                obj: {
                    pre: 5,
                }
            }
        },
        watch: {
            //Reference type data monitoring needs to be addeddeep选项
            //oval和nval都是最新的值
            "obj": {
                handler(nval, oval) {
                    console.log("数据发生变化", oval, nval);
                },
                deep: true,
            }
        }

    });

</script>

案例-watch监听todolist本地存储

<body>
    <div id="app">
        <input type="text" @keyup.enter="addItem">
        <!-- 遍历数据list -->
        <h3>未完成{
   {undolist.length}}</h3>
        <div v-for="item in undolist" :key="item.title">
            <input type="checkbox" v-model="item.done">
            <span>{
   {item.title}}</span>
            <button @click="delItem(item)">x</button>
        </div>
        <h3>已经完成{
   {donelist.length}}</h3>
        <div v-for="item in donelist" :key="item.title">
            <input type="checkbox" v-model="item.done">
            <span>{
   {item.title}}</span>
            <button @click="delItem(item)">x</button>
        </div>
    </div>
    <script>
        new Vue({
            el: "#app",
            computed: {
                // 通过计算list算出undolist没有完成的列表
                undolist() {
                    // 通过list过滤 返回item.done值为false的所有元素
                    return this.list.filter(item => !item.done);
                },
                donelist() {
                    // 返回保留item.done值为true的元素
                    return this.list.filter(item => item.done);
                }
            },
            methods: {
                // 删除元素
                delItem(item) {
                    // 查找item在list的下标
                    var ind = this.list.indexOf(item);
                    // 进行删除
                    this.list.splice(ind, 1);
                },
                // 添加元素
                addItem(e) {
                    // e.target输入的文本框
                    // e.target.value 文本框的值
                    this.list.unshift({ done: false, title: e.target.value })
                    // 清空文本框的内容
                    e.target.value = "";
                }
            },
            data() {
                return {
                    //从本地localStorage获取数据,If you can't get it, use the default
                    list: JSON.parse(localStorage.getItem("done") || '[{ "done": true, "title":"学习html" }]')
                }
            },
            watch: {
                "list": {
                    handler() {
                        //监听list的变化,存储todo数据
                        localStorage.setItem("done", JSON.stringify(this.list))
                    },
                    deep: true,
                }
            },
        })
			// 目标:1 在文本框输入文字,按回车,文字添加到list里面
			// 目标:2 单击x 删除当前行
			// unshift在数组的前面添加一个元素
			// splice(n,m,j) 从第n个删除m个,添加j
			// indexOf(item) 查找item在列表的下标
    </script>

localStorage的使用

localStorage.getItem(key):获取指定key本地存储的值
localStorage.setItem(key,value):将value存储到key字段

在AThe page is stored first: 

var imgs = obj_mainform.archivesId  //Declare a variable to store data
localStorage.setItem('key',imgs);  //将变量imgs存储到name字段

在B页面中使用:

var naid = localStorage.getItem("key"); //获取指定key本地存储的值

 类的绑定

1.给v-bind:class 设置一个对象,可以动态地切换class,例如:

<div id="app">
    <div :class="{'active':isActive}"></div>
</div>
<script>
var app = new Vue({
    el:'#app',
    data:{
        isActive:true
    }
})
</script>

最终渲染结果:<div class="active"></div>
2、Multiple properties can also exist in an object,动态切换class,:class 可以合class共存

<div id="app">
    <div class="static" :class="{'active':isActive,'error':isError}"></div>
</div>
<script>
var app = new Vue({
    el:'#app',
    data:{
        isActive:true,
        isError:false
    }
})
</script>

 最终渲染结果:<div class="static active"></div>

数组语法

我们可以把一个数组传给 :class,以应用一个 class 列表:

<div :class="[activeClass, errorClass]"></div>

<style>
    .active {
        color: aqua;
        background-color: blanchedalmond;
    }

    .big {
        font-size: large;
    }

    .bold {
        color: red;
    }
</style>

<body>
    <div id="app">
        <button @click="flag=!flag" v-bind:class="flag?active:''">开关</button>
        <button @click="flag=!flag" :class="{'active':flag,'big':isbig}">开关</button>
        <!-- 数组方式 -->
        <p :class="classlist" This is the line test text></p>
    </div>
    <script>
        new Vue({
            el: "#app",
            data() {
                return {
                    flag: true,
                    isbig: true,
                    classlist: ['bold', 'big', 'active']
                }
            }
        })

    </script>

样式绑定

<body>
    <div id="app">
        <input type="color" v-model="color">
        <input type="range" min="1" max="200" v-model="height">
        <!-- 数组方式 -->
        <p :style="{'fontSize':'48px','backgroundColor':color,'lineHeight':height+'px'}">样式的绑定</p>
    </div>
    <script>
        new Vue({
            el: "#app",
            data() {
                return {
                    color: "#f00",
                    height: 80

                }
            }
        })

    </script>

Style内联样式 

对象语法:
CSS 属性名可以用驼峰式 (camelCase) 或短横线分隔 (kebab-case,记得用引号括起来) 来命名

<div :style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>


数组语法
<div :style="[baseStyles, overridingStyles]"></div>

回顾js数组 方法

http://t.csdn.cn/5ku8Thttp://t.csdn.cn/5ku8T

copyright notice
author[kind amumu],Please bring the original link to reprint, thank you.
https://en.qdmana.com/2022/266/202209230621493325.html

Random recommended