Vuejs-学习记录(二)属性和计算属性

本文介绍了Vue.js中的属性(包括v-if/v-show的区别)、过滤器和计算属性的使用。详细讲解了计算属性的缓存机制、属性与方法的区别以及v-for遍历数据的注意事项,包括数组和对象的遍历以及如何根据需求选择使用对象数组。此外,还对比了计算属性和侦听属性的差异,帮助读者深入理解Vue.js的核心概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

属性(或指令)

v-show

根据条件的 boolean 值来切换元素的 CSS display 属性。

相对 v-if 来说

v-show 只是针对 display 属性,即该元素会始终被渲染,只是不一定会显示出来。

v-if 不同,它会根据条件决定是否会被创建-渲染或者销毁

v-html

官方说是只能按照普通 html 内容去插入,不会作为模版来编译。如果需要用v-html结合模版来使用,最好通过自定义组件形式来实现。

v-text

更新元素的 textContent 属性, 这种更新属于更新标签的整个文本内容。如果要局部更新需要用到插值

其实就是元素的文本节点内容。

v-once

数据只会在加载时更新,后面不会随数据变化而变化

用法:

<div id="example"><h1 v-once>{{a}}</h1></div>

对标签使用了 v-once 之后,在控制台改变 vm.a 的值,会发现 DOM 中显示的还是 vm.a 的初始值

v-model="attr"

数据模型,即双向绑定,和 v-bind 单向绑定不同,它不仅可以读取值还可以通过输入来修改属性值。

v-bind="value"v-bind:attr="value":attr="value"

单向绑定,一般可以绑定标签的一个内置属性(比如:title,鼠标放上去会出现被绑定的值,即双引号中的 value),不能直接修改绑定的属性值。

v-on:eventHandler

为元素绑定事件,比如 v-on:click="clickHandler" ,为元素绑定了个点击事件,事件处理函数为:clickHandler

v-if

条件属性,通过判断条件值来决定是否显示标签。

示例:点击按钮显示隐藏 div

tags:

// tags
<h1>条件属性:v-if</h1>
<button v-on:click="toggle">Show Message ?</button>
<p v-if="isToggle">I am showed !</p>

datas:

var data = { 

    isToggle: false,
};

methods:

// 方法
methods: {

    toggle: function () {
        this.isToggle = !this.isToggle;   
    },
}

通过点击按钮,调用 toggle 改变 isToggle 的值,然后 p 标签内使用 v-if 属性绑定 isToggle 属性。

v-elsev-else-if

if ... else ... 条件语句一样,承接 v-if 之后的 v-else;

即:v-if 不满足然后执行 v-else

如:(如果 num 大于 10 就显示红色背景div,否则显示蓝色背景div)


<h1>条件属性:v-if</h1>
<button v-on:click="toggle">Show Message ?</button>
<p v-if="isToggle">I am showed !</p><br/><br/>

<button v-on:click="changeBgNum">点我 {{bgNum}}</button><br/><br/>
<span v-if="bgNum === 1" style="background-color:red;color:white;">我是红色</span>
<span v-else-if="bgNum === 2" style="background-color:green;color:white;">我是绿色</span>
<span v-else style="background-color:blue;color:white;">我是蓝色</span><br/><br/>

数据:

var data = { 
    bgNum: 1,
}

方法:

// 方法
methods: {

    changeBgNum: function () {

        if ( this.bgNum++ === 3 ) {
            this.bgNum = 1;
            return;
        } 
    },
}

该例子是通过判断 this.bgNum 的值来决定显示哪种颜色的 div

1: 红色(默认)
2: 绿色
3: 蓝色

通过点击按钮来切换div

效果如图:

v-else-if v-else

PS: 使用v-else-ifv-else 的标签必须是紧跟的兄弟关系,即中间不能想跟其他标签。

v-for

遍历数据,来动态生成元素

数据类型可以是:数组,对象或基本类型数据。

使用方式:

  1. 数组元素是普通类型,这个时候单独改变数组成员的值不会引发 render,修改整个数组的时候会

    比如:人物列表一

    
    <h1>循环属性:v-for</h1>
    <label>数组数据列表:</label>
    <ul><li v-for="person in persons">{{person}}</li></ul>

    数据:

    data: {
        persons: ['Som', 'Bob', 'Coco'],
    }

    这样的话,控制台修改 vm.persons[0] = 'lizc' 的值,并不会触发 render

    但是整体修改数组会:vm.persons = ['a', 'b', 'c']

  2. 数组元素是对象类型,然后标签内引用对象的成员,单独改变这个成员的值的时候会触发 render

    比如:人物列表二

    
    <h1>循环属性:v-for</h1>
    <label>对象数据列表:</label>
    <ul><li v-for="people in peoples">{{people.name}}</li></ul>

    数据:

    
    var data = { 
    
        peoples: [
            {name: 'Tom'},
            {name: 'Lily'},
            {name: 'Simon'}
        ],
    
    };

    控制台修改成员值:

    vm.peoples[0].name = 'lizc'
    beforeUpdate
    updated
    "lizc"

    从控制输出可知,单独修改成员值可以触发 render,如上的 beforeUpdateupdated 就是更新了数据。

  3. 自定义组件形式

    // 自定义组件
    Vue.component('people-list', {
        props: ['people'],  // 组件接收到的属性
        template: '<li>{{people.name}}</li>' // 组件模版
    });

    标签:

    <h1>循环属性:v-for</h1>
    <label>自定义组件列表:</label>
    <ol><people-list v-for="people in peoples" v-bind:people="people"></people-list></ol>

    数据依旧使用 2 中的 peoples

    v-bind:people="people" 组件中的这个,是将组件 props 属性中的 people成员绑定到了前面v-for 中遍历用的 people 数据。

    v-bind:people 这个里面的people可以任意定义,只要跟组件内部的 props 属性中对应即可。

结论: 在使用 v-for 循环的时候,如果需要根据单个元素去重新render,要用对象数组形式,如果不需要只要普通类型元素的数组即可。


  • 在遍历数组的时候,还可以在遍历的时候指定索引值,比如:

    // 指定索引遍历
    <label>数组数据列表(指定索引):</label>
    <ul><li v-for="(person, index) in persons">{{person + ', ' + index}}</li></ul>

    结果:

    v-for-index

    名字后面的数字就是其在数组中对应的索引

  • 遍历对象,可以指定属性key, 值value, 以及索引index

    比如:(汽车的宽高和速度信息列表)

    
    <label>对象数据列表(指定键,值,索引):</label>
    <ul><li v-for="(value, key, index) in car">{{ '汽车参数' + key + ': ' + value + ', ' + index}}</li></ul>

    汽车参数:

    data: {
        car: {
            width: '180cm',
            height: '200cm',
            speed: '200km/h',
        },
    }

    结果:

    car attrs

    需要注意的是:(value, key, index),第一个是值不是键。

  • 唯一 key,排序

在使用 v-for 列表式数据的时候,如果需要排序,则需要主动指定一个 key 告诉 vue 需要根据这个属性去排序列表

比如:

有如下数据:

data: {
    students: [
        {name: 'Tom', id: '002'},
        {name: 'Dog', id: '004'},
        {name: 'Cat', id: '003'},
        {name: 'Tiger', id: '001'},
    ]
}

<ul><li v-for="stu in students" :key="stu.id"></li></ul>

然后会发现

过滤器

使用场景:(Vue 2.1.0 以上支持)

  1. 插值

{{ firstValue | secondValue }}

  1. v-bind 值中

v-bind:id="name | age"

计算属性

计算属性
new Vue({

    data: {
        message: 'hello vue.js !'
    },

    computed: {
        reverseMessage: function () {
            return this.reverseMessage.split('').reverse().join('');
        }
    }
});

标签使用:

<span>Reversed Message: {{ reverseMessage }}</span>

结果: Reversed Message: ! sj.euv olleh

计算属性的使用是为了避免插值中使用复杂的计算而导致难以维护。

使用计算属性可以将最终的结果值放入到插值中去显示

还可以通过 vm.reverseMessage 来直接调用获取其值,由于 compted:{}reverseMessage 的结果是与 vm.message 绑定的,因此只要message 发生变化其值也会立即发生变化。

计算缓存 vs Methods

组件中有个属性专门用来定义组件内所使用到的方法,即:methods,对象类型。

比如上面的例子:

new Vue({

    data: {
        message: 'hello vue.js !'
    },

    computed: {
        reverseMessage: function () {
            return this.reverseMessage.split('').reverse().join('');
        }
    },

    methods: {
        reverseMessage: function () {
            return this.reverseMessage.split('').reverse().join('');
        }
    },
});

然后通过直接调用函数方式:

<span>Reversed Message: {{ reverseMessage() }}</span>

同样可以达到与使用计算属性同样的效果。


计算属性和 methods 最大的区别就在于缓存机制

计算属性:会在每次调用 vm.reverseMessage 取值的时候,只要 vm.message 没有发生改变,就会立即返回之前计算过的值。

methods:每次调用函数都会返回实时的计算结果。

该区别在使用 Date 更新时间的时候最为明显:

比如:

computed: {
    reverseMessage: function () {
        return this.message.split('').reverse().join('');
    },

    cnow: function () {
        this.currTime = new Date(Date.now())
        return this.currTime;
    }
},

methods: {
    reverseMessage: function () {
        return this.message.split('').reverse().join('');
    },

    now: function () {
        return new Date(Date.now());
    }
},

标签:

<h1>计算属性 vs Methods</h1>
<label>计算属性:</label><span>{{ cnow }}</span><br/>
<label>Methods: </label><span>{{ now() }}</span><br/>

输出:

计算属性:"2017-05-04T03:24:19.991Z"
Methods: "2017-05-04T03:24:19.991Z"

这里输出都是一样的,可以到控制台验证下,在获取计算属性值和调用 methods 函数结果:

compted and methods

从结果图中可以知道在每次获取计算属性的时候都是之前计算过的值,而 methods 每次都会实时计算出最新的值返回。

其实这也好理解,计算属性毕竟是作为属性来使用,只要其依赖的数据没发生变化它也不应该会有所变化(虽然其实现还是以函数形式),而对于 methods 其实是以函数形式定义并以函数形式调用,既然每次都是函数调用形式去获取值,那肯定会每次调用都会重新计算得出最新值返回。

两者使用场景:

  1. 计算属性:可以应对大型数据计算并且一般不会发生变动的数据,这样就避免了每次想要获取需要经过大量计算而又不会经常发生变化的值导致的每次都需要重新计算,消耗性能;
  2. methods:适用于数据变化性比较大,经常变动的内容,也可替代计算属性来使用。
Computed 属性 vs Watched 属性

计算属性和观察属性区别在于,观察属性一次只能观察一个属性然后针对该属性的变化做出响应,而计算属性却不一样,它可以同时检测几个属性,通过这几个属性的值返回计算的结果。

比如:(分别通过观察属性和计算属性来实现:更新人物姓名)

  1. 观察属性:

    // 数据
    
    
    var data = { 
    
        firstName: 'li',
        lastName: 'zc',
        fullName: 'lizc',
    };

    观察:

    
    // 观察属性,观察的属性发生变化,会做出响应(比如:改变其他属性的值)
    watch: {
        firstName: function (newValue) {
            console.log('firstName ---------- new: ' + newValue);
            this.fullName = newValue + ' ' + this.lastName; 
        },
    
        lastName: function (newValue) {
            console.log('lastName ---------- new: ' + newValue);
            this.fullName = this.firstName + ' ' + newValue;
        },
    },

    这里对 firstNamelastName 分别进行了观察,一旦有改变发生,就会去更新全名:fullName 值;

  2. 计算属性

    通过计算属性的特性:只要被绑定的属性值不发生变化计算结果就不会变,被绑定的属性发生变化计算结果会根据变化后的最新值去计算最新的结果。

    可以更方便的去实现上面通过 watch 属性来刷新全名的功能。

    // 数据
    var data = { 
    
        firstName: 'li',
        lastName: 'zc',
        // fullName: 'lizc', 这里就不需要设置这个属性了,直接从计算属性结果中获取
    };

    计算属性:

    // 计算属性,只要绑定的属性不变,会先使用缓存的值
    computed: {
    
        fullName: function () {
            return this.firstName + ' ' + this.lastName;
        },
    },

最后两者通用的标签书写方式:

<h1>Compted 属性 vs Watched 属性</h1>
<label>Fist Name: </label><input type="text" v-model="firstName"><br/>
<label>Last Name: </label><input type="text" v-model="lastName"><br/>
<label>计算属性:</label><span>{{ fullName }}</span><br/>
<label>观察属性:</label><span>{{ fullName }}</span><br/>

上面的计算和观察属性中的 fullName 有所不同

前者标签内的 fullName 插值使用的是 compted 属性中的 fullName

后者标签内的 fullName 插值使用的是 data 数据中的 fullName 属性;

最终结果其实都是一样的,见效果图:

compted and watched

计算属性的 setter

默认情况下计算属性是只有 getter 的,但是我们可以自己添加 setter

比如:

需要注意的是,这里 fullName 不能再是函数声明形式了,而需要采用对象方式

// 为计算属性添加 setter 
fullName: { // fullName: function (){} => fullName: {}


    get: function () {
        return this.firstName + ' ' + this.lastName;
    },

     set: function (newValue) {
        var name = newValue.split(' ');

        this.firstName = name[0];
        this.lastName = name[name.length - 1];
     }


    // return this.firstName + ' ' + this.lastName;
},

这样我们也可以通过 vm.fullName = 'li zc 方式去修改绑定的属性了。

setter 里面可以做一些自定义的需求等等。

总结

本篇主要涉及 Vue.js 中的一些主要属性(比如:v-bind, v-model, v-if, v-for, v-on 等等),以及计算属性与观察属性的概念和用法。

回顾:

  • 计算属性

    会缓存结果,只要被绑定的属性值没变,多次调用计算属性获取值得到的结果都是被绑定的属性最后发生改变的那个值。

    默认没有 setter,可以自定义,注意自定义的时候需要以对象形式出现,比如:

    var vm = new Vue({
    
        data: { name: 'lizc' },
    
        computed: {
    
            // 这是只有 getter 的情况
            myName: function () {
                return this.name;
            },
    
            // 自定义 setter 情况
            youName: {
                get: function () {
                    return this.name;
                },
    
                // 有了这个之后就可以通过 vm.youName = 'Tom'
                // 去改变计算属性的值,而这个 set 里面又是绑定了 this.name,
                // 因此在修改这个计算属性的时候也会触发绑定了 this.name 的组件刷新 UI
                set: function (newVaule) {
                    this.name = newVaule;
                }
            }
        }
    });

    计算属性有个好处就是,可以同时检测多个属性并且可以根据这多个属性通过一定方式计算得出结果。

  • 观察属性

    观察属性,是针对单个属性进行观察,一旦有值变化会做出相应的响应。

    使用方式:

    new Vue({
    
        data: {
            name: 'lizc',
            age: '30',
        },
    
        watch: {
            name: function () {  // do sth },
    
            age: function () { // do sth },
        }
    });
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

若叶岂知秋vip

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值