一、计算属性(data中的相关数据)

  侦听多个属性时——计算属性 comuted

  模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的。在模板中放入太多的逻辑会让模板过重且难以维护。例如:

  1. <body>
  2. <div id="computed">
  3. <div>
  4. {{msg.split('').reverse().join('')}}
  5. </div>
  6. </div>
  7. <script type="text/javascript" src="./vue.js"></script>
  8. <script type="text/javascript">
  9. var com = new Vue({
  10. el: "#computed",
  11. data:{
  12. msg:"Hello World"
  13. }
  14. })
  15. </script>
  16. </body>

  在这个地方,模板不再是简单的声明式逻辑。你必须看一段时间才能意识到,这里是想要显示变量 message 的翻转字符串。显示效果如下:

  

  当你想要在模板中多次引用此处的翻转字符串时,就会更加难以处理。

  所以,对于任何复杂逻辑,都应当使用计算属性

  1. <body>
  2. <div id="computed">
  3. <div>
  4. <!--{{msg.split('').reverse().join('')}}-->
  5. {{reverseStr}}
  6. </div>
  7. <button @click="clickHandler">修改</button>
  8. </div>
  9. <script type="text/javascript" src="./vue.js"></script>
  10. <script type="text/javascript">
  11. var com = new Vue({
  12. el: "#computed",
  13. data:{
  14. msg:"Hello World"
  15. },
  16. methods:{
  17. clickHandler(){
  18. this.msg = 'Hello Luffy'
  19. }
  20. },
  21. computed:{ // 计算属性: watch监听
  22. // 计算属性默认只有getter方法,因此必须return
  23. reverseStr(){
  24. return this.msg.split('').reverse().join('');
  25. }
  26. }
  27. })
  28. </script>
  29. </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

  1. <body>
  2. <div id="app">
  3. <h4>{{alexDesc}}</h4>
  4. <button @click="clickHandler">修改</button>
  5. </div>
  6. <script type="text/javascript" src="./vue.js"></script>
  7. <script type="text/javascript">
  8. new Vue({
  9. el:'#app',
  10. template:'',
  11. data(){
  12. return {
  13. myName:'alex',
  14. age:18
  15. }
  16. },
  17. methods:{
  18. clickHandler(){
  19. this.myName='WUSIR';
  20. this.age=28;
  21. }
  22. },
  23. computed:{
  24. alexDesc:function () {
  25. var str = `${this.myName}它的年龄是${this.age}
  26. 岁了可以去大保健了`;
  27. // 默认只有getter方法
  28. return str;
  29. }
  30. }
  31. })
  32. </script>
  33. </body>

(1)页面显示效果

  

(2)按钮点击后显示效果

  

(3)分析程序

  var str = `${this.myName}它的年龄是${this.age}   在实时监听data中声明的数据的变化。

  点击事件,对数据属性进行修改,由于计算属性的实时监听,就察觉了数据的修改。

  由于计算属性方法用模板插值关联,因此alexDesc函数的返回值就直接显示在模板中了。

  

2、计算属性的setter方法

  计算属性默认只有 getter ,不过在需要时也可以提供一个 setter 。

  1. <body>
  2. <div id="app">
  3. <h4>{{alexDesc}}</h4>
  4. <button @click="clickHandler">修改</button>
  5. </div>
  6. <script type="text/javascript" src="./vue.js"></script>
  7. <script type="text/javascript">
  8. new Vue({
  9. el:'#app',
  10. template:'',
  11. data(){
  12. return {
  13. myName:'alex',
  14. age:18
  15. }
  16. },
  17. methods:{
  18. clickHandler(){
  19. console.log(this.alexDesc);
  20. this.alexDesc = 'ALEX IS SB!!!';
  21. }
  22. },
  23. computed:{
  24. alexDesc:{
  25. // setter
  26. set:function (newValue) {
  27. console.log(newValue);
  28. this.myName = newValue;
  29. },
  30. // getter
  31. get:function(){
  32. var str = `${this.myName}它的年龄是${this.age}
  33. 岁了可以去大保健了`;
  34. return str;
  35. }
  36. }
  37. }
  38. })
  39. </script>
  40. </body>

(1)计算属性setter固定编写套路

  1. computed:{
  2. alexDesc:{
  3. // setter
  4. set:function (newValue) {
  5. console.log(newValue);
  6. this.myName = newValue;
  7. },
  8. // getter
  9. get:function(){
  10. var str = `${this.myName}它的年龄是${this.age}
  11. 岁了可以去大保健了`;
  12.  
  13. return str;
  14. }
  15. }
  16. }

(2)显示效果

  

(3)点击事件传值给计算属性setter方法

  

3、进一步理解setter用途

  1. <body>
  2. <div id="app">
  3. <input type="text" v-model="alexDesc">
  4. <h4>{{alexDesc}}</h4>
  5. <!--<button @click="clickHandler">修改</button>-->
  6. </div>
  7. <script type="text/javascript" src="./vue.js"></script>
  8. <script type="text/javascript">
  9. new Vue({
  10. el:'#app',
  11. template:'',
  12. data(){
  13. return {
  14. myName:'',
  15. }
  16. },
  17. computed:{
  18. alexDesc:{
  19. // setter,给myName赋新值
  20. set:function (newValue) {
  21. this.myName = newValue;
  22. },
  23. // getter,实时监听myName属性的变化
  24. get:function(){
  25. return this.myName;
  26. }
  27. }
  28. }
  29. })
  30. </script>
  31. </body>

  在input表单中输入信息,使用v-model进行双向数据绑定,使用setter给myName赋新值。getter监听myName属性的变化,并将值显示在 <h4>{{ alexDesc }} </h4>。

4、计算属性案例——音乐播放器

(1)构建音乐播放器页面

  <audio>标签是 HTML5 的新标签。<audio>标签定义声音,比如音乐或其他音频流。

  • autoplay属性:如果出现该属性,则音频在就绪后马上播放。
  • src属性:要播放音频的URL。
  • controls属性:如果出现该属性,则向用户显示控件,比如播放控件。
  • loop属性:如果出现该属性,则每当音频结束时重新开始播放。
  • muted属性:规定视频输出应该被静音。
  • preload属性:如果出现该属性,则音频在页面加载时进行加载,并预备播放。如果使用 "autoplay",则忽略该属性。
  1. <body>
  2. <div id="music">
  3. <audio src="../static/那吾克热-水滴石穿.mp3" controls=""
  4. autoplay=""></audio>
  5. <ul>
  6. <li v-for="(item, index) in musics">
  7. <h3>{{item.id}}--歌曲为:{{item.name}}</h3>
  8. <p>歌手:{{item.author}}</p>
  9. </li>
  10. </ul>
  11. </div>
  12. <script type="text/javascript" src="./vue.js"></script>
  13. <script type="text/javascript">
  14. var musicData = [{
  15. id:1,
  16. name:"那吾克热-水滴石穿",
  17. author:"那吾克热",
  18. songSrc:'../static/那吾克热-水滴石穿.mp3'
  19. },
  20. {
  21. id:2,
  22. name:"Inna-10 Minutes",
  23. author:"Inna",
  24. songSrc:'../static/10 Minutes.mp3'
  25. },
  26. {
  27. id:3,
  28. name:"Devotion-My_Prayer",
  29. author:"Devotion",
  30. songSrc:'../static/My_Prayer.mp3'
  31. }
  32. ];
  33.  
  34. new Vue({
  35. el:'#music',
  36. data(){
  37. return {
  38. musics:musicData
  39. }
  40. },
  41. template:''
  42. });
  43. </script>
  44. </body>

  显示效果:

  

(2)计算属性监听切换播放歌曲

  1. <body>
  2. <div id="music">
  3. <audio v-bind:src="currentSrc" controls=""
  4. autoplay=""></audio>
  5. <ul>
  6. <li v-for="(item, index) in musics" @click="clickHandler(index)"> <!--给每个li绑定点击事件-->
  7. <h3>{{item.id}}--歌曲为:{{item.name}}</h3>
  8. <p>歌手:{{item.author}}</p>
  9. </li>
  10. </ul>
  11. </div>
  12. <script type="text/javascript" src="./vue.js"></script>
  13. <script type="text/javascript">
  14. var musicData = [{
  15. id:1,
  16. name:"那吾克热-水滴石穿",
  17. author:"那吾克热",
  18. songSrc:'../static/那吾克热-水滴石穿.mp3'
  19. },
  20. {
  21. id:2,
  22. name:"Inna-10 Minutes",
  23. author:"Inna",
  24. songSrc:'../static/10 Minutes.mp3'
  25. },
  26. {
  27. id:3,
  28. name:"Devotion-My_Prayer",
  29. author:"Devotion",
  30. songSrc:'../static/My_Prayer.mp3'
  31. }
  32. ];
  33.  
  34. new Vue({
  35. el:'#music',
  36. data(){
  37. return {
  38. musics:musicData,
  39. musicSrc:'../static/那吾克热-水滴石穿.mp3'
  40. }
  41. },
  42. methods:{
  43. clickHandler(index){ // 声明点击事件
  44. // alert(index);
  45. this.musicSrc = this.musics[index].songSrc; // 获取数组musics中对应index的歌曲资源
  46.  
  47. }
  48. },
  49. computed:{
  50. currentSrc(){ // 实时监听musicSrc
  51. return this.musicSrc;
  52. }
  53. },
  54. template:''
  55. });
  56. </script>
  57. </body>

(3)不再监听musicSrc,改为监听musics数组

  1. <body>
  2. <div id="music">
  3. <audio v-bind:src="currentSrc" controls=""
  4. autoplay=""></audio>
  5. <ul>
  6. <li v-for="(item, index) in musics" @click="clickHandler(index)"> <!--给每个li绑定点击事件-->
  7. <h3>{{item.id}}--歌曲为:{{item.name}}</h3>
  8. <p>歌手:{{item.author}}</p>
  9. </li>
  10. </ul>
  11. </div>
  12. <script type="text/javascript" src="./vue.js"></script>
  13. <script type="text/javascript">
  14. var musicData = [{
  15. id:1,
  16. name:"那吾克热-水滴石穿",
  17. author:"那吾克热",
  18. songSrc:'../static/那吾克热-水滴石穿.mp3'
  19. },
  20. {
  21. id:2,
  22. name:"Inna-10 Minutes",
  23. author:"Inna",
  24. songSrc:'../static/10 Minutes.mp3'
  25. },
  26. {
  27. id:3,
  28. name:"Devotion-My_Prayer",
  29. author:"Devotion",
  30. songSrc:'../static/My_Prayer.mp3'
  31. }
  32. ];
  33.  
  34. new Vue({
  35. el:'#music',
  36. data(){
  37. return {
  38. musics:musicData,
  39. currentIndex:0
  40. // musicSrc:'../static/那吾克热-水滴石穿.mp3'
  41. }
  42. },
  43. methods:{
  44. clickHandler(index){ // 声明点击事件
  45. // alert(index);
  46. this.currentIndex = index; // 点击事件修改index
  47. }
  48. },
  49. computed:{
  50. currentSrc(){ // 实时监听了两个属性:musics、currentIndex
  51. return this.musics[this.currentIndex].songSrc // 修改的index会导致获取的歌曲资源不同
  52. }
  53. },
  54. template:''
  55. });
  56. </script>
  57. </body>

(4)添加点选切换样式

  1. <head>
  2. <meta charset="UTF-8">
  3. <title>Title</title>
  4. <style type="text/css">
  5. *{
  6. padding: 0;
  7. margin: 0;
  8. }
  9. ul{
  10. list-style: none;
  11. }
  12. ul li{
  13. margin: 30px 20px;
  14. padding: 10px;
  15. }
  16. ul li.active{
  17. background-color: #20FFFF;
  18. }
  19. </style>
  20. </head>
  21. <body>
  22. <div id="music">
  23. <audio v-bind:src="currentSrc" controls=""
  24. autoplay=""></audio>
  25. <ul>
  26. <li v-for="(item, index) in musics" @click="clickHandler(index)"
  27. :class="{active:currentIndex==index}"> <!--给当前歌曲li添加class=active-->
  28. <h3>{{item.id}}--歌曲为:{{item.name}}</h3>
  29. <p>歌手:{{item.author}}</p>
  30. </li>
  31. </ul>
  32. </div>
  33. <script type="text/javascript" src="./vue.js"></script>
  34. <script type="text/javascript">
  35. var musicData = [{
  36. id:1,
  37. name:"那吾克热-水滴石穿",
  38. author:"那吾克热",
  39. songSrc:'../static/那吾克热-水滴石穿.mp3'
  40. },
  41. {
  42. id:2,
  43. name:"Inna-10 Minutes",
  44. author:"Inna",
  45. songSrc:'../static/10 Minutes.mp3'
  46. },
  47. {
  48. id:3,
  49. name:"Devotion-My_Prayer",
  50. author:"Devotion",
  51. songSrc:'../static/My_Prayer.mp3'
  52. }
  53. ];
  54.  
  55. new Vue({
  56. el:'#music',
  57. data(){
  58. return {
  59. musics:musicData,
  60. currentIndex:0
  61. // musicSrc:'../static/那吾克热-水滴石穿.mp3'
  62. }
  63. },
  64. methods:{
  65. clickHandler(index){ // 声明点击事件
  66. // alert(index);
  67. this.currentIndex = index; // 点击事件修改index
  68. }
  69. },
  70. computed:{
  71. currentSrc(){ // 实时监听了两个属性:musics、currentIndex
  72. return this.musics[this.currentIndex].songSrc // 修改的index会导致获取的歌曲资源不同
  73. }
  74. },
  75. template:''
  76. });
  77. </script>
  78. </body>

  点击事件的时候修改currentIndex,自己的li标签监听currentIndex,修改为对应的标签,添加class=active,显示效果如下所示:

  

二、侦听器(watch)

  虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的侦听器。因此Vue 通过 watch 选项提供了一个更通用的方法,来响应数据的变化。当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。

1、简单侦听器示例

  1. <body>
  2. <div id="app">
  3. <input type="text" v-model="myName">
  4. <h3>{{myName}}</h3>
  5. </div>
  6. <script type="text/javascript" src="./vue.js"></script>
  7. <script type="text/javascript">
  8. new Vue({
  9. el:'#app',
  10. template:'',
  11. data(){
  12. return {
  13. myName:''
  14. }
  15. },
  16. watch:{
  17. // 检测单个属性 命令式
  18. myName:function (value) { // 通过watch来监听myName属性
  19. console.log(value);
  20. if (value === 'alex'){
  21. console.log(value+"是sb");
  22. }
  23. }
  24. }
  25. })
  26. </script>
  27. </body>

  通过watch来监听myName属性的变化,当属性值为alex时,控制台打印alex是sb。

  

2、结合其他属性一起检测

  1. <body>
  2. <div id="app">
  3. <input type="text" v-model="myName">
  4. <h3>{{myName}}</h3>
  5. </div>
  6. <script type="text/javascript" src="./vue.js"></script>
  7. <script type="text/javascript">
  8. new Vue({
  9. el:'#app',
  10. template:'',
  11. data(){
  12. return {
  13. myName:'',
  14. firstName:'wuSir'
  15. }
  16. },
  17. watch:{
  18. // 检测单个属性 命令式的
  19. myName:function (value) { // 通过watch来监听myName属性
  20. console.log(value);
  21. if (value === 'alex'){
  22. console.log(value + " " + this.firstName +"是sb");
  23. }
  24. }
  25. }
  26. })
  27. </script>
  28. </body>

  显示效果:

  

三、计算属性 vs 侦听属性 对比

  侦听器:侦听的是单个属性;

  计算属性:侦听多个属性;

  Vue 提供了一种更通用的方式来观察和响应 Vue 实例上的数据变动:侦听属性。当你有一些数据需要随着其它数据变动而变动时,你很容易滥用 watch——特别是如果你之前使用过 AngularJS。然而,通常更好的做法是使用计算属性而不是命令式的 watch 回调

1、命令式的 watch 回调

  添加按钮,并给按钮绑定事件:

  1. <body>
  2. <div id="app">
  3. <input type="text" v-model="myName">
  4. <h3>{{myName}}</h3>
  5. <button @click="clickHandler">修改</button>
  6. </div>
  7. <script type="text/javascript" src="./vue.js"></script>
  8. <script type="text/javascript">
  9. new Vue({
  10. el:'#app',
  11. template:'',
  12. data(){
  13. return {
  14. myName:'',
  15. firstName:'wuSir'
  16. }
  17. },
  18. methods:{
  19. clickHandler(){
  20. this.myName = '日天';
  21. }
  22. },
  23. watch:{
  24. // 检测单个属性 命令式的
  25. myName:function (value) { // 通过watch来监听myName属性
  26. console.log(value);
  27. if (value === 'alex'){
  28. console.log(value + " " + this.firstName +"是sb");
  29. }
  30. }
  31. }
  32. })
  33. </script>
  34. </body>

  点击按钮显示效果如下:

  

  可以看到控制台也输出“日天”,这个输出的语句是来自:console.log(value);

  如果将事件改为:this.myName = 'alex'; 则还会触发检测的if判断,显示效果如下所示:

  

2、计算属性版本

  上面的代码是命令式且重复的,将它与计算属性的版本进行比较:

  1. <body>
  2. <div id="app">
  3. <input type="text" v-model="myName">
  4. <h3>{{myName}}</h3>
  5. <button @click="clickHandler">修改</button>
  6. </div>
  7. <script type="text/javascript" src="./vue.js"></script>
  8. <script type="text/javascript">
  9. var vm = new Vue({
  10. el: '#app',
  11. data(){
  12. return{
  13. myName: '',
  14. firstName: 'wuSir',
  15. }
  16. },
  17. methods:{
  18. clickHandler(){
  19. this.myName = 'alex';
  20. }
  21. },
  22. computed: {
  23. fullName: function (value) { // 计算属性的名字不能与data中属性同名
  24. if (value === 'alex') {
  25. console.log(value + " " + this.firstName + "是sb!")
  26. }
  27. }
  28. }
  29. })
  30. </script>
  31. </body>

  修改为计算属性的版本,明显比上面命令式的要好得多。显示效果如下所示:

  

vue——计算属性和侦听器的更多相关文章

  1. Vue.js之Vue计算属性、侦听器、样式绑定

    前言 上一篇介绍了Vue的基本概念,这一篇介绍一下Vue的基本使用. 一.搭建一个Vue程序 1.1 搭建Vue环境 搭建Vue的开发环境总共有三种方法: 引入CDN <script src=& ...

  2. vue计算属性和侦听器

    一.计算属性: main.js: var app = new Vue({ el: '#app', data: { math: 80, physics: 90, english: 30 }, compu ...

  3. 15 Vue计算属性和侦听器

    计算属性 模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的. 在模板中放入太多的逻辑会让模板过重且难以维护.例如: split = 字符中间空格分割, reverse= 反转 join('' ...

  4. vue 计算属性与侦听器

    侦听器:顾名思义,就是用来监听数据变化用的.侦听器在vue实例中,定义变量watch来使用.监听新值newVal和旧值oldVal,具体使用方法如下: <!DOCTYPE html> &l ...

  5. Vue学习之vue中的计算属性和侦听器

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. 一起学Vue之计算属性和侦听器

    概述 在Vue开发中,模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的.在模板中放入太多的逻辑会让模板过重且难以维护.当你想要在模板中多次引用相同表达式时,就会更加难以处理.所以,对于任何复 ...

  7. Vue.js 生命周期、计算属性及侦听器

    一.创建一个Vue实例 每个Vue应用都是使用Vue函数创建一个Vue实例.所有的Vue组件都是一个Vue实例,并且接受相同的选项对象(一些根实例特有的选项除外). 数据和方法 当一个实例被创建后,它 ...

  8. 【Vue】Vue框架常用知识点 Vue的模板语法、计算属性与侦听器、条件渲染、列表渲染、Class与Style绑定介绍与基本的用法

    Vue框架常用知识点 文章目录 Vue框架常用知识点 知识点解释 第一个vue应用 模板语法 计算属性与侦听器 条件渲染.列表渲染.Class与Style绑定 知识点解释 vue框架知识体系 [1]基 ...

  9. VueJs(7)---计算属性和侦听器

    计算属性和侦听器 一. 概述 计算属性 模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的.在模板中放入太多的逻辑会让模板过重且难以维护.例如: <div id="exampl ...

随机推荐

  1. 设置placeholder的样式

    :-moz-placeholder { /* Mozilla Firefox 4 to 18 */ color: #f00; } ::-moz-placeholder { /* Mozilla Fir ...

  2. js自定义对象 (转)

    原文地址:https://sjolzy.cn/js-custom-object.html 29 March 2010 9:53 Monday by 小屋 javascript进阶之对象篇 一,概述 在 ...

  3. LCT小小结

    模板题P3690 基础题P3203[HNOI2010]弹飞绵羊 \(access\)是搞出一条端点为\(x,y\)的路径 , 且维护的是实子树的信息 . 由于题目比较简单 , \(access\)时还 ...

  4. 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 ...

  5. BZOJ - 2115 独立回路 线性基

    题意:给定一个图集\((V,E)\),求路径\(1...n\)的最大异或和,其中重复经过的部分也会重复异或 所求既任意一条\(1...n\)的路径的异或和,再异或上任意独立回路的组合的异或和(仔细想想 ...

  6. 【记录】SQL注入过滤源码分享

    $id=check_addslashes($_GET['id']);$id= preg_replace('/o*r/i',"", $id); //strip out OR (non ...

  7. oracle 基础知识(十三)----执行计划

    一, 执行计划是什么? 一条查询语句在ORACLE中的执行过程或访问路径的描述.即就是对一个查询任务,做出一份怎样去完成任务的详细方案. 二,执行计划的查看 设置autotrace 序号 命令 解释 ...

  8. CentOS 6.7 安装配置 nagios-server

    作者博文地址:https://www.cnblogs.com/liu-shuai/ 一.简介    Nagios是一款开源的免费网络监视工具,能有效监控Windows.Linux和Unix的主机状态, ...

  9. 昨天太晚了,今天教你用Debug模式来分析程序执行顺序

    还是以昨天的XML文件解析来做栗子,希望通过这个好吃的栗子可以举一反三 学会用debug来看源码和找Bug 事件类型主要有五种START_DOCUMENT:xml头的事件类型    = 0END_DO ...

  10. 使用jxl读取excel内容,并转换成Json,用于Datagrid

    一.上传excel文件,得到InputStream,由InputStream得到Jxl中的Workbook,取出内容,存到二维数组中. 1.使用 Jquery Uploadify 插件(http:// ...