Vue 基础之侦听器

导读:本篇文章讲解 Vue 基础之侦听器,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

描述

项目 描述
IDE VScode
操作系统 Windows 10 专业版
Vue.js 2.6.12

侦听器

侦听器允许开发者对数据进行监视,并指定数据发生变化时需要执行的操作。

侦听器的创建

侦听器需要定义在 watch 节点中,侦听器可以定义为一个函数为一个对象。其函数名或对象名需要与被监听数据的名称(该数据在 data 节点中对应的名称)相同。

侦听器的处理函数接受提供两个实参,请使用相同数量的形参对其进行接收。其中,第一个实参为数据变化后的值,第二个参数为数据变化前的值。

如果通过创建对象的方式创建监听器,则处理函数需要定义在 handler 方法名之中。

侦听器的应用

侦听器在实际开发中,常用于 检测用户名是否已经被使用。我将使用一个 users 列表来代替存放用户名的数据库。具体实现代码如下:

<!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>Vue 基础之侦听器</title>
</head>
<body>
    <div id="app">
        <!-- 被侦听的目标元素 input -->
        <input id="name" type="text" v-model:value="username" placeholder="请输入您的用户名">
    </div>

    <!-- 导入 Vue.js -->
    <script src="../lib/vue-2.6.12.js"></script>
    <script>
        // 创建 ViewModel 对象
        const vm = new Vue({
            el: '#app',
            data: {
                username: '',
                users: ['redheart', 'yjh', 'twomoons']
            },
            watch: {
                username(after, before){
                    // 先将变化后的值转换为小写字符,再通过 includes 方法
                    // 判断该值是否存在于 users 数组之中。
                    if(vm.users.includes(after.toLowerCase())){
                        // 若该用户名已存在于 users 中,我们将更改输入框
                        // 中的文本颜色为红色。
                        document.querySelector('#name').style.color = 'red'
                    }else{
                        // 当输入的文本不存在于 users 中时,我们将更改输入
                        // 框中的文本颜色为黑色。
                        document.querySelector('#name').style.color = 'black'
                    }
                }
            }
        })
    </script>
</body>
</html>

执行效果:

执行效果

选项

Vue 中的侦听器为开发者提供了多个选项来满足各位的特殊需求。

immediate 选项

immediate 选项可以使侦听器在创建后立即执行相关的处理函数,要设置 immediate 选项需要通过对象字面量的形式创建监听器。

<!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>Vue 基础之侦听器</title>
</head>
<body>
    <div id="app">
        <!-- 被侦听的目标元素 input -->
        <input id="name" type="text" v-model:value="username" placeholder="请输入您的用户名">
    </div>

    <!-- 导入 Vue.js -->
    <script src="../lib/vue-2.6.12.js"></script>
    <script>
        // 创建 ViewModel 对象
        const vm = new Vue({
            el: '#app',
            data: {
                username: ''
            },
            watch: {
                username: {
                    handler: (after, before) => {
                        alert(before + ' ' + after)
                    },
                    immediate: true
                }
            }
        })
    </script>
</body>
</html>

在执行上述代码后,首次进入页面可能会立即弹出弹窗(在创建侦听器后立即执行处理函数)。

立即执行

deep 选项

当监听的目标数据为一个对象时,对象中的属性的值发生变化并不会触发侦听器。

未使用 deep 选项
<!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>Vue 基础之侦听器</title>
</head>
<body>
    <div id="app">
        <!-- 被侦听的目标元素 input -->
        <input id="name" type="text" v-model:value="info.username" placeholder="请输入您的用户名">
    </div>

    <!-- 导入 Vue.js -->
    <script src="../lib/vue-2.6.12.js"></script>
    <script>
        // 创建 ViewModel 对象
        const vm = new Vue({
            el: '#app',
            data: {
                info: {
                    username: ''
                },
                users: ['redheart', 'yjh', 'twomoons']
            },
            watch: {
                info: {
                    handler: (target) => {
                        // 先将变化后的值转换为小写字符,再通过 includes 方法
                        // 判断该值是否存在于 users 数组之中。
                        if(vm.users.includes(target.username.toLowerCase())){
                            // 若该用户名已存在于 users 中,我们将更改输入框
                            // 中的文本颜色为红色。
                            document.querySelector('#name').style.color = 'red'
                        }else{
                            // 当输入的文本不存在于 users 中时,我们将更改输入
                            // 框中的文本颜色为黑色。
                            document.querySelector('#name').style.color = 'black'
                        }
                    }
                }
            }
        })
    </script>
</body>
</html>

执行结果:

执行结果

注:

  1. 由执行结果可以发现,侦听器无法检测到被侦听对象内属性的变化。
使用 deep 选项

使用 deep 选项后可以侦听到目标对象中属性的变化。

<!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>Vue 基础之侦听器</title>
</head>
<body>
    <div id="app">
        <!-- 被侦听的目标元素 input -->
        <input id="name" type="text" v-model:value="info.username" placeholder="请输入您的用户名">
    </div>

    <!-- 导入 Vue.js -->
    <script src="../lib/vue-2.6.12.js"></script>
    <script>
        // 创建 ViewModel 对象
        const vm = new Vue({
            el: '#app',
            data: {
                info: {
                    username: ''
                },
                users: ['redheart', 'yjh', 'twomoons']
            },
            watch: {
                info: {
                    handler: (target) => {
                        // 先将变化后的值转换为小写字符,再通过 includes 方法
                        // 判断该值是否存在于 users 数组之中。
                        if(vm.users.includes(target.username.toLowerCase())){
                            // 若该用户名已存在于 users 中,我们将更改输入框
                            // 中的文本颜色为红色。
                            document.querySelector('#name').style.color = 'red'
                        }else{
                            // 当输入的文本不存在于 users 中时,我们将更改输入
                            // 框中的文本颜色为黑色。
                            document.querySelector('#name').style.color = 'black'
                        }
                    },
                    deep: true
                }
            }
        })
    </script>
</body>
</html>

正常执行

注:

  1. 请注意,在该示例中,我仅使用了一个参数。这是因为侦听目标为对象,参数接收到的数据并不为数据变化前后的数据值,参数将接收到的是一个对象。在本示例中,参数接收到的内容为:
    接收内容
  2. 由于实参为一个对象,所以我们将 username 转换为小写字符需要使用 target.username.toLowerCase() 而不是 target.toLowerCase(),否则你将收到如下错误信息:

错误信息3. 利用 deep 选项,我们可以使得多个数据共同使用同一个侦听器(使用 deep 选项后,监听的目标对象中的属性值发生变化都将触发侦听器)。

  1. 使用多个形参接收实参,得到的实参均为一个相同的对象。
侦听目标对象中的单个属性

即使不适用 deep 选项,我们同样也可以侦听对象中的属性的值的变化,只不过不能使得目标对象中的多个属性触发监听器,仅目标对象中的目标属性可以触发侦听器。

<!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>Vue 基础之侦听器</title>
</head>
<body>
    <div id="app">
        <!-- 被侦听的目标元素 input -->
        <input id="name" type="text" v-model:value="info.username" placeholder="请输入您的用户名">
    </div>

    <!-- 导入 Vue.js -->
    <script src="../lib/vue-2.6.12.js"></script>
    <script>
        // 创建 ViewModel 对象
        const vm = new Vue({
            el: '#app',
            data: {
                info: {
                    username: ''
                },
                users: ['redheart', 'yjh', 'twomoons']
            },
            watch: {
                // 需要使用引号对表达式进行包裹
                'info.username': {
                    handler: (after, before) => {
                        // 先将变化后的值转换为小写字符,再通过 includes 方法
                        // 判断该值是否存在于 users 数组之中。
                        if(vm.users.includes(after.toLowerCase())){
                            // 若该用户名已存在于 users 中,我们将更改输入框
                            // 中的文本颜色为红色。
                            document.querySelector('#name').style.color = 'red'
                        }else{
                            // 当输入的文本不存在于 users 中时,我们将更改输入
                            // 框中的文本颜色为黑色。
                            document.querySelector('#name').style.color = 'black'
                        }
                    }
                }
            }
        })
    </script>
</body>
</html>

注:
使用该方法时,需要在使用引号包裹表达式:
需要使用引号对表达式进行包裹

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由半码博客整理,本文链接:https://www.bmabk.com/index.php/post/84031.html

(0)

相关推荐

半码博客——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!