Vue学习(基础)

MVVM模型


MVVM是Model-View-ViewModel的缩写。

  • Model:代表数据模型,也可以在Model中定义数据修改和操作的业务逻辑;
  • View:代表UI 组件,它负责将数据模型转化成UI 展现出来;
  • ViewModel:是一个同步View 和 Model的对象。

在MVVM架构下,View 和 Model 之间并没有直接的联系,而是通过ViewModel进行交互,Model 和 ViewModel 之间的交互是双向的, 因此View 数据的变化会同步到Model中,而Model 数据的变化也会立即反应到View 上。
ViewModel 通过双向数据绑定把 View 层和 Model 层连接了起来,而View 和 Model 之间的同步工作完全是自动的,无需人为干涉,因此开发者只需关注业务逻辑,不需要手动操作DOM, 不需要关注数据状态的同步问题,复杂的数据状态维护完全由 MVVM 来统一管理。

Vue.js的优点


  • 低耦合:视图(View)可以独立于Model变化和修改,一个ViewModel可以绑定到不同的"View"上,当View变化的时候Model可以不变,当Model变化的时候View也可以不变。
  • 可重用性:可以把一些视图逻辑放在一个ViewModel里面,让很多view重用这段视图逻辑。
  • 独立开发:开发人员可以专注于业务逻辑和数据的开发(ViewModel),设计人员可以专注于页面设计。
  • 可测试性:界面素来是比较难于测试的,而现在测试可以针对ViewModel来写。

指令和事件


指令(Directives)是Vue模板中最常用的一项功能,它带有前缀v-,能帮我们快速完成DOM操作、循环渲染、显示影藏。

  • v-text:解析文本,作用与{{}}一样
  • v-html:解析html
  • v-bind:基本用途是动态更新HTML元素上的属性,如id、class等,可用:代替
  • v-on:用来绑定事件监听器,可用@代替

v-on具体介绍

在普通元素中,v-on可以监听原生的DOM事件,除了click以外,还有dbclick、keyup、mousemove等。表达式可以是一个方法名,这些方法都写在Vue实例的methods属性内,并且是函数的形式,函数内的this指向的是当前Vue实例本身,因此可以直接使用this.xxx的形式来访问或修改数据。

代码实战

要求:

  1. 渲染文本到页面
  2. 渲染HTML到页面
  3. 动态绑定属性(任意属性均可)
  4. 绑定一个事件
  5. 必须使用到过滤器

代码预览

Vue计算属性


一、字符翻转实例

创建以一个vue实例,并使用计算属性和方法实现一个字符串翻转的操作,写出核心代码:

<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
  <div id="app">
    <p>初始字符:{{number}}</p>
    <p>方法反转:{{reverseNumber2()}}</p>
    <p>计算属性反转:{{reverseNumber}}</p>
    <p>模板内表达式反转:{{number.split(', ').reverse().join(', ')}}</p>
  </div>
<script>
  var app1 = new Vue({
    el: '#app',
    data: {
      number: '123, 456, 789',
      lastName: 'He',
      fullName: 'Wang He'
    },
    computed: {
      reverseNumber: function(){
        return this.number.split(', ').reverse().join(', ')
      }
    },
    methods: {
      reverseNumber2: function(){
        return this.number.split(', ').reverse().join(', ')
      }
    }
  })
</script>
</body>
</html>

预览链接

二、何时使用模板内表达式,何时使用计算属性?

  • 模板内表达式:只支持单行表达式,适用于简单计算
  • 计算属性:适用于复杂逻辑计算

三、计算属性与方法(methods)的区别

计算属性与方法呈现的最终结果相同,然而不同的是,计算属性是基于它们的依赖进行缓存的,只有相关依赖发生变化时它们才会重新执行,否则返回已缓存的之前的计算结果;而方法只要触发重新渲染就会再次执行

代码实战

实例化一个vue实例,在data中定义一个firstName和lastName,还有一个全称叫fullName。
提示:fullName = firstName + lastName。
需求:分别使用watch监听器和计算属性来实现以下功能实现,只要firstName和lastName中的任意一个改变,全称fullname就会改变
代码预览

v-bind以及class与style的绑定


v-bind通常用来绑定属性,可以动态地绑定一些class类名或者style样式:

  • 变量语法v-bind:class="变量",这里变量的值通常是在CSS定义好的类名;
  • 数组语法v-bind:class="[变量1, 变量2]",形式与变量语法差不多,但可以同时绑定多个类名;
  • 对象语法v-bind:class="{classname1:boolean, classname2:boolean}",这里的classname就是样式表的类名,boolean通常是一个变量,也可以是常量、计算属性等,这种方法也是绑定class最常用的方式。

代码实战

  1. 使用v-bind对象语法来动态绑定一个class预览链接
  2. 使用v-bind数组语法来动态绑定一个class预览链接
  3. v-bind绑定style属性预览链接

Vue的内置指令


一、v-model有什么作用

v-model可以在表单<input>、<textarea>及<select>元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。尽管有些神奇,但v-model的本质不过是语法糖。它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理。

<input type="text" v-model="msg"/> {{msg}}

二、各指令的作用

  • v-if根据表达式的值的真假条件渲染元素。在切换时元素及其数据绑定/组件被销毁并重建。如果元素是<template>,将提出他的内容作为条件块。当条件变化时该指令触发过渡效果。当和v-if一起使用时,v-for的优先级更高,只渲染变化的元素。提供key值可以决定是否复用该元素。
  • v-else:必须紧跟在v-if或v-else-if后,否则不能被识别。
  • v-show根据条件显示元素。与v-if不同的是,带有v-show的元素始终会被渲染并保留在DOM中,v-show只是简单地切换元素CSS的display属性。
    注意:v-show不支持<template>元素,也不支持v-else
  • v-once只渲染元素和组件一次。元素和组件及其所有子节点会将随后的重新渲染视为静态内容并跳过。这可以用于优化更新性能。
  • v-cloak解决初始化慢导致的页面闪动[v-cloak]:{display:none}一起使用,可以隐藏未编译的Mustache标签指导失利准备完毕。

代码实例

  1. 使用v-for循环写出一个demo:预览链接
  2. 使用v-bind,v-on写出一个demo:预览链接
  3. 在输入框运用v-model:预览链接
  4. 在复选框运用v-model:预览链接
  5. 在单选框运用v-model:预览链接

Vue组件


一、全局注册和局部注册组件

<!DOCTYPE html>
<html>
<head>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
  <div id="app">
    <p>全局注册组件:</p>
    <my-component></my-component>
    <hr>
    <p>局部注册组件:</p>
    <app-component></app-component>
  </div>
  <script>
     Vue.component('my-component',{
      template:'<div class="quanju">我是全局注册的组件</div>'
    })
     
     var app = new Vue({
       el: '#app',
       data: {
         
       },
       components: {
         'app-component': {
           template: '<div class="jubu">我是局部注册的组件</div>'
         }
       }
     })
  </script>
</body>
</html>

预览链接

二、父组件给子组件传递信息的代码

<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
  <div id="app">
    <a-component msg="我是父组件传递的数据"></a-component>
    <hr>
    <p>提示:通过输入的数据改变正方形的边长</p>
    <input type="text" v-model="length">
    <b-component :length="length"></b-component>
  </div>
  <script>
    var app = new Vue({
      el: '#app',
      data: {
        length: '10'
      },
      components: {
        'a-component': {
          props: ['msg'],
          template: '<div class="jubu">{{count}}</div>',
          data: function(){
            return {
              count: this.msg
            }
          }
        },
        'b-component': {
          props: ['length'],
          template: '<div :style="style"></div>',
          computed: {
            style: function(){
              return {
                width: this.length + 'px',
                height: this.length + 'px',
                background: 'red',
                marginTop: '10px'
              }
            }
          },
          data: function(){
            return {}
          }
        }
      }
    })
  </script>
</body>
</html>

预览链接

三、子组件给父组件传递信息的代码

1. 自定义事件

<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
  <div id="app">
    <p>通过按钮给父组件传递数据</p>
    <div class="content">
      <p class="btn-title">您现在的银行卡余额是:{{total}}元</p>
      <app-component @change="handleTotal"></app-component>
    </div>
  <script>
    var app = new Vue({
      el: '#app',
      data: {
        total: 2000
      },
      components: {
        'app-component': {
          template: '<div class="btn">\
<button @click="increase">+100</button>\
<button @click="decrease">-100</button>\
    </div>\
    </div>',
          methods: {
            increase: function(){
              this.count += 100
              this.$emit('change', this.count)
            },
            decrease: function(){
              this.count = this.count>0? this.count-100:0
              this.$emit('change',this.count)
            }
          },
          data: function(){
            return {
              count: 2000
            }
          }
        }
      },
      methods: {
        handleTotal: function(value){
          this.total = value
        }
      }
    })
  </script>
</body>
</html>

预览链接
2. v-model

<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
  <div id="app">
    <p>通过按钮给父组件传递数据</p>
    <div class="content">
      <p class="btn-title">您现在的银行卡余额是:{{total}}元</p>
      <app-component v-model="total"></app-component>
    </div>
  <script>
    var app = new Vue({
      el: '#app',
      data: {
        total: 2000
      },
      components: {
        'app-component': {
          template: '<div class="btn">\
<button @click="increase">+100</button>\
<button @click="decrease">-100</button>\
    </div>\
    </div>',
          methods: {
            increase: function(){
              this.count += 100
              this.$emit('input', this.count)
            },
            decrease: function(){
              this.count = this.count>0? this.count-100:0
              this.$emit('input',this.count)
            }
          },
          data: function(){
            return {
              count: 2000
            }
          }
        }
      }
    })
  </script>
</body>
</html>

预览链接

五、非父子组件之间传值

<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
  <div id="app">
    <a-component></a-component>
    <b-component></b-component>
  </div>
  <script>
    var app = new Vue({
      el: '#app',
      data: {
        bus: new Vue()
      },
      components: {
        'a-component': {
          template: '<div class="a">a组件<br><button @click="handle">点击向b组件传值</button></div>',
          data: function(){
            return {
              msg: '我是来自a组件的内容'
            }
          },
          methods: {
            handle: function(){
              this.$root.bus.$emit('hello', this.msg)
            }
          }
        },
        'b-component': {
          template: '<div class="b">b组件</div>',
          data: function(){
            return {
              msg2: '我是来自b组件的内容'
            }
          },
          created: function(){
            this.$root.bus.$on('hello', function(value){
              alert(value)
            })
          }
        }
      }
    })
  </script>
</body>
</html>

预览链接

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,402评论 6 499
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,377评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,483评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,165评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,176评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,146评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,032评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,896评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,311评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,536评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,696评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,413评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,008评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,815评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,698评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,592评论 2 353

推荐阅读更多精彩内容

  • # 传智播客vue 学习## 1. 什么是 Vue.js* Vue 开发手机 APP 需要借助于 Weex* Vu...
    再见天才阅读 3,536评论 0 6
  • 这篇笔记主要包含 Vue 2 不同于 Vue 1 或者特有的内容,还有我对于 Vue 1.0 印象不深的内容。关于...
    云之外阅读 5,048评论 0 29
  • 1.安装 可以简单地在页面引入Vue.js作为独立版本,Vue即被注册为全局变量,可以在页面使用了。 如果希望搭建...
    Awey阅读 11,014评论 4 129
  • vue概述 在官方文档中,有一句话对Vue的定位说的很明确:Vue.js 的核心是一个允许采用简洁的模板语法来声明...
    li4065阅读 7,209评论 0 25
  • 主要还是自己看的,所有内容来自官方文档。 介绍 Vue.js 是什么 Vue (读音 /vjuː/,类似于 vie...
    Leonzai阅读 3,348评论 0 25