VUE

概述:一套用于构建用户界面的渐进式框架。

​ vue被设计为可以自底向上逐层应用,vue的核心库只关注视图层,易于上手且便于与第三方库或已有项目进行整合。


VUE基础概述

环境

想要使用vue有两种方式:

  • 直接在html文件的<script>中引入xur.js

    可以直接下载,或者使用CDN。

    <!-- 带有帮助信息的开发环境版本 -->
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    
    <!-- 优化大小速度的生产环境版本 -->
    <script src="https://cdn.jsdelivr.net/npm/vue"></script>
    
  • 使用命令行工具:vue-cli


基本操作

首先,vue其实就是一个js框架。

​ 其精妙之处在于虚拟化了一个DOM对象,并在未加载html时就对该对象进行虚拟操作,等到加载后,该虚拟对象与真实的htmlDOM对象进行了关联,此时操作就会由真实DOM呈现。

基础渲染

文本插值:

<div id="app">
  {{ message }}
</div>
<script>
var app = new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue!'
  }
})
</script>

绑定attribute

<div id="app-2">
  <span v-bind:title="message">
    鼠标悬停几秒钟查看此处动态绑定的提示信息!
  </span>
</div>
<script>
var app2 = new Vue({
  el: '#app-2',
  data: {
    message: '页面加载于 ' + new Date().toLocaleString()
  }
})
</script>

条件与循环

v-if
<div id="app-3">
  <p v-if="seen">现在你看到我了</p>
</div>
<script>
var app3 = new Vue({
  el: '#app-3',
  data: {
    seen: true
  }
})
</script>

继续在控制台输入 app3.seen = false,你会发现之前显示的消息消失了。

v-for
<div id="app-4">
  <ol>
    <li v-for="todo in todos">
      {{ todo.text }}
    </li>
  </ol>
</div>
<script>
var app4 = new Vue({
  el: '#app-4',
  data: {
    todos: [
      { text: '学习 JavaScript' },
      { text: '学习 Vue' },
      { text: '整个牛项目' }
    ]
  }
})
</script>

在控制台里,输入 app4.todos.push({ text: '新项目' }),你会发现列表最后添加了一个新项目。

事件监控器

v-on:***
<div id="app-5">
  <p>{{ message }}</p>
  <button v-on:click="reverseMessage">反转消息</button>
</div>
<script>
var app5 = new Vue({
  el: '#app-5',
  data: {
    message: 'Hello Vue.js!'
  },
  methods: {
    reverseMessage: function () {
      this.message = this.message.split('').reverse().join('')
    }
  }
})
</script>

console输出myapp5.btnDown = function(){this.btnMsg = '嘻嘻';},则按下按钮会变。

表单

Vue 还提供了 v-model 指令,它能轻松实现表单输入和应用状态之间的双向绑定。

双向绑定:修改message会修改表单内内容,修改表单内内容,会修改massage

<div id="app-6">
  <p>{{ message }}</p>
  <input v-model="message">
</div>
<script>
var app6 = new Vue({
  el: '#app-6',
  data: {
    message: 'Hello Vue!'
  }
})
</script>

组件化应用构建

组件系统是 Vue 的另一个重要概念,因为它是一种抽象,允许我们使用小型、独立和通常可复用的组件构建大型应用。仔细想想,几乎任意类型的应用界面都可以抽象为一个组件树:


2.png

组件:拥有预定义选项的 Vue 实例。(类似于javaBean:可重用组件)

注册组件方式

<script>中创建组件

几个要点:

  • props:起着占位符的作用,里面是占位符数组。

    传值方式:

    • 在html使用组件时,开始标签中使用 propName="" 来传递
    • 在html使用组件时,开始标签中使用 v-bind:porpName="" 来传递。
  • template:被调用时,显示的内容。其内容可以跟普通 html 标签完全一样

  • data:数据

  • methods:函数方法

    <!-- 组件化应用 -->
    <div id="app-7">
        <ol>
            <xixi v-for="fruit in fruits" v-bind:todo="fruit"></xixi>
            <button-counter title="①"></button-counter>
            <button-counter title="②"></button-counter>         
        </ol>
    </div>
    
    <script>
         Vue.component('button-counter',{
            props:['title'],
            template:'<button v-on:click="count++">{{title}}点了我{{count}}次</button>',
            data:function(){
                return{
                    count: 0
                }
            },
        })
                         
        Vue.component('xixi',{
            props:['todo'],
            template: '<li v-on:click="changeName()">{{todo.text}}</li>',
            methods: {
                changeName: function(){
                    this.todo.text = "荔枝";
                },
            }
        })
    </script>
实际模型概述
<div id="app">
  <app-nav></app-nav>
  <app-view>
    <app-sidebar></app-sidebar>
    <app-content></app-content>
  </app-view>
</div>

VUE实例

API 文档

创建一个Vue实例

规范:
  • 一个根 Vue 实例
  • 可选的嵌套的可重用组件(也是 Vue 实例)
根实例
└─ TodoList
   ├─ TodoItem
   │  ├─ DeleteTodoButton
   │  └─ EditTodoButton
   └─ TodoListFooter
      ├─ ClearTodosButton
      └─ TodoListStatistics

数据与方法

​ 当一个Vue实例被创建时,会将data对象的所有 property 加入到Vue 的响应式系统中;当某个属性发生变化时,该系统会产生响应,作用到视图上就是更新为新的值。(双向)

响应式:

​ 当数据改变时,视图会进行冲渲染。注意:仅当存在于Vue实例的data对象中的属性(数据)才是响应式的。

一些小知识:
  • 初始值:(以后可能会用到该数据,先将其变成响应式数据

    data: {
      newTodoText: '',
      visitCount: 0,
      hideCompletedTodos: false,
      todos: [],
      error: null
    }
    
例外:Object.freeze(obj)

​ 该语句会阻止对已有对象obj的修改。所以该对象的属性的响应式功能会失效。

var obj = {
  foo: 'bar'
}

Object.freeze(obj)

new Vue({
  el: '#app',
  data: obj
})
<div id="app">
  <p>{{ foo }}</p>
  <!-- 这里的 `foo` 不会更新! -->
  <button v-on:click="foo = 'baz'">Change it</button>
</div>

Vue提供的实例

所有的new出来的Vue实例,都继承了Vue定义的property与方法;

语法:$属性

如:

var data = { a: 1 }
var vm = new Vue({
  el: '#example',
  data: data
})

vm.$data === data // => true
vm.$el === document.getElementById('example') // => true

// $watch 是一个Vue定义的实例方法
vm.$watch('a', function (newValue, oldValue) {
  // 这个回调将在 `vm.a` 改变后调用
})

以后你可以在 API 参考中查阅到完整的实例 property 和方法的列表


Vue实例的生命周期钩子

创建:

每个Vue实例被创建时,都要经过一系列的初始化过程:

  • 设置数据监听
  • 编译模板
  • 将实例挂载关联到DOM,并在数据变化时更新DOM
  • ...

在这个过程中,同时会运行一些叫生命周期钩子的函数。

作用:用户可在不同阶段添加自己的代码。如:

created会在Vue创建后,执行

new Vue({
  data: {
    a: 1
  },
  created: function () {
    // `this` 指向 vm 实例
    console.log('a is: ' + this.a)
  }
})
// => "a is: 1"

生命周期钩子:

  • created
  • mounted(已安装、已挂载)
  • updated
  • destroyed

生命周期钩子的this,指调用它的Vue实例。

注意:

不要在选项 property 或回调上使用箭头函数,比如
created: () => console.log(this.a) 或
vm.$watch('a', newValue => this.myMethod())。
因为箭头函数并没有 this,this 会作为变量一直向上级词法作用域查找,直至找到为止,经常导致
Uncaught TypeError: Cannot read property of undefined 或
Uncaught TypeError: this.myMethod is not a function 之类的错误。

生命周期图示

1.png

模板语法

插值

文本

最常见格式

  • {{}}

    • "Mustache"(八字胡)语法,双大括号中插入变量名

    ​ 如:{{msg}},显示时会显示msg这个属性的值,且具有响应式更新。

  • v-once

    • 一次性的放置数据,之后数据改变时,该插值内容不会变。如:

      <span v-once>这个将不会变:{{msg}}</span>
      

原始 HTML

说明:使用{{}},里面的数据将被解释为普通文本,而非 HTML 代码。

如:

<!--假定msg='<b>你好</b>'-->
<div id="example">
    {{msg}}  //显示的信息为:<b>你好</b>,而非粗体你好
</div>

指令

  • v-html = "data"

    <p>
        使用双括号:{{rawHtml}}   
    </p>
    <p>
        使用v-html指令:<span v-html="rawHtml"></span>
    </p>
    

注意

你的站点上动态渲染的任意 HTML 可能会非常危险,因为它很容易导致 XSS 攻击。请只对可信内容使用 HTML 插值,绝不要对用户提供的内容使用插值。

Attribute属性

说明:Mustache 语法不能作用在 HTML 标签属性上,如果需要,可以使用v-bind指令

指令:

  • v-bind:AttributeName = "data"

    <div v-bind:id="dynamicId"></div>
    

使用 JS 表达式

说明:插值不仅包含普通的属性键值,还可以支持完整的 JS 表达式。

{{ number + 1 }}
{{ ok? 'yes':'no' }}
{{ message.split('').reverse().join('.') }}
<div v-bind:id="'list-' + id"></div>

限制:

只能包含单个表单,所以下面的例子不会生效:

<!-- 这是语句不是表达式 -->
{{ var a = 1 }}

<!-- 流控制也不会生效,可以用三元表达式代替 -->
{{ if (ok) { return message } }}

注意

模板表达式都被放在沙盒中,只能访问全局变量的一个白名单,如 MathDate 。你不应该在模板表达式中试图访问用户定义的全局变量。

指令

说明:指令(Directives)指标签元素中带有:v-前缀的特殊属性。

职责:

预期职责:作为单个 JavaScript 表达式(v-for是例外情况),当指令改变时,会响应式地对整个标签起作用。如:

<p v-if="seen">现在看得见</p>

seen的值由true变为false时,该DOM会被重新渲染,直接移除。

参数

说明:一些指令能够接收一个"参数",在指令名称之后,以冒号表示。如:

<a v-bind:href="url">
    本链接的地址是:{{url}}
</a>

其可以接收从 Vue 挂载对象的属性,已达到更复杂多样的变化。

动态参数

2.6.0新增

说明:

可以用方括号括起来的 JavaScript 表达式作为一个指令的参数:

<!--
注意,参数表达式的写法存在一些约束,如之后的“对动态参数表达式的约束”章节所述。
-->
<a v-bind:[attributeName]="url"> ... </a>

​ 这里的 attributeName 会被作为一个 JavaScript 表达式进行动态求值,求得的值将会作为最终的参数来使用。例如,如果你的 Vue 实例有一个 data property attributeName,其值为 "href",那么这个绑定将等价于 v-bind:href

对动态参数的值的约束

动态参数预期会求出一个字符串,异常情况下值为 null。这个特殊的 null 值可以被显性地用于移除绑定。任何其它非字符串类型的值都将会触发一个警告。

对动态参数表达式的约束

动态参数表达式有一些语法约束,因为某些字符,如空格和引号,放在 HTML attribute 名里是无效的。例如:

<!-- 这会触发一个编译警告 -->
<a v-bind:['foo' + bar]="value"> ... </a>

变通的办法是使用没有空格或引号的表达式,或用计算属性替代这种复杂表达式。

在 DOM 中使用模板时 (直接在一个 HTML 文件里撰写模板),还需要避免使用大写字符来命名键名,因为浏览器会把 attribute 名全部强制转为小写:

<!--
在 DOM 中使用模板时这段代码会被转换为 `v-bind:[someattr]`。
除非在实例中有一个名为“someattr”的 property,否则代码不会工作。
-->
<a v-bind:[someAttr]="value"> ... </a>

修饰符

修饰符 (modifier) 是以半角句号 . 指明的特殊后缀,用于指出一个指令应该以特殊方式绑定。例如,.prevent 修饰符告诉 v-on 指令对于触发的事件调用 event.preventDefault()

<form v-on:submit.prevent="onSubmit">...</form>

在接下来对 v-onv-for等功能的探索中,你会看到修饰符的其它例子。

缩写

v- 前缀作为一种视觉提示,用来识别模板中 Vue 特定的 attribute。当你在使用 Vue.js 为现有标签添加动态行为 (dynamic behavior) 时,v- 前缀很有帮助,然而,对于一些频繁用到的指令来说,就会感到使用繁琐。同时,在构建由 Vue 管理所有模板的单页面应用程序 (SPA - single page application) 时,v- 前缀也变得没那么重要了。因此,Vue 为 v-bindv-on 这两个最常用的指令,提供了特定简写:

v-bind 缩写

<!-- 完整语法 -->
<a v-bind:href="url">...</a>

<!-- 缩写 -->
<a :href="url">...</a>

<!-- 动态参数的缩写 (2.6.0+) -->
<a :[key]="url"> ... </a>

v-on 缩写


<!-- 完整语法 -->
<a v-on:click="doSomething">...</a>

<!-- 缩写 -->
<a @click="doSomething">...</a>

<!-- 动态参数的缩写 (2.6.0+) -->
<a @[event]="doSomething"> ... </a>

注意:

​ 它们看起来可能与普通的 HTML 略有不同,但 :@ 对于 attribute 名来说都是合法字符,在所有支持 Vue 的浏览器都能被正确地解析。而且,它们不会出现在最终渲染的标记中。缩写语法是完全可选的,但随着你更深入地了解它们的作用,你会庆幸拥有它们。


计算属性和侦听器

计算属性

说明:对于模板内(html)的表达式,会提供很多遍历,但是其仅支持简单运算,如果逻辑太复杂会难以维护。

如:

<div id = "example">
    {{ message.split(''). }}
</div>

基础例子

        <div id="reverse1">
            <p>消息:"{{msg}}"</p>
            <p>消息:"{{msgReverse}}"</p>
        </div>

        <script>
            var reverse1 = new Vue({
                el: "#reverse1",
                data:{
                    msg: "apple"
                },
                computed:{
                    msgReverse: function(){
                        return this.msg.split('').reverse().join('.');
                    }
                }
            })
        </script>

结果:

Original message: "Hello"

Computed reversed message: "olleH"

说明:computed相当于提供一个msgReverse的get()函数,其也是响应式的:

​ 控制台输出==> reverse1.msg = '西瓜'

​ html显示:

消息:"西瓜"

消息:"瓜.西"

调用方法也能完成一样的效果。

//组件中
methods: {
    msgReverse: function(){
        return  this.msg.split('').reverse().join('.');
    }
}
//调用:
<p>消息:"{{msgReverse()}}"</p>
methods和计算属性
  • 最终结果相同

  • 方法没缓存、计算属性有缓存。

  • 依赖方式不同:

    • method中:每次重新渲染都需要执行函数。

    • 计算属性中:基于响应式依赖进行缓存,只在相关响应式依赖发生改变时,才会重新求值,只要msg还没有改变,多次访问msgReverse会立即返回之前的计算结果,而不必再次执行函数。

      注意:

      ​ 此时,如果计算属性函数是:

      ​ time:funciton(){

      ​ return new Date.now()

      ​ }

      ​ 其永远不会更新.

计算属性 vs 侦听属性

侦听属性:

定义:Vue提供的一种通用方式,来观察、响应Vue实例上的数据变动。

计算属性和监听属性都可以用于:随数据变动而改变的值。

但有时可能是计算属性更好用:
例子:

<div id="demo">{{ fullName }}</div>
var vm = new Vue({
  el: '#demo',
  data: {
    firstName: 'Foo',
    lastName: 'Bar',
    fullName: 'Foo Bar'
  },
  watch: {
    firstName: function (val) {
      this.fullName = val + ' ' + this.lastName
    },
    lastName: function (val) {
      this.fullName = this.firstName + ' ' + val
    }
  }
})

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

var vm = new Vue({
  el: '#demo',
  data: {
    firstName: 'Foo',
    lastName: 'Bar'
  },
  computed: {
    fullName: function () {
      return this.firstName + ' ' + this.lastName
    }
  }
})

计算属性的 setter

计算属性默认只有 getter,但在需要时可以提供 setter:

...//Vue声明中
computed: {
    fullName:{ 
        get: function () {
        return this.firstName + '  ' + this.lastName
        }
        set: function(new value){
            var names = newValue.split(' ');
            this.firstName = names[0];
            this.lastName = names[1];
        }
     }
}
...

现在再运行 vm.fullName = 'John Doe' 时,setter 会被调用,vm.firstNamevm.lastName 也会相应地被更新。

侦听器

​ 虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的侦听器。这就是为什么 Vue 通过 watch 选项提供了一个更通用的方法,来响应数据的变化。

场景

​ 当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。


class 与 style 绑定

详情-官网


条件渲染

v-if

作用:根据其值是否为true,来选择是否渲染该标签。

<p id="customP2" :style="myStyle" v-if="render">我是中国人</p>

v-else

作用:需要紧跟v-if,且是相同元素标签,用于表达else语法。

<p id="customP2" :style="myStyle" v-if="render">我是中国人</p>
<p v-else>我是中国人</p>

v-else-if

作用:需要紧跟在v-ifv-else-if后面。

<div v-if="Math.random() > 0.5">
    Now you see me
</div>
<div v-else-if="Math.random() > 0.5">
    else if
</div>

总说:

        <div id="exam">
            <div v-if="Math.random() > 0.5">
                Now you see me
            </div>
            <div v-else-if="Math.random() > 0.5">
                else if
            </div>
            <div v-else>
                Now you don't
            </div>
        </div>
        
        <script>
            var exam = new Vue({
            el:"#exam"
            })
        </script>

key 管理可复用的元素

​ Vue 会尽可能高效地渲染元素,通常会复用已有元素而不是从头开始渲染。这么做除了使 Vue 变得非常快之外,还有其它一些好处。例如,如果你允许用户在不同的登录方式之间切换:

<template v-if="loginType === 'username'">
  <label>Username</label>
  <input placeholder="Enter your username">
</template>
<template v-else>
  <label>Email</label>
  <input placeholder="Enter your email address">
</template>

​ 那么在上面的代码中切换 loginType 将不会清除用户已经输入的内容。因为两个模板使用了相同的元素.

<input> 不会被替换掉——仅仅是替换了它的 placeholder.

​ 这样也不总是符合实际需求,所以 Vue 为你提供了一种方式来表达“这两个元素是完全独立的,不要复用它们”。只需添加一个具有唯一值的 key attribute 即可:

<template v-if="loginType === 'username'">
  <label>Username</label>
  <input placeholder="Enter your username" key="username-input">
</template>
<template v-else>
  <label>Email</label>
  <input placeholder="Enter your email address" key="email-input">
</template>

现在,每次切换时,输入框都将被重新渲染。

注意,<label> 元素仍然会被高效地复用,因为它们没有添加 key attribute。

v-show

作用:根据value真假,选择是否展示元素。

<h1 v-show="ok">ok真,就看得到,假,就看不到</h1>
v-if区别

v-show所在元素,始终会被渲染并保留在 DOM 中。v-show只是简单的切换元素的CSS样式style="display:true"style="display:false"

注意,v-show 不支持 <template>元素,也不支持 v-else

v-if vs v-show

v-if 是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。

v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。

​ 相比之下,v-show 就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。

​ 一般来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。

使用场景总结

  • v-show :需要非常频繁地切换。
  • v-if:如果在运行时条件很少改变。

v-ifv-for 一起使用

不推荐同时使用 v-ifv-for。请查阅风格指南以获取更多信息。

v-ifv-for 一起使用时,v-for 具有比 v-if 更高的优先级。请查阅列表渲染指南以获取详细信息。


列表渲染

v-for

作用:用于遍历数组、对象。

语法

  • v-for="item in items"
  • v-for="item of items" :等同第一个,更切和 JS 语法
  • v-for="(item, index) in items" :items的index属性也可以访问
  • v-for="(item, name ) in items" :对象属性的遍历,也可以用两个属性,分别获得键、值。
  • v-for="(item, name,index) in items"

item参数:可以访问所有父作用域的 property 属性。

<div id="items">
    <ul>
        <label style="color:lightseagreen;font-size: x-large;">
                 具体犬类
            </label>
                <li style="font: bold;color: lightskyblue;" v-for="(item, index) in items">
                    {{item+':'+index}}
            </li>
    </ul>
    <ul>
        <label style="color:lightseagreen;font-size: x-large;">
                犬类特征
              </label>
        <li style="font: bold;color: lightskyblue;" v-for="value of faces">{{value}}</li>
    </ul>
</div>
            var items = new Vue({
                el: "#items",
                data: {
                    items: [
                        "田园犬",
                        "泰迪",
                        "拉布拉多"
                    ],
                    faces: {
                        type: "哺乳动物",
                        voice: "汪汪",
                        walkType: "爬行",
                    }
                }
            })

指定唯一key

v-for遍历,为方便 Vue 跟踪每个节点,而重新排序等,可以为每项提供给一个唯一key

只能是基础数据类型:int ,string 等等

<div v-for="item in items" v-bind:key="item.id">
  <!-- 内容 -->
</div>

尽量在使用v-for时,指定唯一key,除非遍历输出的的DOM内容非常简单,或是为获得性能刻意不指定。

因为它是 Vue 识别节点的一个通用机制,key 并不仅与 v-for 特别关联。后面我们将在指南中看到,它还具有其它用途。

更多 key attribute 的细节用法请移步至 key 的 API 文档

数组更新检测

更新方法

数组的变更会触发 DOM 重渲染,方法包括:

  • push()
  • pop()
  • shift()
  • unshift()
  • splice()
  • sort()
  • reverse()

如之前的item例子,Console==》items.items.push("西施"),则 DOM 会对应重渲染

替换数组

​ 变更方法,顾名思义,会变更调用了这些方法的原始数组。相比之下,也有非变更方法,例如 filter()concat()slice()。它们不会变更原始数组,而总是返回一个新数组。当使用非变更方法时,可以用新数组替换旧数组:

example1.items = example1.items.filter(function (item) {
  return item.message.match(/Foo/)
})

​ 你可能认为这将导致 Vue 丢弃现有 DOM 并重新渲染整个列表。幸运的是,事实并非如此。Vue 为了使得 DOM 元素得到最大范围的重用而实现了一些智能的启发式方法,所以用一个含有相同元素的数组去替换原来的数组是非常高效的操作。

注意事项

由于 JavaScript 的限制,Vue 不能检测数组和对象的变化。深入响应式原理中有相关的讨论。

v-for 里使用值范围

说明:即父标签或更上层标签中,放入v-for语句,形成更大的循环范围。

v-forv-if 一同使用

注意我们推荐在同一元素上使用 v-ifv-for。更多细节可查阅风格指南

​ 当它们处于同一节点,v-for 的优先级比 v-if 更高,这意味着 v-if 将分别重复运行于每个 v-for 循环中。当你只想为部分项渲染节点时,这种优先级的机制会十分有用,如下:

<li v-for="todo in todos" v-if="!todo.isComplete">
  {{ todo }}
</li>

​ 上面的代码将只渲染未完成的 todo。

​ 而如果你的目的是有条件地跳过循环的执行,那么可以将 v-if 置于外层元素 (或 `) 上。如:

<ul v-if="todos.length">
  <li v-for="todo in todos">
    {{ todo }}
  </li>
</ul>
<p v-else>No todos left!</p>

v-on事件处理

职责:用于监听 DOM 事件,并在触发时,运行一些 JS 代码。

基本格式:v-on:xxx

示例:

<div id="example-1">
  <button v-on:click="counter += 1">Add 1</button>
  <p>The button above has been clicked {{ counter }} times.</p>
</div>
var example1 = new Vue({
  el: '#example-1',
  data: {
    counter: 0
  }
})

事件处理方法

说明:有些事件处理逻辑很复杂,直接写在v-on不是个好办法,替换的是v-on接收一个需要调用的方法名。

如下

<div id="example-2">
  <!-- `greet` 是在下面定义的方法名 -->
  <button v-on:click="greet">Greet</button>
</div>
var example2 = new Vue({
  el: '#example-2',
  data: {
    name: 'Vue.js'
  },
  // 在 `methods` 对象中定义方法
  methods: {
    greet: function (event) {
      // `this` 在方法里指向当前 Vue 实例
      alert('Hello ' + this.name + '!')
      // `event` 是原生 DOM 事件
      if (event) {
        alert(event.target.tagName)
      }
    }
  }
})

// 也可以用 JavaScript 直接调用方法
example2.greet() // => 'Hello Vue.js!'

内联处理器中的方法

除了直接绑定到一个方法,也可以在内联 JavaScript 语句中调用方法:

<div id="example-3">
  <button v-on:click="say('hi')">Say hi</button>
  <button v-on:click="say('what')">Say what</button>
</div>
<script>
new Vue({
  el: '#example-3',
  methods: {
    say: function (message) {
      alert(message)
    }
  }
})

​ 有时也需要在内联语句处理器中访问原始的 DOM 事件。可以用特殊变量 $event 把它传入方法:

<button v-on:click="warn('Form cannot be submitted yet.', $event)">
  Submit
</button>
// ...
<script>
methods: {
  warn: function (message, event) {
    // 现在我们可以访问原生事件对象
    if (event) {
      event.preventDefault()
    }
    alert(message)
  }
}

事件修饰符

在事件处理程序中调用 event.preventDefault()event.stopPropagation() 是非常常见的需求。尽管我们可以在方法中轻松实现这点,但更好的方式是:方法只有纯粹的数据逻辑,而不是去处理 DOM 事件细节。

为了解决这个问题,Vue.js 为 v-on 提供了事件修饰符。之前提过,修饰符是由点开头的指令后缀来表示的。

  • .stop
  • .prevent
  • .capture
  • .self
  • .once
  • .passive
<!-- 阻止单击事件继续传播 -->
<a v-on:click.stop="doThis"></a>

<!-- 提交事件不再重载页面 -->
<form v-on:submit.prevent="onSubmit"></form>

<!-- 修饰符可以串联 -->
<a v-on:click.stop.prevent="doThat"></a>

<!-- 只有修饰符 -->
<form v-on:submit.prevent></form>

<!-- 添加事件监听器时使用事件捕获模式 -->
<!-- 即内部元素触发的事件先在此处理,然后才交由内部元素进行处理 -->
<div v-on:click.capture="doThis">...</div>

<!-- 只当在 event.target 是当前元素自身时触发处理函数 -->
<!-- 即事件不是从内部元素触发的 -->
<div v-on:click.self="doThat">...</div>

使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生。因此,用 v-on:click.prevent.self 会阻止所有的点击,而 v-on:click.self.prevent 只会阻止对元素自身的点击。

2.1.4 新增

<!-- 点击事件将只会触发一次 -->
<a v-on:click.once="doThis"></a>

​ 不像其它只能对原生的 DOM 事件起作用的修饰符,.once 修饰符还能被用到自定义的组件事件上。如果你还没有阅读关于组件的文档,现在大可不必担心。

2.3.0 新增

​ Vue 还对应 addEventListener 中的 passive 选项提供了 .passive 修饰符。

<!-- 滚动事件的默认行为 (即滚动行为) 将会立即触发 -->
<!-- 而不会等待 `onScroll` 完成  -->
<!-- 这其中包含 `event.preventDefault()` 的情况 -->
<div v-on:scroll.passive="onScroll">...</div>

​ 这个 .passive 修饰符尤其能够提升移动端的性能。

​ 不要把 .passive.prevent 一起使用,因为 .prevent 将会被忽略,同时浏览器可能会向你展示一个警告。请记住,.passive 会告诉浏览器你想阻止事件的默认行为。

按键修饰符

​ 在监听键盘事件时,我们经常需要检查详细的按键。Vue 允许为 v-on 在监听键盘事件时添加按键修饰符:

<!-- 只有在 `key` 是 `Enter` 时调用 `vm.submit()` -->
<input v-on:keyup.enter="submit">

​ 你可以直接将 KeyboardEvent.key 暴露的任意有效按键名转换为 kebab-case 来作为修饰符。

<input v-on:keyup.page-down="onPageDown">

​ 在上述示例中,处理函数只会在 $event.key 等于 PageDown 时被调用。

按键码

keyCode 的事件用法已经被废弃了并可能不会被最新的浏览器支持。

使用 keyCode attribute 也是允许的:

<input v-on:keyup.13="submit">

为了在必要的情况下支持旧浏览器,Vue 提供了绝大多数常用的按键码的别名:

  • .enter
  • .tab
  • .delete (捕获“删除”和“退格”键)
  • .esc
  • .space
  • .up
  • .down
  • .left
  • .right

有一些按键 (.esc 以及所有的方向键) 在 IE9 中有不同的 key 值, 如果你想支持 IE9,这些内置的别名应该是首选。

你还可以通过全局 config.keyCodes 对象自定义按键修饰符别名

// 可以使用 `v-on:keyup.f1`
Vue.config.keyCodes.f1 = 112

系统修饰键

2.1.0 新增

可以用如下修饰符来实现仅在按下相应按键时才触发鼠标或键盘事件的监听器。

  • .ctrl
  • .alt
  • .shift
  • .meta

注意:在 Mac 系统键盘上,meta 对应 command 键 (⌘)。在 Windows 系统键盘 meta 对应 Windows 徽标键 (⊞)。在 Sun 操作系统键盘上,meta 对应实心宝石键 (◆)。在其他特定键盘上,尤其在 MIT 和 Lisp 机器的键盘、以及其后继产品,比如 Knight 键盘、space-cadet 键盘,meta 被标记为“META”。在 Symbolics 键盘上,meta 被标记为“META”或者“Meta”。

例如:

<!-- Alt + C -->
<input v-on:keyup.alt.67="clear">

<!-- Ctrl + Click -->
<div v-on:click.ctrl="doSomething">Do something</div>

请注意修饰键与常规按键不同,在和 keyup 事件一起用时,事件触发时修饰键必须处于按下状态。换句话说,只有在按住 ctrl 的情况下释放其它按键,才能触发 keyup.ctrl。而单单释放 ctrl 也不会触发事件。如果你想要这样的行为,请为 ctrl 换用 keyCodekeyup.17

更多看官网


表单输入绑定

v-model

作用:做为表单标签元素的属性,其值v-model="value"

value会挂载:【表单元素的输入值】---- Vue 实例的【data的属性】。

不同<input>元素

​ **v-model **为不同输入元素,使用不同 property ,并抛出不同的事件:

  • <text><textarea> 元素value property 和 input 事件;
  • <checkbox>< radio>checked property 和 change 事件;
  • <select> 字段value 作为 prop 并将 change 作为事件。

v-model 会忽略所有表单元素的 valuecheckedselected attribute 的初始值而总是将 Vue 实例的数据作为数据来源。你应该通过 JavaScript 在组件的 data 选项中声明初始值。

文本

说明:Vue 的响应式数据,使前端可以做到原来后端才能做的事。

message用作输入框内容和 Vue 实例绑定的数据,实现当输入时,会实时显示在<p>中。

<div id="example-1">
  <input v-model="message" placeholder="edit me">
  <p>Message is: {{ message }}</p>
</div>

<script>
new Vue({
  el: '#example-1',
  data: {
    message: ''
  }
})
</script>

多行文本

message用作输入框内容和 Vue 实例绑定的数据,实现当输入时,会实时显示在<p>中。

<div id="exam2">
    <span>Multiline message is:</span>
    <p style="white-space:pre-line;">
        {{message}}
    </p>
    <textarea v-model="message" placeholder="在这里输入"></textarea>
</div>
<script>
    var exam2 = new Vue({
                el: "#exam2",
            data:{
                    message:""
            }
        })
</script>

在文本区域插值 ({{text}}) 并不会生效,应用 v-model 来代替。

复选框

单个复选框

绑定到bool值:

<div id="exam3">
    <input type="checkbox" id="checkbox" v-mode="checked">
         <label for="checkbox">
             {{checked}}
         </label>
</div>
<script>
    var exam3 = new Vue({
            el: "#exam3",
            data:{
                    checked: true
            }
    })
</script>

多个复选框

绑定到一个value数组,凡是勾选的框,其value就刷新为数组元素:

<div id="exam4">
    <input type="checkbox" id="mrLi" value="mrLi" v-model="boxList">
    <input type="checkbox" id="mrSun" value="mrSun" v-model="boxList">
    <input type="checkbox" id="mrWang" value="mrWang" v-model="boxList">
    <p>数组:</p>
    <p>
        {{boxlist}}
    </p>
</div>

<script>
    var exam4 = new Vue({
            el: "#exam4",
            data:{
                    boxList: ["首元素:nothing"]
            }
    })
</script>

单选按钮

<div id="exam5">
    <input type="radio" v-model="radio" value="男">男
    <br/>
    <input type="radio" v-model="radio" value="女">女
    <br/>
    <p>radio:</p>
    <p>{{radio}}</p>
</div>

<script>
    var exam5 = new Vue({
            el: "#exam5",
            data:{
                    radio:""
            }
    })
</script>

选择框

单选时:

<div id="exam6">
    <select v-modle="selected">
        <option disabled value="">请选择</option>
        <option>A</option>
        <option>B</option>
        <option>C</option>
    </select>
    <span>selected is : {{selected}}</span>
</div>
<script>
    var exam6 = new Vue({
            el: "#exam6",
            data:{
                    selected:''
            }
    })
</script>

注意

​ 如果 v-model 表达式的初始值未能匹配任何选项,<select> 元素将被渲染为“未选中”状态。

​ 在 iOS 中,这会使用户无法选择第一个选项。因为这样的情况下,iOS 不会触发 change 事件。因此,更推荐像上面这样提供一个值为空的禁用选项。

多选时,绑定到一个数组:

<div id="exam7">
    <select v-model="selectedList" multiple style="background-color:lightseagreen;width: 50px">
        <option>A</option>
        <option>B</option>
        <option>C</option>
    </select>
    <span>selectedList is : {{selectedList}}</span>
</div>
<script>
    var exam7 = new Vue({
            el: "#exam7",
            data:{
                    selectedList:[]
            }
    })
</script>

配合v-for

<div id="exam8">
    <!-- 单选择框+v-for -->
     <select v-model="selectedList" multiple style="background-color:lightseagreen;width: 50px">
        <option v-for="op of options">{{op}}</option>
    </select>
    <span>selectedList is : {{selectedList}}</span>
    <br/><hr/><br/>
    <!-- 单选择框+v-for -->
    <select v-model="selectedList" multiple style="background-color:lightseagreen;width: 50px">
        <option v-for="op of options">{{op}}</option>
    </select>
    <span>selectedList is : {{selectedList}}</span>
</div>
<script>
    var exam8 = new Vue({
            el: "#exam8",
            data:{
                    selectedList:[],
                    options:[
                        "甲木",
                        "丙火",
                        "戊土",
                        "庚金",
                        "壬水"
                    ]
            }
    })
</script>

表单值绑定

说明:对于单选按钮,复选框及选择框的选项,v-model 绑定的值通常是静态字符串 (对于复选框也可以是布尔值):

但是有时我们可能想把值绑定到 Vue 实例的一个动态 property 上,这时可以用 v-bind 实现,并且这个 property 的值可以不是字符串。

<input
  type="checkbox"
  v-model="toggle"
  true-value="yes"
  false-value="no"
>
// 当选中时
vm.toggle === 'yes'
// 当没有选中时
vm.toggle === 'no'

这里的 true-valuefalse-value attribute 并不会影响输入控件的 value attribute,因为浏览器在提交表单时并不会包含未被选中的复选框。如果要确保表单中这两个值中的一个能够被提交,(即“yes”或“no”),请换用单选按钮。

表单v-model修饰符

.lazy

用法:修饰符用法,都是在v-model后面直接连接就行。

职责

​ 在默认情况下,v-model 在每次 input 事件触发后将输入框的值与数据进行同步 (除了上述输入法组合文字时)。你可以添加 lazy 修饰符,从而转为在 change 事件之后进行同步:

<!-- 在“change”时而非“input”时更新 -->
<input v-model.lazy="msg">

.number

职责:自动将用户输入的值,转换为整数类型。

​ 这通常很有用,因为即使在 type="number" 时,HTML 输入元素的值也总会返回字符串。如果这个值无法被 parseFloat() 解析,则会返回原始的值。

.trim(修剪)

职责:自动过滤用户输入的首尾空白字符。


组件基础

定义形如

Vue.component('button-demo',{
        template: "<p>这里是显示模板</p>",
    data:  function()[{
            return{
            count: 0
        }
        },
         methods:{
         ....
    }
       
})

说明:组件是可服用的 Vue 实例,且带有一个名字,如上<button-demo>

  • 相同:含有datacomputedwatchmethods 以及生命周期钩子等。

  • 区别:其不含有 el这个根实例项。

使用:直接在html中使用即可

组件复用

说明:组件可以复用任意次数,每次使用一个组件时,就会创建一个新Vue实例,他们维护各自的数据。

data 必须是一个函数

说明:在组件中,data并不是一个对象,而是等于一个函数的return的形式.

原因:为每个实例提供一份唯一的拷贝。若非这样,则对一个组件的操作,会影响相同的组件。

组件的组织

格式:通常以树状来组织。

如:导航栏、侧边栏、内容区等组件。

每个组件又包含了其他的像导航链接、博文之类的组件。

2.png

组件注册

要使用组件,首先得注册组件

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