【Vue2&3】Vue组件的属性和方法

一、Vue实例

Vue实例又称为Vue组件。

1.Vue2.0创建Vue组件的方法:

            new Vue({...})

<!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>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14"></script>
</head>
<body>
    <div id="app">
            {{ msg }}
    </div>
    <script>
        new Vue({
            el:'#app',
            data:{
                msg:'西安'
            }
        })
    </script>
</body>
</html>

2.Vue3.0创建Vue组件的方法:

           Vue.createApp(...):创建Vue组件。

           .mount(...):将vue组件挂载到页面的某个标签上。

方法一(推荐):

<!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>
    <script src="https://unpkg.com/vue@next"></script>
</head>
<body>
    <div id="app">
     <div>{{ count }}</div>
    </div>
    <script>
        const obj = {
            data(){
                return{
                    count:1
                }
            }
        }
        Vue.createApp(obj).mount('#app')
    </script>
</body>
</html>

方法二(不推荐):

<!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>
    <script src="https://unpkg.com/vue@next"></script>
</head>
<body>
    <div id="app">{{ count }}</div>
    <script>
        const obj = {}
        Vue.createApp({
            data(){
                return{
                    count:120
                }
            }
        }).mount('#app')
    </script>
</body>
</html>

二、Vue组件的属性

1. 存储属性(data)

存储属性是一个函数。在组件创建时会调用此函数来构建响应性的数据系统。是组件的存储属性,专门用来存放数据

获取该属性值的方式
        Vue组件名.变量名
        Vue组件名.$data.变量名

本质是访问的同一个数据块。

<!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>
    <script src="https://unpkg.com/vue@next"></script>
</head>
<body>
    <div id="app">{{ count }}</div>

    <script>
        const obj = {
            data(){
                return {
                    count:120
                }
            }
        }

        let instance = Vue.createApp(obj).mount('#app') //instance就是Vue组件

		//获取存储属性data属性值的方式一:
        console.log(instance.count)

		//获取存储属性data属性值的方式二:
        console.log(instance.$data.count)
    </script>
</body>
</html>

2.计算属性(computed)

通常可以将存储属性的值直接渲染到html的元素上。但在有些场景下存储属性的值不适合直接渲染,需要处理之后再进行渲染。

计算属性指的是 通过一系列运算 之后,最终得到一个 属性值 这个动态计算出来的属性值 可以被 模板结构 methods 方法使用。
注意:
  • 计算属性应该定义为“方法”格式
  • 计算属性可以当作“属性值”被使用

优点:

  • 实现了代码的复用
  • 只要计算属性中依赖的数据源变化了,则计算属性会自动更新求值
    <script src="https://unpkg.com/vue@next"></script>

    <div id="app">
        <div>{{ type }}</div>
		<!--v-on绑定事件,若使用v-on绑定单个事件可以简写为@事件名	-->
        <button @click="add">Add</button>
    </div>

    <script>
        const obj = {
            data(){
                return {
                    count: 0
                }
            },
            //定义计算属性
            computed:{
                 type(){
                     return this.count>10?"大":"小"
                 } 
            },
            methods: {
                add(){
                    this.count++
                }
            }
        }
        let instance = Vue.createApp(obj).mount("#app")
        console.log(instance.type) //获得初始值
    </script>

注意:

  • 存储属性(例如下例中的count)主要用于数据的存取,我们可以通过赋值运算来修改它的属性值。
  • 通常,计算属性只用来取值,不会用来存值,因此计算属性默认提供的是取值方法(get方法);计算属性也可以通过赋值进行存数据,但是存数据的方法需要手动实现(set方法)
  • 当使用计算属性时,默认调用get方法(该方法不能显式调用);当给计算属性赋值时,调用的是set方法(该方法不能显式调用)
    <script src="https://unpkg.com/vue@next"></script>

    <div id="app">
        <div>{{ type }}</div>
        <button @click="add">Add</button>
    </div>

    <script>
        const obj = {
            data(){
                return {
                    count: 0
                }
            },
            //定义计算属性
            computed:{
                type: {
                    get(){ //实现计算属性的get方法,用来取值
                        return this.count>10?"大":"小"
                    },
                    set(newVal){ //实现计算属性的set方法,用来设置的值
                        if(newVal == "大"){
                            this.count = 11
                        }else {
                            this.count = 0
                        }
                    }
                }
            },
            methods: {
                add(){
                    this.count++
                },
                sub:function(prarms){

                },
                m1:(prarms)=>{

                }
            }
        }
        let instance = Vue.createApp(obj).mount("#app")
        console.log("count="+instance.count)
        console.log("type="+instance.type)

        //人为赋值“大”后,count变为11
        instance.type = "大"
        console.log("count="+instance.count)
    </script>

3.侦听属性(属性侦听器watch)

可以方便的监听某个属性变化,以完成复杂的业务逻辑。在Vue中的属性侦听器是watch

作用:watch是vue内部提供的一个用于侦听功能的更通用的方法,其用来响应数据的变化,通过特定的数据变化驱动一些操作。
vue官方文档解释当需要在数据变化时执行异步或开销较大的操作时,推荐使用该方法。
Vue侦听器是提供给开发者可以用来监测某些数据的变化,从而针对这些数据的变化进行某些操作。

Vue侦听器提供了两种语法格式

3.1 普通数据类型(方法格式的侦听器):

侦听器本质上是一个函数,如果要监听哪一个数据的变化,就把那个数据作为函数名

const vm = new Vue({

    el: '#app' ,
    data: { username: '" },

    watch: {
    //侦听器本质上是一个函数,要监视哪个数据的变化,就把数据名作为方法名即可
    //newVal 是"变化后的新值",oldval是"变化之前的旧值”

        username(newval,oldval) {
            console.log(newVal, oldVal)

        }
    }

})

    <div id="app">
     <input type="text" v-model="searchText">
    </div>

    <!--  Vue2.0写法  -->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14"></script>
    <script>
        const vm = new Vue({
            el: '#app',
            data: {
                searchText:''
            },
            //定义属性侦听器
            watch:{
                searchText(oldText,newText){
                    if(newText.length > 10){
                        alert('文本内容太长')
                    }
                }
            }
        })
    </script>

    <!--  Vue3.0写法  -->
    <script src="https://unpkg.com/vue@next"></script>
    <script>
        const obj  = {
            data(){
                return{
                    searchText:''
                }
            },
            //定义属性侦听器
            watch:{
                searchText(oldText,newText){
                    if(newText.length > 10){
                        alert('文本内容太长')
                    }
                }
            }
        }
        Vue.createApp(obj).mount('#app')
    </script>

案例:使用 watch 检测用户名是否可用
监听 username 值的变化,并使用 jquery  发起 Ajax 请求, 检测当前输入的用户名是否可 用:
    <div id="app">
        <input type="text" v-model="username">
    </div>

    <script src="./lib/jquery-v3.6.0.js"></script>

    <!--  Vue2.0写法  -->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14"></script>
    <script>
        const vm = new Vue({
            el: '#app',
            data: {
                username: ''
            },
            watch: {
                username(newVal) {
                    // 为了不让为空时报错,就在为空时return
                    if (newVal === '') return
                    // 调用 jQuery 中的 Ajax 发起请求,判断 newVal 是否被占用!!!
                    $.get('https://www.escook.cn/api/finduser/' + newVal, function (result) {
                        console.log(result)
                    })
                }
            }
        })
    </script>

    <!--  Vue3.0写法  -->
    <script src="https://unpkg.com/vue@next"></script>
    <script>
        const obj = {
            data() {
                return {
                    username: ''
                }
            },
            watch: {
                username(newVal) {
                    // 为了不让为空时报错,就在为空时return
                    if (newVal === '') return
                    // 调用 jQuery 中的 Ajax 发起请求,判断 newVal 是否被占用!!!
                    $.get('https://www.escook.cn/api/finduser/' + newVal, function (result) {
                        console.log(result)
                    })
                }
            }
        }
        Vue.createApp(obj).mount('#app')
    </script>

方法格式的监听器有两个缺点

  • 因为是函数,所以无法在刚进入页面的时候,自动触发,只有当值改变的时候才会执行。
  • 如果侦听的是一个对象,如果对象中的属性发生了变化,不会触发侦听器。

3.2 对象类型( 对象格式的侦听器):

const vm = new Vue({

    el: '#app' ,
    data: { username: '" },

    watch: {

        // 定义对象格式的侦听器:只要监听到了username变化就会自动触发handler函数

        username: {

          // 对象中有handler属性,即侦听器的处理函数

          handler(newVal, oldVal) {

            console.log(newVal, oldVal)

          }

        }

      }

})

对象格式的侦听器有两个优点

  • 可以通过immediate属性,控制侦听器自动触发一次(默认是false)
  • 可以 通过deep属性,控制侦听器深度监听到对象中每一个属性的变化。

① 如果我们想在第一次绑定的时候执行此监听函数 则需要 设置 immediate为true。

    <div id="app">
        <input type="text" v-model="username">
    </div>

    <script src="./lib/jquery-v3.6.0.js"></script>

    <!--  Vue2.0写法  -->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14"></script>
    <script>
        const vm = new Vue({
            el: '#app',
            data: {
                username: 'admin'
            },
            // 所有的侦听器,都应该被定义到 watch 节点下
            watch: {
                // 定义对象格式的侦听器:只要监听到了username变化就会自动触发handler函数
                username: {
                    // 对象中有handler属性,即侦听器的处理函数
                    // 写法一:推荐
                    handler(newVal, oldVal) {
                        console.log(newVal, oldVal)
                    },
                    // 写法二:
                    // handler:function(){}

                    // immediate 选项的默认值是 false
                    // immediate 的作用是:控制侦听器是否自动触发一次!
                    immediate: true
                }
            }
        })
    </script>

    <!--  Vue3.0写法  -->
    <script src="https://unpkg.com/vue@next"></script>
    <script>
        const obj = {
            data() {
                return {
                    username: 'admin'
                }
            },
            // 所有的侦听器,都应该被定义到 watch 节点下
            watch: {
                // 定义对象格式的侦听器:只要监听到了username变化就会自动触发handler函数
                username: {
                    // 对象中有handler属性,即侦听器的处理函数
                    // 写法一:推荐
                    handler(newVal, oldVal) {
                        console.log(newVal, oldVal)
                    },
                    // 写法二:
                    // handler:function(){}

                    // immediate 选项的默认值是 false
                    // immediate 的作用是:控制侦听器是否自动触发一次!
                    immediate: true
                }
            }
        }
        Vue.createApp(obj).mount('#app')
    </script>

② 当需要监听对象的改变时,此时就需要设置深度侦听deep为true

    <div id="app">
        <!-- 绑定在对象的属性上 -->
        <input type="text" v-model="info.username">
        <input type="text" v-model="info.address.city">
    </div>
    <script src="./lib/jquery-v3.6.0.js"></script>

    <!--  Vue2.0写法  -->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14"></script>
    <script>
        const vm = new Vue({
            el: '#app',
            data: {
                // 用户的信息对象
                info: {
                    username: 'admin',
                    address: {
                        city: '北京'
                    }
                }
            },
            // 所有的侦听器,都应该被定义到 watch 节点下
            watch: {
                // 1. 侦听的是对象所以得到的也是对象
                info: {
                    handler(newVal) {
                        console.log(newVal)
                    },
                    // 开启深度监听,只要对象中任何一个属性变化了,都会触发“对象的侦听器”
                    deep: true
                },

                // 2. 如果要侦听的是对象的子属性的变化,则必须包裹一层单引号
                'info.username'(newVal) {
                    console.log(newVal)
                }
            }
        })
    </script>


    <!--  Vue3.0写法  -->
    <script src="https://unpkg.com/vue@next"></script>
    <script>
        const obj = {
            data() {
                return {
                    // 用户的信息对象
                    info: {
                        username: 'admin',
                        address: {
                            city: '北京'
                        }
                    }
                }
            },
            // 所有的侦听器,都应该被定义到 watch 节点下
            watch: {
                // 1. 侦听的是对象所以得到的也是对象
                info: {
                    handler(newVal) {
                        console.log(newVal)
                    },
                    // 开启深度监听,只要对象中任何一个属性变化了,都会触发“对象的侦听器”
                    deep: true
                },

                // 2. 如果要侦听的是对象的子属性的变化,则必须包裹一层单引号
                'info.username'(newVal) {
                    console.log(newVal)
                }
            }
        }
        Vue.createApp(obj).mount('#app')
    </script>

4.定义方法的属性(methods)

在该属性下定义Vue组件的函数。

Vue自动为methods绑定this,以便于它始终指向组件实例。这将确保方法在用作事件监听或回调时保持正确的this指向。在定义methods 时应避免使用箭头函数,因为这会阻正Vue绑定恰当的this指向。
这些methods和组件实例的其它所有property一样可以在组件的模板中被访问。在模板中,它们通常被当做事件监听使用:
methods方法会每次在调用方法时候,都执行一次方法。

computed 属性和methods属性的区别:

computed 属性是vue的计算属性,是数据层到视图的数据转化映射;计算属性是基于他们的依赖进行缓存的,只有在相关依赖发现改变时,他们才会重新求值,也就是说,只要他的依赖没有发生变化,那么每次访问的时候计算属性都会立即返回之前的计算结果,不在执行函数。只要计算属性依赖的数据项不发生改变,计算属性只会执行一次,然而methods里的方法调用几次就执行几次。

computedmethods
computed 是响应式的methods并非响应式
调用方式不一样,computed定义的成员像属性一样访问methods定义的成员必须以函数形式调用
computed是带缓存的,只有依赖数据发生改变,才会重新进行计算methods里的函数在每次调用时都要执行
computed中的成员可以只定义一个函数作为只读属性,也可以定义get/set变成可读属性这点时methods中的成员做不到的
computed不支持异步当computed内有异步操作时无效,无法监听数据的变化可以异步

如果声明的计算属性计算量非常大的时候,而且访问量次数非常多,改变的时机却很小,那就需要用到computed;缓存会让我们减少很多计算量。

三、Vue组件的函数 

1.使用限流函数

1.1 限流

  • 场景1:点击按钮向服务器发起数据请求,在请求的数据回来之前多次单击按钮是无效的且会消耗资源。
  • 场景2:页面中某个按钮会导致页面的刷新,我们需要限制用户对该按钮进行频繁的操作。

        为了避免以上两种情况的发生,我们将使用Vue中的限流来解决该问题。

1.2 限流函数

        在指定的时间间隔内不允许重复执行同一个函数。

示例:页面中有一个按钮,单击按钮后在控制台输出当前的时间,要求这个按钮的两次事件触发间隔不能小于5秒。

<!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>
    <script src="https://unpkg.com/vue@next"></script>
</head>

<body>
    <div id="app">
        <!-- 给按钮绑定click事件 -->
        <button @click="myClick">按钮</button>
    </div>
    <script>
        // 当我们点击页面中的按钮时,会在终端打印出当前日期和时间,打印后的5s内我们多次点击按钮都不会执行打印操作,5s后则可以继续通过点击按钮来打印,依次循环
        const obj = {
            data() {
                return {
                    throttle: false
                }
            },
            methods: {
                myClick() {
                    if (!this.throttle) { //如果throttle取反为真,即为false时
                        console.log(Date()) //打印日期
                    } else {
                        return //不打印
                    }
                    this.throttle = true //设throttle为true
                    setTimeout(() => {
                        this.throttle = false //五秒钟后true变为false
                    }, 5000)
                }
            }
        }
        Vue.createApp(obj).mount("#app")
    </script>
</body>

</html>

封装:将限流的逻辑封装成单独的工具方法——一次编写多次使用 

<!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>
    <script src="https://unpkg.com/vue@next"></script>
</head>

<body>
    <div id="app">
        <button @click="myClick">按钮</button>
    </div>
    <script>
        var throttle = false
        function throttleTool(callback, timeout) { //throttleTool:限流的工具函数;callback:回调函数;timeout:时间限制
            if (!throttle) { //如果throttle取反为真,就调用回调函数
                callback() //主要业务(输出日期)放在此回调函数中
            } else {
                return
            }
            throttle = true
            setTimeout(() => {
                throttle = false
            }, timeout)
        }

        const obj = {
            data() {
                return {
                    throttle: false
                }
            },
            methods: {
                myClick() {
                    throttleTool(() => {
                        console.log(Date())
                    }, 2000)
                }
            }
        }
        Vue.createApp(obj).mount("#app")

    </script>
</body>

</html>

 2.使用Lodash库进行函数限流

是一款高性能的JavaScript实用工具库,提供了大量的数组、对象、字符串等边界的操作方法,使开发者更简单的使用JavaScript,在Lodash库中提供了debounce函数进行方法的限流。

<script src="https://unpkg.com/lodash@4.17.20/lodash.min.js"></script>

<!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>
    <script src="https://unpkg.com/vue@next"></script>
    <!--引入Lodash库-->
    <script src="https://unpkg.com/lodash@4.17.20/lodash.min.js"></script>

<body>
    <div id="app">
        <button @click="myClick">按钮</button>
    </div>
    <script>
        const obj = {
            data(){
                return{
                
                }
            },
            methods:{
                myClick:_.debounce(function(){
                    console.log(Date())
                },2000)
            }
        }
        Vue.createApp(obj).mount('#app')
    </script>
</body>
</html>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值