04-侦听器

168 阅读2分钟

什么是 watch 侦听器

watch 侦听器允许开发者监视数据的变化,从而针对数据的变化做特定的操作。

语法格式如下:

chrome_ZC5Cdq8q3y

使用 watch 检测用户名是否可用

监听 username 值的变化,并使用 axios 发起 Ajax 请求,检测当前输入的用户名是否可用:

watch: {
	// 监听 username 值的变化
	async username(newVal) {
		if (newVal === '') return
		// 使用 axios 发起请求,判断用户名是否可用
		const { data: res } = await axios.get('https://www.escook.cn/api/finduser/' + newVal)
		console.log(res)
	}
}

侦听器格式

  1. 方法格式的侦听器
    • 缺点1:无法在刚进入页面的时候,自动触发
    • 缺点2:如果侦听的是一个对象,如果对象中的属性发生了变化,不会触发侦听器
  2. 对象格式的侦听器
    • 好处1:可以通过 immediate 选项,让侦听器自动触发
    • 好处2:可以通过 deep 选项,让侦听器深度监听对象中每个属性的变化

immediate 选项

默认情况下,组件在初次加载完毕后不会调用 watch 侦听器。如果想让 watch 侦听器立即被调用,则需要使 用 immediate 选项。示例代码如下:

watch: {
	username: {
		// handler 是固定写法,表示当 username 的值变化时,自动调用 handler 处理函数
		handler(newVal,oldVal){
            console.log(newVal,oldVal)
        },
		// 表示页面初次渲染好之后,就立即触发当前的 watch 侦听器
        //immediate 选项的默认值是 false
		immediate: true
	}
}

deep 选项

如果 watch 侦听的是一个对象,如果对象中的属性值发生了变化,则无法被监听到。此时需要使用 deep 选 项,代码示例如下:

<body>
    <div class="app">
        <input type="text" v-model="username">
    </div>
    <script>
        const vm = new Vue({
            el:'.app',
            data:{
                info:{
                    username:'admin'
                }
            },
            // 所有侦听器都应该被定义到 watch 节点下
            watch:{
                info:{
                    handler(newVal){
                        console.log(newVal)
                    },
                    // 开启深度监听,只要对象中任何一个属性变化了,都会触发对象的侦听器
                }
            }
        })
    </script>
</body>

监听对象单个属性的变化

如果只想监听对象中单个属性的变化,则可以按照如下的方式定义 watch 侦听器:

<body>
    <div class="app">
        <input type="text" v-model="info.username">
    </div>
    <script>
        const vm = new Vue({
            el:'.app',
            data:{
                info:{
                    username:'admin'
                }
            },
            // 所有侦听器都应该被定义到 watch 节点下
            watch:{
                // 如果要侦听的是对象的子属性的变化,则必须包裹一层单引号
                'info.username'(newVal) {
                    console.log(newVal)
                }
            }
        })
    </script>
</body>

计算属性

什么是计算属性

计算属性指的是通过一系列运算之后,最终得到一个属性值。 这个动态计算出来的属性值可以被模板结构或 methods 方法使用。示例代码如下:

chrome_7l1o2QjI76

特点:

  1. 定义的时候,要被定义为方法
  2. 在使用计算属性的时候,当普通的属性使用即可

好处:

  1. 实现了代码的复用
  2. 只要计算属性中依赖的数据源变化了,则计算属性会自动重新求值

利用计算属性写一个rgba颜色生成器

<!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>rgba颜色生成器</title>
    <script src="vue-2.6.12.js"></script>
    <style>
        * {
            padding: 0;
            margin: 0;
        }
        .Color {
            width: 200px;
            height: 200px;
            position: absolute;
            top: 150px;
            right: 100px;
            clip-path: polygon(50% 0%, 83% 12%, 100% 43%, 94% 78%, 68% 100%, 32% 100%, 6% 78%, 0% 43%, 17% 12%);
        }
        .app {
            position: relative;
            width: 400px;
            height: 500px;
            border: 3px solid #828584;
            margin: 100px auto;
            border-radius: 15px;
            padding: 15px;
            box-sizing: border-box;
        }
        input {
            width: 45px;
            height: 50px;
            font-size: 20px;
            outline: none;
            border-radius: 5px;
            border: 1px solid #00f9e5;
            text-align: center;
            color: #00f9e5;
            background-color: black;
        }
        p {
            text-align: center;
            margin-top: 250px;
        }
        .top {
            width: 100%;
            display: flex;
            justify-content: space-around;
        }
        .txt {
            display: flex;
            justify-content: space-around;
            font-size: 30px;
            margin-bottom: 5px;
            color: #206f9c;
        }
    </style>
</head>
<body>
    <div class="app">
        <div class="txt"><span>R</span><span>G</span><span>B</span><span>A</span></div>
        <div class="top">
            <input type="text" v-model.number="r">
            <input type="text" v-model.number="g">
            <input type="text" v-model.number="b">
            <input type="text" v-model.number="a">
        </div>
        <div class="Color" :style="{backgroundColor:rgba}"></div>
        <p>{{rgba}}</p>
    </div>
    <script>
        const vm = new Vue({
            el:'.app',
            data:{
                r:0,g:0,b:0,a:0.5
            },
            computed:{
                rgba(){
                    return `rgba(${this.r},${this.g},${this.b},${this.a})`
                }
            }
        })
    </script>
</body>
</html>