vue——计算属性和侦听器
一、计算属性(data中的相关数据)
侦听多个属性时——计算属性 comuted。
模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的。在模板中放入太多的逻辑会让模板过重且难以维护。例如:
- <body>
- <div id="computed">
- <div>
- {{msg.split('').reverse().join('')}}
- </div>
- </div>
- <script type="text/javascript" src="./vue.js"></script>
- <script type="text/javascript">
- var com = new Vue({
- el: "#computed",
- data:{
- msg:"Hello World"
- }
- })
- </script>
- </body>
在这个地方,模板不再是简单的声明式逻辑。你必须看一段时间才能意识到,这里是想要显示变量 message
的翻转字符串。显示效果如下:
当你想要在模板中多次引用此处的翻转字符串时,就会更加难以处理。
所以,对于任何复杂逻辑,都应当使用计算属性。
- <body>
- <div id="computed">
- <div>
- <!--{{msg.split('').reverse().join('')}}-->
- {{reverseStr}}
- </div>
- <button @click="clickHandler">修改</button>
- </div>
- <script type="text/javascript" src="./vue.js"></script>
- <script type="text/javascript">
- var com = new Vue({
- el: "#computed",
- data:{
- msg:"Hello World"
- },
- methods:{
- clickHandler(){
- this.msg = 'Hello Luffy'
- }
- },
- computed:{ // 计算属性: watch监听
- // 计算属性默认只有getter方法,因此必须return
- reverseStr(){
- return this.msg.split('').reverse().join('');
- }
- }
- })
- </script>
- </body>
当我点击按钮的时候更改了当前的数据,同时h3和p标签中数据也随时改变。
(1)为什么会这样呢?
因为Vue知道com.currentMsg依赖与com.msg,因此当com.msg发生改变时,所有依赖com.currentMsg的绑定也会更新。而且最妙的是我们已经以声明的方式创建了这种依赖关系。:计算属性的getter函数是没有副作用的,这使它更易于测试和理解。
(2)同样的上面操作,我们不用computed声明的计算属性方法,而仅仅通过methods中声明的方法也能完成上面的效果,那么为什么又要使用computed方法呢?
因为计算属性是基于它们的依赖进行缓存的。计算属性只有在它的相关依赖发生改变时才会重新求值。这就意味着只要msg还没有发生变化,多次访问currentMsg计算属性会立刻返回之前计算的结果,而不比再次执行函数。同样的。每当触发重新渲染时,调用方法将总会执行函数。
(3)我们为什么需要缓存?
假设我们有一个性能开销比较大的的计算属性 A,它需要遍历一个巨大的数组并做大量的计算。然后我们可能有其他的计算属性依赖于 A 。如果没有缓存,我们将不可避免的多次执行 A 的 getter!如果你不希望有缓存,请用方法来替代。
1、计算属性之computed
- <body>
- <div id="app">
- <h4>{{alexDesc}}</h4>
- <button @click="clickHandler">修改</button>
- </div>
- <script type="text/javascript" src="./vue.js"></script>
- <script type="text/javascript">
- new Vue({
- el:'#app',
- template:'',
- data(){
- return {
- myName:'alex',
- age:18
- }
- },
- methods:{
- clickHandler(){
- this.myName='WUSIR';
- this.age=28;
- }
- },
- computed:{
- alexDesc:function () {
- var str = `${this.myName}它的年龄是${this.age}
- 岁了可以去大保健了`;
- // 默认只有getter方法
- return str;
- }
- }
- })
- </script>
- </body>
(1)页面显示效果
(2)按钮点击后显示效果
(3)分析程序
var str = `${this.myName}它的年龄是${this.age} 在实时监听data中声明的数据的变化。
点击事件,对数据属性进行修改,由于计算属性的实时监听,就察觉了数据的修改。
由于计算属性方法用模板插值关联,因此alexDesc函数的返回值就直接显示在模板中了。
2、计算属性的setter方法
计算属性默认只有 getter ,不过在需要时也可以提供一个 setter 。
- <body>
- <div id="app">
- <h4>{{alexDesc}}</h4>
- <button @click="clickHandler">修改</button>
- </div>
- <script type="text/javascript" src="./vue.js"></script>
- <script type="text/javascript">
- new Vue({
- el:'#app',
- template:'',
- data(){
- return {
- myName:'alex',
- age:18
- }
- },
- methods:{
- clickHandler(){
- console.log(this.alexDesc);
- this.alexDesc = 'ALEX IS SB!!!';
- }
- },
- computed:{
- alexDesc:{
- // setter
- set:function (newValue) {
- console.log(newValue);
- this.myName = newValue;
- },
- // getter
- get:function(){
- var str = `${this.myName}它的年龄是${this.age}
- 岁了可以去大保健了`;
- return str;
- }
- }
- }
- })
- </script>
- </body>
(1)计算属性setter固定编写套路
- computed:{
- alexDesc:{
- // setter
- set:function (newValue) {
- console.log(newValue);
- this.myName = newValue;
- },
- // getter
- get:function(){
- var str = `${this.myName}它的年龄是${this.age}
- 岁了可以去大保健了`;
- return str;
- }
- }
- }
(2)显示效果
(3)点击事件传值给计算属性setter方法
3、进一步理解setter用途
- <body>
- <div id="app">
- <input type="text" v-model="alexDesc">
- <h4>{{alexDesc}}</h4>
- <!--<button @click="clickHandler">修改</button>-->
- </div>
- <script type="text/javascript" src="./vue.js"></script>
- <script type="text/javascript">
- new Vue({
- el:'#app',
- template:'',
- data(){
- return {
- myName:'',
- }
- },
- computed:{
- alexDesc:{
- // setter,给myName赋新值
- set:function (newValue) {
- this.myName = newValue;
- },
- // getter,实时监听myName属性的变化
- get:function(){
- return this.myName;
- }
- }
- }
- })
- </script>
- </body>
在input表单中输入信息,使用v-model进行双向数据绑定,使用setter给myName赋新值。getter监听myName属性的变化,并将值显示在 <h4>{{ alexDesc }} </h4>。
4、计算属性案例——音乐播放器
(1)构建音乐播放器页面
<audio>标签是 HTML5 的新标签。<audio>标签定义声音,比如音乐或其他音频流。
- autoplay属性:如果出现该属性,则音频在就绪后马上播放。
- src属性:要播放音频的URL。
- controls属性:如果出现该属性,则向用户显示控件,比如播放控件。
- loop属性:如果出现该属性,则每当音频结束时重新开始播放。
- muted属性:规定视频输出应该被静音。
- preload属性:如果出现该属性,则音频在页面加载时进行加载,并预备播放。如果使用 "autoplay",则忽略该属性。
- <body>
- <div id="music">
- <audio src="../static/那吾克热-水滴石穿.mp3" controls=""
- autoplay=""></audio>
- <ul>
- <li v-for="(item, index) in musics">
- <h3>{{item.id}}--歌曲为:{{item.name}}</h3>
- <p>歌手:{{item.author}}</p>
- </li>
- </ul>
- </div>
- <script type="text/javascript" src="./vue.js"></script>
- <script type="text/javascript">
- var musicData = [{
- id:1,
- name:"那吾克热-水滴石穿",
- author:"那吾克热",
- songSrc:'../static/那吾克热-水滴石穿.mp3'
- },
- {
- id:2,
- name:"Inna-10 Minutes",
- author:"Inna",
- songSrc:'../static/10 Minutes.mp3'
- },
- {
- id:3,
- name:"Devotion-My_Prayer",
- author:"Devotion",
- songSrc:'../static/My_Prayer.mp3'
- }
- ];
- new Vue({
- el:'#music',
- data(){
- return {
- musics:musicData
- }
- },
- template:''
- });
- </script>
- </body>
显示效果:
(2)计算属性监听切换播放歌曲
- <body>
- <div id="music">
- <audio v-bind:src="currentSrc" controls=""
- autoplay=""></audio>
- <ul>
- <li v-for="(item, index) in musics" @click="clickHandler(index)"> <!--给每个li绑定点击事件-->
- <h3>{{item.id}}--歌曲为:{{item.name}}</h3>
- <p>歌手:{{item.author}}</p>
- </li>
- </ul>
- </div>
- <script type="text/javascript" src="./vue.js"></script>
- <script type="text/javascript">
- var musicData = [{
- id:1,
- name:"那吾克热-水滴石穿",
- author:"那吾克热",
- songSrc:'../static/那吾克热-水滴石穿.mp3'
- },
- {
- id:2,
- name:"Inna-10 Minutes",
- author:"Inna",
- songSrc:'../static/10 Minutes.mp3'
- },
- {
- id:3,
- name:"Devotion-My_Prayer",
- author:"Devotion",
- songSrc:'../static/My_Prayer.mp3'
- }
- ];
- new Vue({
- el:'#music',
- data(){
- return {
- musics:musicData,
- musicSrc:'../static/那吾克热-水滴石穿.mp3'
- }
- },
- methods:{
- clickHandler(index){ // 声明点击事件
- // alert(index);
- this.musicSrc = this.musics[index].songSrc; // 获取数组musics中对应index的歌曲资源
- }
- },
- computed:{
- currentSrc(){ // 实时监听musicSrc
- return this.musicSrc;
- }
- },
- template:''
- });
- </script>
- </body>
(3)不再监听musicSrc,改为监听musics数组
- <body>
- <div id="music">
- <audio v-bind:src="currentSrc" controls=""
- autoplay=""></audio>
- <ul>
- <li v-for="(item, index) in musics" @click="clickHandler(index)"> <!--给每个li绑定点击事件-->
- <h3>{{item.id}}--歌曲为:{{item.name}}</h3>
- <p>歌手:{{item.author}}</p>
- </li>
- </ul>
- </div>
- <script type="text/javascript" src="./vue.js"></script>
- <script type="text/javascript">
- var musicData = [{
- id:1,
- name:"那吾克热-水滴石穿",
- author:"那吾克热",
- songSrc:'../static/那吾克热-水滴石穿.mp3'
- },
- {
- id:2,
- name:"Inna-10 Minutes",
- author:"Inna",
- songSrc:'../static/10 Minutes.mp3'
- },
- {
- id:3,
- name:"Devotion-My_Prayer",
- author:"Devotion",
- songSrc:'../static/My_Prayer.mp3'
- }
- ];
- new Vue({
- el:'#music',
- data(){
- return {
- musics:musicData,
- currentIndex:0
- // musicSrc:'../static/那吾克热-水滴石穿.mp3'
- }
- },
- methods:{
- clickHandler(index){ // 声明点击事件
- // alert(index);
- this.currentIndex = index; // 点击事件修改index
- }
- },
- computed:{
- currentSrc(){ // 实时监听了两个属性:musics、currentIndex
- return this.musics[this.currentIndex].songSrc // 修改的index会导致获取的歌曲资源不同
- }
- },
- template:''
- });
- </script>
- </body>
(4)添加点选切换样式
- <head>
- <meta charset="UTF-8">
- <title>Title</title>
- <style type="text/css">
- *{
- padding: 0;
- margin: 0;
- }
- ul{
- list-style: none;
- }
- ul li{
- margin: 30px 20px;
- padding: 10px;
- }
- ul li.active{
- background-color: #20FFFF;
- }
- </style>
- </head>
- <body>
- <div id="music">
- <audio v-bind:src="currentSrc" controls=""
- autoplay=""></audio>
- <ul>
- <li v-for="(item, index) in musics" @click="clickHandler(index)"
- :class="{active:currentIndex==index}"> <!--给当前歌曲li添加class=active-->
- <h3>{{item.id}}--歌曲为:{{item.name}}</h3>
- <p>歌手:{{item.author}}</p>
- </li>
- </ul>
- </div>
- <script type="text/javascript" src="./vue.js"></script>
- <script type="text/javascript">
- var musicData = [{
- id:1,
- name:"那吾克热-水滴石穿",
- author:"那吾克热",
- songSrc:'../static/那吾克热-水滴石穿.mp3'
- },
- {
- id:2,
- name:"Inna-10 Minutes",
- author:"Inna",
- songSrc:'../static/10 Minutes.mp3'
- },
- {
- id:3,
- name:"Devotion-My_Prayer",
- author:"Devotion",
- songSrc:'../static/My_Prayer.mp3'
- }
- ];
- new Vue({
- el:'#music',
- data(){
- return {
- musics:musicData,
- currentIndex:0
- // musicSrc:'../static/那吾克热-水滴石穿.mp3'
- }
- },
- methods:{
- clickHandler(index){ // 声明点击事件
- // alert(index);
- this.currentIndex = index; // 点击事件修改index
- }
- },
- computed:{
- currentSrc(){ // 实时监听了两个属性:musics、currentIndex
- return this.musics[this.currentIndex].songSrc // 修改的index会导致获取的歌曲资源不同
- }
- },
- template:''
- });
- </script>
- </body>
点击事件的时候修改currentIndex,自己的li标签监听currentIndex,修改为对应的标签,添加class=active,显示效果如下所示:
二、侦听器(watch)
虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的侦听器。因此Vue 通过 watch
选项提供了一个更通用的方法,来响应数据的变化。当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。
1、简单侦听器示例
- <body>
- <div id="app">
- <input type="text" v-model="myName">
- <h3>{{myName}}</h3>
- </div>
- <script type="text/javascript" src="./vue.js"></script>
- <script type="text/javascript">
- new Vue({
- el:'#app',
- template:'',
- data(){
- return {
- myName:''
- }
- },
- watch:{
- // 检测单个属性 命令式
- myName:function (value) { // 通过watch来监听myName属性
- console.log(value);
- if (value === 'alex'){
- console.log(value+"是sb");
- }
- }
- }
- })
- </script>
- </body>
通过watch来监听myName属性的变化,当属性值为alex时,控制台打印alex是sb。
2、结合其他属性一起检测
- <body>
- <div id="app">
- <input type="text" v-model="myName">
- <h3>{{myName}}</h3>
- </div>
- <script type="text/javascript" src="./vue.js"></script>
- <script type="text/javascript">
- new Vue({
- el:'#app',
- template:'',
- data(){
- return {
- myName:'',
- firstName:'wuSir'
- }
- },
- watch:{
- // 检测单个属性 命令式的
- myName:function (value) { // 通过watch来监听myName属性
- console.log(value);
- if (value === 'alex'){
- console.log(value + " " + this.firstName +"是sb");
- }
- }
- }
- })
- </script>
- </body>
显示效果:
三、计算属性 vs 侦听属性 对比
侦听器:侦听的是单个属性;
计算属性:侦听多个属性;
Vue 提供了一种更通用的方式来观察和响应 Vue 实例上的数据变动:侦听属性。当你有一些数据需要随着其它数据变动而变动时,你很容易滥用 watch
——特别是如果你之前使用过 AngularJS。然而,通常更好的做法是使用计算属性而不是命令式的 watch
回调。
1、命令式的 watch 回调
添加按钮,并给按钮绑定事件:
- <body>
- <div id="app">
- <input type="text" v-model="myName">
- <h3>{{myName}}</h3>
- <button @click="clickHandler">修改</button>
- </div>
- <script type="text/javascript" src="./vue.js"></script>
- <script type="text/javascript">
- new Vue({
- el:'#app',
- template:'',
- data(){
- return {
- myName:'',
- firstName:'wuSir'
- }
- },
- methods:{
- clickHandler(){
- this.myName = '日天';
- }
- },
- watch:{
- // 检测单个属性 命令式的
- myName:function (value) { // 通过watch来监听myName属性
- console.log(value);
- if (value === 'alex'){
- console.log(value + " " + this.firstName +"是sb");
- }
- }
- }
- })
- </script>
- </body>
点击按钮显示效果如下:
可以看到控制台也输出“日天”,这个输出的语句是来自:console.log(value);
如果将事件改为:this.myName = 'alex'; 则还会触发检测的if判断,显示效果如下所示:
2、计算属性版本
上面的代码是命令式且重复的,将它与计算属性的版本进行比较:
- <body>
- <div id="app">
- <input type="text" v-model="myName">
- <h3>{{myName}}</h3>
- <button @click="clickHandler">修改</button>
- </div>
- <script type="text/javascript" src="./vue.js"></script>
- <script type="text/javascript">
- var vm = new Vue({
- el: '#app',
- data(){
- return{
- myName: '',
- firstName: 'wuSir',
- }
- },
- methods:{
- clickHandler(){
- this.myName = 'alex';
- }
- },
- computed: {
- fullName: function (value) { // 计算属性的名字不能与data中属性同名
- if (value === 'alex') {
- console.log(value + " " + this.firstName + "是sb!")
- }
- }
- }
- })
- </script>
- </body>
修改为计算属性的版本,明显比上面命令式的要好得多。显示效果如下所示:
vue——计算属性和侦听器的更多相关文章
- Vue.js之Vue计算属性、侦听器、样式绑定
前言 上一篇介绍了Vue的基本概念,这一篇介绍一下Vue的基本使用. 一.搭建一个Vue程序 1.1 搭建Vue环境 搭建Vue的开发环境总共有三种方法: 引入CDN <script src=& ...
- vue计算属性和侦听器
一.计算属性: main.js: var app = new Vue({ el: '#app', data: { math: 80, physics: 90, english: 30 }, compu ...
- 15 Vue计算属性和侦听器
计算属性 模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的. 在模板中放入太多的逻辑会让模板过重且难以维护.例如: split = 字符中间空格分割, reverse= 反转 join('' ...
- vue 计算属性与侦听器
侦听器:顾名思义,就是用来监听数据变化用的.侦听器在vue实例中,定义变量watch来使用.监听新值newVal和旧值oldVal,具体使用方法如下: <!DOCTYPE html> &l ...
- Vue学习之vue中的计算属性和侦听器
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 一起学Vue之计算属性和侦听器
概述 在Vue开发中,模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的.在模板中放入太多的逻辑会让模板过重且难以维护.当你想要在模板中多次引用相同表达式时,就会更加难以处理.所以,对于任何复 ...
- Vue.js 生命周期、计算属性及侦听器
一.创建一个Vue实例 每个Vue应用都是使用Vue函数创建一个Vue实例.所有的Vue组件都是一个Vue实例,并且接受相同的选项对象(一些根实例特有的选项除外). 数据和方法 当一个实例被创建后,它 ...
- 【Vue】Vue框架常用知识点 Vue的模板语法、计算属性与侦听器、条件渲染、列表渲染、Class与Style绑定介绍与基本的用法
Vue框架常用知识点 文章目录 Vue框架常用知识点 知识点解释 第一个vue应用 模板语法 计算属性与侦听器 条件渲染.列表渲染.Class与Style绑定 知识点解释 vue框架知识体系 [1]基 ...
- VueJs(7)---计算属性和侦听器
计算属性和侦听器 一. 概述 计算属性 模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的.在模板中放入太多的逻辑会让模板过重且难以维护.例如: <div id="exampl ...
随机推荐
- 设置placeholder的样式
:-moz-placeholder { /* Mozilla Firefox 4 to 18 */ color: #f00; } ::-moz-placeholder { /* Mozilla Fir ...
- js自定义对象 (转)
原文地址:https://sjolzy.cn/js-custom-object.html 29 March 2010 9:53 Monday by 小屋 javascript进阶之对象篇 一,概述 在 ...
- LCT小小结
模板题P3690 基础题P3203[HNOI2010]弹飞绵羊 \(access\)是搞出一条端点为\(x,y\)的路径 , 且维护的是实子树的信息 . 由于题目比较简单 , \(access\)时还 ...
- Magic Odd Square (思维+构造)
Find an n × n matrix with different numbers from 1 to n2, so the sum in each row, column and both ma ...
- BZOJ - 2115 独立回路 线性基
题意:给定一个图集\((V,E)\),求路径\(1...n\)的最大异或和,其中重复经过的部分也会重复异或 所求既任意一条\(1...n\)的路径的异或和,再异或上任意独立回路的组合的异或和(仔细想想 ...
- 【记录】SQL注入过滤源码分享
$id=check_addslashes($_GET['id']);$id= preg_replace('/o*r/i',"", $id); //strip out OR (non ...
- oracle 基础知识(十三)----执行计划
一, 执行计划是什么? 一条查询语句在ORACLE中的执行过程或访问路径的描述.即就是对一个查询任务,做出一份怎样去完成任务的详细方案. 二,执行计划的查看 设置autotrace 序号 命令 解释 ...
- CentOS 6.7 安装配置 nagios-server
作者博文地址:https://www.cnblogs.com/liu-shuai/ 一.简介 Nagios是一款开源的免费网络监视工具,能有效监控Windows.Linux和Unix的主机状态, ...
- 昨天太晚了,今天教你用Debug模式来分析程序执行顺序
还是以昨天的XML文件解析来做栗子,希望通过这个好吃的栗子可以举一反三 学会用debug来看源码和找Bug 事件类型主要有五种START_DOCUMENT:xml头的事件类型 = 0END_DO ...
- 使用jxl读取excel内容,并转换成Json,用于Datagrid
一.上传excel文件,得到InputStream,由InputStream得到Jxl中的Workbook,取出内容,存到二维数组中. 1.使用 Jquery Uploadify 插件(http:// ...