Vue.js备忘记录(一) 概述 安装 vue对象 生命周期 语法 数据绑定 事件处理

介绍 — Vue.js

vscode必装插件:vuetr 和 Vue 2 snippets

image
image

为了方便调试,我们还应该安装官方浏览器插件devtools

https://github.com/vuejs/vue-devtoolsgithub.com

安装要翻墙,安装好后进入调试工具,找vue标签

小贴士合集:

  • 每个 Vue 应用都是通过用Vue函数创建一个新的Vue 实例开始的

  • 只有当实例被创建时就已经存在于data中的属性才是响应式的。

  • 不要在选项属性或回调上使用箭头函数 (this问题)

  • v-on: 可以缩写为 @

  • v-bind: 可以缩写为 :

  • v-bind:class指令也可以与普通的 class 属性共存。

  • 不推荐同时使用v-if和v-for

  • 将计算属性computed里的函数取名为名词,当属性来调用

  • 组件中使用v-for时,key属性是必须的

  • key必须使用v-bind来绑定,key必须是string或者number

  • v-on绑定的方法如果有参数,必须传参

  • 为了与ES6风格统一,v-for="value in object"也可以写成v-for="value of object"

  • 注册自定义组件时不建议使用驼峰命名法,驼峰命名法会自动转为 - 命名法

  • 组件里的data必须是传入一个function,function里面再return对象出来

  • 子组件props里的数据不要和子组件的表单做双向数据绑定!

  • 最好不要在插槽上绑定vue指令,可以在其外面包一个div绑上

一. 概述

1.单页面应用程序 SPA

  • 经典的多页面: 不同页面都是独立的页面(有利于搜索引擎,前后端融合)

  • 现代式的单页面:不同网页其实是一个页面,只是在刷新区别内容 (只需要加载局部视图,用户体验好,不好兼容到低版本IE,所以诞生了一堆的开发框架,前后端分离,没有服务端渲染,服务端不再关心视图)

例如:https://music.163.com/ 不管页面怎么刷新,上面的导航条和下面的音乐播放条都不会刷新

2. 多页面的价值 //以服务端为主导,前后端混合

  • 以服务端为主

  • 有利于搜索引擎SEO

3.单页面的价值 //前后端分离

  • 前后端分离,前后端通过接口交互,服务端不关心页面

  • 不好兼容到低版本IE

  • 没有服务端渲染

  • 单页是肯定要使用框架的,比如 ract vue

4.前后端分离

项目立项

需求分析

服务端工作:

  • 需求分析

  • 设计数据库

  • 接口设计(前端也参与)

  • 数据处理及接口开发

前端工作

  • 需求分析

  • 页面搭建

  • 页面功能制作

  • 通过接口和服务器进行交互

5. vue简介

vue可以轻松构建SPA

通过指令扩展了HTML,通过 表达式 绑定数据到HTML

最大程度的解放DOM操作

vue特性:

  • MVVM

  • 双向数据绑定

  • 组件化

  • 渐进式

  • Vue不支持IE8 及以下版本

6.MVC和MVVM的概念

mvc是后端分层的概念 m 数据库层 v 视图层 c控制层

MVVM是前端视图层的概念,主要关注于 模型 视图模型 视图

image

二. vue的安装和hello world

1.安装


<script  src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

也可以指定版本(推荐生产环境这样用)


<script  src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>

还没有npm下载


$ cnpm install vue --save

2. hello world


<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <h1>{{ 1+2 }}</h1>
        <h1>{{ 'hello world'}}</h1>
        <h2>{{message}}</h2>
        <h2>{{lolo}}</h2>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        const app = new Vue({  //实例化一个Vue
            el: '#app',  //赋值el,意思是这个Vue实例接管id=app的组件
            data: {//数据必须声明在data中
                //data中的数据不是一般的数据,而是响应式数据
                message: 'hello',
                lolo:''
            }
        })
        app.message = "haha"
    </script>
</body>

</html>

image
  • 在此,我们可以先把vue看作一个模板引擎,

  • data中的数据不是一般的数据,而是响应式数据,

  • 响应式数据是一种数据驱动视图的思想,MVVM

  • el不要作用在html或body节点上

3. vue对象和其选项

(1) vue对象

每个 Vue 应用都是通过用Vue函数创建一个新的Vue 实例开始的

(2) data属性 (Vue的选项)

data其实Vue对象的一个属性,我们也可以称之为Vue的选项,那么vue有多少选项呢?

我们简单的看一下API就知道了

API — Vue.js

image
image
image
image

目前,我们只看最常用的选项.

当一个 Vue 实例被创建时,它将data对象中的所有的属性加入到 Vue 的响应式系统中。当这些属性的值发生改变时,视图将会产生“响应”,即匹配更新为新的值。当这些数据改变时,视图会进行重渲染。

值得注意的是只有当实例被创建时就已经存在于 data 中的属性才是响应式的。也就是说如果你添加一个新的属性,比如:


vm.b = 'hi'

那么对 b 的改动将不会触发任何视图的更新。如果你知道你会在晚些时候需要一个属性,但是一开始它为空或不存在,那么你仅需要设置一些初始值。

除了数据属性,Vue 实例还暴露了一些有用的实例属性与方法。它们都有前缀 $,以便与用户定义的属性区分开来。例如:


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

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

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

(3) methods

v-on 引用的函数都写在这个集合里

methods 将被混入到 Vue 实例中。可以直接通过 VM 实例访问这些方法,或者在指令表达式中使用。方法中的this自动绑定为 Vue 实例。

(4) computed 计算属性

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

这时候我们用到计算属性,他算是一种带有计算行为的属性,我们应该把他当作属性来调用

computed里的内容实质是方法,但不能当方法来调用,相较于方法,其特点是可以缓存计算结果

建议computed里的函数取名为名词,当属性来调用

例如:


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

但当计算复杂度高的时候,我们可以封装计算过程


<div  id="example">  <p>"{{ reversed }}"</p>  </div> const app = new Vue({
            el: '#app',
            data: {
                message:'hello world'
            },
            computed:{
                reversed:function(){
                    return this.message.split('').reverse().join('')
                }
            }
        })

双向绑定计算属性

每个计算属性其实都可以有自己的get和set属性. 如果设置了这两个属性,那么计算属性既可以get取值也可以set传值 (a=计算属性 计算属性=a)

只是默认只有 getter ,当你为其传入一个函数时,getter会接收它, 除非......

不过在需要时你也可以提供一个 setter :

computed: {
  fullName: {
    // getter
    get: function () {
      return this.firstName + ' ' + this.lastName
    },
    // setter
    set: function (newValue) {
      var names = newValue.split(' ')
      this.firstName = names[0]
      this.lastName = names[names.length - 1]
    }
  }
}
现在再运行 vm.fullName = 'John Doe' 时,setter 会被调用,vm.firstName 和 vm.lastName 
也会相应地被更新。

如果有一个计算属性是既可以get又可以set的,那么它完全可以双向绑定

例子:

image

如果我们想实现上图中的 全选联动 可以

<input  type="checkbox" v-model=allDone >

    computed: {
        allDone:{
            get:function(){
                return this.todos.every(todo=>todo.done==true)
            },
            set:function(value){
                todos.forEach(todo => {
                    todo.done=value
                });
            }
        }

v-model绑定计算属性allDone, 这样就完成了联动,

当我们点击下面的按钮时,会改变this.todos.every(...)的值,这个值会通过计算属性allDone的getter改变顶部checkbox的勾选状态.

同时,我们点击checkbox改变勾选状态时,会触发allDone的setter 从而改变下面的todo的done状态

使用计算属性实现过滤

<div  v-for="(todo, index) in filterTodos" :key="index" v-show=todo.seen >

data: {
    todos: JSON.parse(window.localStorage.getItem('todos') || '[]'),
    filterText: 'all'
    },

computed: {
    filterTodos() {
        switch (this.filterText) {
            case 'done':
                return this.todos.filter(todo => todo.done)
                break;
            case 'undone':
                return this.todos.filter(todo => !todo.done)
                break;
            default:
                return this.todos
                break;
        }
    }
},

(5) watch 侦听属性 //用来监听属性的变化

Vue 提供了一种更通用的方式来观察和响应 Vue 实例上的数据变动:侦听属性。

计算属性在大多数情况下更合适,但有时也需要一个自定义的侦听器。

下例会侦听message的数据变化并触发方法

watch默认又两个参数;可以直接在函数中接收

  • newValue 属性的新值

  • oldValue 属性的旧值

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <input type="text" v-model=message>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        const app = new Vue({
            el: '#app',
            data: {
                message:'hello world'
            },
            watch:{
                message:function(newValue,oldValue){
                console.log(this.message);
            }}
        })
    </script>
</body>

</html>

深度监视

watch监视对象只能监视一层,如果对象中还有子对象,则需要使用深度监视

如下面的例子C

var vm = new Vue({
  data: {
    a: 1,
    b: 2,
    c: 3,
    d: 4,
    e: {
      f: {
        g: 5
      }
    }
  },
  watch: {
    a: function (val, oldVal) {
      console.log('new: %s, old: %s', val, oldVal)
    },
    // 方法名
    b: 'someMethod',
    // 该回调会在任何被侦听的对象的 property 改变时被调用,不论其被嵌套多深
    c: {
      handler: function (val, oldVal) { /* ... */ },
      deep: true
    },
    // 该回调将会在侦听开始之后被立即调用
    d: {
      handler: 'someMethod',
      immediate: true
    },
    e: [
      'handle1',
      function handle2 (val, oldVal) { /* ... */ },
      {
        handler: function handle3 (val, oldVal) { /* ... */ },
        /* ... */
      }
    ],
    // watch vm.e.f's value: {g: 5}
    'e.f': function (val, oldVal) { /* ... */ }
  }
})
vm.a = 2 // => new: 2, old: 1

(6) filters 过滤器

详见本系列第四篇第一节

(7) directives 自定义私有指令

详见本系列第三篇第一节

三. 生命周期函数

vue对象的生命周期:

image

1.创建期间的钩子函数

(1) beforeCreated

vue对象创建完成时触发, 还不能访问data和methods

(2)created

vue对象初始化完成时触发

created钩子可以用来在一个实例被创建之后执行代码 可以访问data和methods了

(3) beforeMounted

模板编译完成,在内存中,还没有挂载到页面中去时触发 //{{msg}}还是花括号

(4) mounted

模板编译完成,挂载到了页面中去时触发 //{{msg}}已经被替换成了this.msg的内容

2. 运行期间的钩子函数

(1)beforeUpdated

data数据改变,渲染到页面之前触发

(2)updated

data数据改变并渲染到页面之后触发

3. 销毁阶段

(1)beforeDestroyed

(2)destroyed

四. vue基本语法

1.条件

(1) v-if

v-if指令用于条件性地渲染一块内容。


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

也可以用v-else添加一个“else 块”:


<h1  v-if="awesome">Vue is awesome!</h1>  
<h1  v-else>Oh no 😢</h1>

还有v-else-if,顾名思义,充当v-if的“else-if 块”,可以连续使用

(2) 如何一次性判断多个元素?

因为v-if是一个指令,所以必须将它添加到一个元素上。但是如果想切换多个元素呢?此时可以把一个<template>元素当做不可见的包裹元素,并在上面使用v-if。最终的渲染结果将不包含<template>元素。

(3) 元素复用问题

① 什么是元素复用

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属性即可


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

(4) v-show

v-show指令和v-if用法基本一样

但是v-if用法是“真正”的条件渲染,v-show总是被渲染,只是简单地基于 CSS 进行切换。

2.循环

(1) v-for


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

(2) 第二个参数 index

v-for 还支持一个可选的第二个参数,即当前项的索引。


<ul  id="example-2">  <li  v-for="(item, index) in items"> {{ parentMessage }} - {{ index }} - {{ item.message }} </li>  </ul> var example2 = new Vue({
  el: '#example-2',
  data: {
    parentMessage: 'Parent',
    items: [
      { message: 'Foo' },
      { message: 'Bar' }
    ]
  }
})

(3) v-for遍历对象的属性

你也可以用 v-for 来遍历一个对象的属性。想循环谁就挂在谁身上


<ul  id="v-for-object"  class="demo">  <li  v-for="value in object"> {{ value }} </li>  </ul> new Vue({
  el: '#v-for-object',
  data: {
    object: {
      title: 'How to do lists in Vue',
      author: 'Jane Doe',
      publishedAt: '2016-04-10'
    }
  }
})

注意:为了与ES6风格统一,v-for="value in object"也可以写成v-for="value of object"

你也可以提供第二个的参数为 property 名称 (也就是键名):


<div  v-for="(value, name) in object"> {{ name }}: {{ value }} </div>

你也可以提供第三个的参数为 index 名称 (也就是索引值):


<div  v-for="(value, name,index) in object"> {{ name }}: {{ value }} 索引值{{index}} </div>

(4) 迭代数字


<div  v-for="count in 10"> {{ count }} </div>

(5) 绑定key属性

由于Vue虚拟dom机制问题, 给v-for的标签 绑定key之后会提升性能

组件中使用v-for时,key属性是必须的!!

key必须使用v-bind来绑定,key必须是string或者number 但不要绑定第三个参数 index(由于虚拟DOM算法问题,这样做无意义)


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

没有key会有什么问题? 如下图:我们尝试从数组的头部加项时,会出现r如下问题.这种问题靠key可以解决

image
image

五. vue基本列表渲染

表单输入绑定 — Vue.js​cn.vuejs.org
图标

1. 表单双向数据绑定 用v-model绑定

双向数据绑定,在表单中添加属性v-model=xxx即可

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <h1>{{message}}</h1>
        <input type="text" v-model='message'>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        const app = new Vue({
            el: '#app'
        })
    </script>
</body>

</html>

2. 表单数据单向绑定 //值绑定 v-bind:value

v-bind可以用来动态绑定属性值, 可以把组件的value绑定任意内容或对象.但是这是单项的绑定,data里的值只会影响视图中的值,但视图中的值不会影响data


<input  type="text"  v-model=message> 其值改变时,data里的message会改变,进而下面的标签值亦变 
<input  type="text"  :value=message> 其值改变时,data里的message不会改变

当有v-bind:value时,组件的value失效


<input  type="checkbox"  name=""  v-bind:value="01"  v-model=box1>  
<option  v-bind:value="{ number: 123 }">123</option>

3. selected下拉单选框 //用v-model绑定 ,同时 option里设置好value或者v-bind:value

用v-model绑定select ,同时 option里设置好value,

如果没有设置value则 value=选项文本内容

<div id="example-5">
  <select v-model="selected">
    <option disabled value="">请选择</option>
    <option>A</option>
    <option>B</option>
    <option>C</option>
  </select>
  <span>Selected: {{ selected }}</span>
</div>

new Vue({
  el: '...',
  data: {
    selected: ''
  }
})

如果v-model表达式的初始值未能匹配任何选项,<select>元素将被渲染为“未选中”状态。在 iOS 中,这会使用户无法选择第一个选项。因为这样的情况下,iOS 不会触发 change 事件。因此,更推荐像上面这样提供一个值为空的禁用选项。

例子:计算器


<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <input type="number" v-model=el1>
        <select name="" id="" v-model='opt' value='2'>
            <option value="0" v-on:>+</option>
            <option value="1">-</option>
            <option value="2">*</option>
            <option value="3">/</option>
        </select>
        <input type="number" v-model=el2>
        <button v-on:click="funcE">=</button>
        <span>{{answer}}</span>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        const app = new Vue({
            el: '#app',
            data: {
                el1: 15,
                el2: 2,
                opt: '2',
                answer: 0
            },
            methods: {//方法的处理全方在这里~
                funcE() {
                    console.log(this.opt);

                    switch (this.opt) {
                        case '0':
                            this.answer = this.el1 + this.el2
                            break;
                        case '1':
                            this.answer = this.el1 - this.el2
                            break;
                        case '2':
                            this.answer = this.el1 * this.el2
                            break;
                        case '3':
                            if (this.el2 != 0)
                                this.answer = this.el1 / this.el2
                            else
                                alert('除数为0')
                            break;
                        default:
                            break;
                    }
                }
            }
        })
    </script>
</body>

</html>

4. selected下拉多选框 //用v-model绑定 ,同时 option里设置好value或者v-bind:value 数组接收

和上面基本一致,但是<select>里有了属性 multiple, 可能会选出多个,所以应该数组接收

<div id="example-6">
  <select v-model="selected" multiple>
    <option>A</option>
    <option>B</option>
    <option>C</option>
  </select>
  <br>
  <span>Selected: {{ selected }}</span>
</div>

数组接收


new Vue({
  el: '#example-6',
  data: {
    selected: []
  }
})

5.checkbox单个check框 用v-model


<input  type="checkbox"  id="checkbox"  v-model="checked">  
<label  for="checkbox">{{ checked }}</label>

例:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <input type="checkbox" name="" id="" v-model=box1>
        <p>{{box1}}</p>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        const app = new Vue({
            el: '#app',
            data: {
               box1:true
            }
        })
    </script>
</body>

</html>

6.checkbox单个check框 值绑定 //用v-model绑定,同时复选框里设置好true-value和false-value

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <input type="checkbox" v-model=box1 true-value="yes" false-value="no">
        <p>{{box1}}</p>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        const app = new Vue({
            el: '#app',
            data: {
               box1:"no"
            }
        })
    </script>
</body>

</html>

7. checkbox多个check框 //用v-model绑定,同时每个复选框里设置好value或者v-bind:value,数组接收

<div id='example-3'>
  <input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
  <label for="jack">Jack</label>
  <input type="checkbox" id="john" value="John" v-model="checkedNames">
  <label for="john">John</label>
  <input type="checkbox" id="mike" value="Mike" v-model="checkedNames">
  <label for="mike">Mike</label>
  <br>
  <span>Checked names: {{ checkedNames }}</span>
</div>

可能接收到多个数据,故用数组表示


new Vue({
  el: '#example-3',
  data: {
    checkedNames: []
  }
})

8.单选按钮 //用v-model绑定同一个data,同时每个单选框里设置好value或者v-bind:value

<div id="example-4">
  <input type="radio" id="one" value="One" v-model="picked">
  <label for="one">One</label>
  <br>
  <input type="radio" id="two" value="Two" v-model="picked">
  <label for="two">Two</label>
  <br>
  <span>Picked: {{ picked }}</span>
</div>

new Vue({
  el: '#example-4',
  data: {
    picked: ''
  }
})

9.修饰符

(1) .lazy

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


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

(2) .number

如果想自动将用户的输入值转为数值类型,可以给v-model添加number修饰符:


<input  v-model.number="age"  type="number">

(3) .trim

如果要自动过滤用户输入的首尾空白字符,可以给v-model添加trim修饰符:


<input  v-model.trim="msg">

六. 事件处理

可以用v-on指令监听 DOM 事件,并在触发时运行一些 JavaScript 代码。

v-on:有一个简写:@

v-on:click 等价于 @click

1.注册点击事件 用v-on:click="clickfunc"

vue对象本身包含mothod属性 ,可以把方法声明在其中

注意:方法不能用箭头函数,剪头函数的this不指向vue 实例

但可以使用另一种ES6写法:

func1:function (){} 可以简写成 func1(){}

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <input type="number" v-model=count>
        <button v-on:click="clickfunc">点击+1</button>
        <!-- 用v-on绑定了一个事件,事件名字叫click -->
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        const app = new Vue({
            el: '#app',
            data:{ 
                count:0
            },
            methods:{//方法的处理全方在这里~
                clickfunc:function () {
                    this.count++
                    //方法不能用箭头函数,剪头函数的this不指向vue 实例
                }
            }
        })

    </script>
</body>

</html>

2.(内联版)注册点击事件 用v-on:click="count++"

如果函数执行简单可以直接内联写

三元表达式也可以写内联

<button v-on:click="count= count-1 < 0 ? 0:count-1">-1</button>

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <input type="number" v-model=count>
        <button v-on:click="count++">点击+1</button>
        <!-- 用v-on绑定了一个事件,事件名字叫click -->
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        const app = new Vue({
            el: '#app',
            data:{
                count:0
            }
        })
    </script>
</body>
</html>

3.修饰符

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

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

  • .stop //停止冒泡

  • .prevent //阻止默认事件

  • .capture //采用捕获机制触发事件(反向冒泡,先触发外层的再触发内层的)

  • .self // 只有自己能触发,冒泡不会触发,但还是会继续往上冒泡

  • .once // 只触发一次

  • .passive //

  • .native // 如果是一个自定义组件,那么给它绑定事件时必须加.native

<!-- 阻止单击事件继续传播 -->
<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> 

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

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

<!-- 自定义组件必须加.native -->
<myDiv  v-on:click.native='someThing'></myDiv> 

这个 .passive 修饰符尤其能够提升移动端的性能。
不要把 .passive 和 .prevent 一起使用,因为 .prevent 将会被忽略,同时浏览器可能会向你展示一个
警告。请记住,.passive 会告诉浏览器你不想阻止事件的默认行为。

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

4. 按键修饰符

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


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

Vue 提供了绝大多数常用的按键码的别名:

  • .enter

  • .tab

  • .delete (捕获“删除”和“退格”键)

  • .esc

  • .space

  • .up

  • .down

  • .left

  • .right

除了上述按键码别名,也可以用 按键码来修饰


<input  v-on:keyup.113="submit"> //113代表F2

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

  • .ctrl

  • .alt

  • .shift

  • .meta

  • .exact

<!-- Alt + C -->
<input @keyup.alt.67="clear">

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

<!-- 没有任何系统修饰符被按下的时候才触发 -->
<button @click.exact="onClick">A</button>

5.鼠标修饰符

  • .left

  • .right

  • .middle

这些修饰符会限制处理函数仅响应特定的鼠标按钮。

6.事件对象

事件方法会默认传入一个参数,event

我们编写方法时可以直接接收这个event


 handleIn(e){
                console.log(e);         
            },

此时,我们得到一个event对象

image

这个事件里有好多信息,后续我们会应用.

但是 , 如果调用函数里面有形参,这个参数是不会默认传递的,如果想既传参又传event 则需要在调用时强烈的声明!!!!并在写函数时做好形参接收工作!


<input class="new-todo" 
placeholder="What needs to be done?" 
autofocus v-on:keyup.enter="handleIn(index,$event)" 
v-model="add">

handleIn(index,e){

}

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