事件处理

v-on 指令监听 DOM 事件,并在触发时运行一些 JavaScript 代码,示例:

<div id="example-2">
<!-- `greet` 是在下面定义的方法名 -->
<button v-on:click="greet">Greet</button>
</div>
<!-- 点击按钮会依次显示'Hello Vue.js!'和Button>
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!'
  • 事件修饰符

    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>
<!-- 点击事件将只会触发一次 -->
<a v-on:click.once="doThis"></a>
<!-- 滚动事件的默认行为 (即滚动行为) 将会立即触发 -->
<!-- 而不会等待 `onScroll` 完成 -->
<!-- 这其中包含 `event.preventDefault()` 的情况 -->
<div v-on:scroll.passive="onScroll">...</div>

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

  • 其他修饰符(基本用不到,用到了再查文档就行)

    • 按键修饰符
    • 系统修饰符
    • .exact 修饰符
    • 鼠标按钮修饰符

组件基础篇

Vue示例中的data类型:Object | Function;限制:组件的定义只接受 function,这一点尤其需要注意,data详情用法见链接api

例子:

// 定义一个名为 button-counter 的新组件
Vue.component('button-counter', {
data: function () {
return {
count: 0
}
},
template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>'
})
<div id="components-demo">
<button-counter></button-counter>
<button-counter></button-counter>
<button-counter></button-counter>
</div>
  new Vue({ el: '#components-demo' })

同一个组件可以任意次的复用,正是由于data返回的是函数,所以每个实例可以维护一份被返回对象的独立的拷贝,否则,返回的是对象的话,所有的实例将共享引用同一个数据对象,这样显然不合适

  • 组件注册

    • 全局注册

      全局注册的组件可以用在其被注册之后的任何 (通过 new Vue) 新创建的 Vue 根实例,也包括其组件树中的所有子组件的模板中。
    • 局部注册
  • prop

    Prop 是你可以在组件上注册的一些自定义特性,用来传递数据给组件,组件默认可以有任意数量的 prop ,可以用一个 props 选项将其包含在该组件可接受的 prop 列表中,其中v-for迭代数据,v-bind绑定数据,key作为唯一标示区别等用法跟前面基本语法保持一致。

    例子:

    <div id="blog-post-demo" class="demo">
    <blog-post
    v-for="post in posts"
    v-bind:key="post.id"
    v-bind:title="post.title"
    ></blog-post>
    </div>
      Vue.component('blog-post', {
    props: ['title'],
    template: '<h3>{{ title }}</h3>'
    }) new Vue({
    el: '#blog-post-demo',
    data: {
    posts: []
    },
    created: function () {
    // Alias the component instance as `vm`, so that we
    // can access it inside the promise function
    var vm = this
    // Fetch our array of posts from an API
    fetch('https://jsonplaceholder.typicode.com/posts')
    .then(function (response) {
    return response.json()
    })
    .then(function (data) {
    vm.posts = data
    })
    }
    })

    fetch请求的返回数据格式为:

    [
    {
    userId: 1,
    id: 1,
    title: "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
    body: "quia et suscipit suscipit recusandae consequuntur expedita et cum reprehenderit molestiae ut ut quas totam nostrum rerum est autem sunt rem eveniet architecto"
    },
    {
    userId: 1,
    id: 2,
    title: "qui est esse",
    body: "est rerum tempore vitae sequi sint nihil reprehenderit dolor beatae ea dolores neque fugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis qui aperiam non debitis possimus qui neque nisi nulla"
    },
    ]
  • 单个根元素

    组件template部分不能写多个单独的元素,必须用父元素包裹起来。

    错误例子:

      template: '<h3>{{ title }}</h3><h1>abc</h1>'

    正确例子:

      template: '<div class="test"><h3>{{ title }}</h3><h1>abc</h1></div>'

    属性传递多个值示例:

      <blog-post
    v-for="post in posts"
    v-bind:key="post.id"
    v-bind:post="post"
    ></blog-post>
      Vue.component('blog-post', {
    props: ['post'],
    template: `
    <div class="blog-post">
    <h3>{{ post.title }}</h3>
    <div v-html="post.content"></div>
    </div>
    `
    })

    这样传递的post对象的所有属性都可以迭代出来,上面例子中template用到了``这个JavaScript 的模板字符串来写,对于多行书写更优雅一些。

  • 监听子组件事件

    这部分初看很难理解,需要结合实际代码效果多看几遍,也可以参考这个文章

    父级组件可以像处理 native DOM 事件一样通过 v-on 监听子组件实例的任意事件

      <blog-post
    ...
    v-on:enlarge-text="postFontSize += 0.1"
    ></blog-post>

    同时子组件可以通过调用内建的 $emit 方法 并传入事件名称来触发一个事件

      <button v-on:click="$emit('enlarge-text')">
    Enlarge text
    </button>

    有了这个 v-on:enlarge-text="postFontSize += 0.1" 监听器,父级组件就会接收该事件并更新 postFontSize 的值。emit的用法参考api

    可以使用 $emit 的第二个参数来抛出一个特定的值

    <button v-on:click="$emit('enlarge-text', 0.1)">
    Enlarge text
    </button>

    然后当在父级组件监听这个事件的时候,我们可以通过 $event 访问到被抛出的这个值

      <blog-post
    ...
    v-on:enlarge-text="postFontSize += $event"
    ></blog-post>

    或者,如果这个事件处理函数是一个方法:

      <blog-post
    ...
    v-on:enlarge-text="onEnlargeText"
    ></blog-post>

    那么这个值将会作为第一个参数传入这个方法:

      methods: {
    onEnlargeText: function (enlargeAmount) {
    this.postFontSize += enlargeAmount
    }
    }

    解释一下:

      button v-on:click="$emit('enlarge-text', 0.1)"

    这里的button相对于blog-post来说是子组件,所以它的click事件可以抛出让blog-post父组件接收,回调方法可以写在blog-post组件的methods里面定义一个方法名,例如:

      button v-on:click="clickfun"
          methods: {
    clickfun:function () {
    console.log('abc');
    this.$emit('enlarge-text', 0.1);
    }
    }

    通过$emit方法抛出新的自定义的监控方法enlarge-text,然后vue的根实例,即blog-post的父组件通过监听器去接收和回调处理这个方法,emit传出来的0.1被方法的第一个参数接收:

      <blog-post
    ...
    v-on:enlarge-text="sizeLarge"
    ></blog-post>
      methods: {
    sizeLarge:function (value) {
    this.postFontSize += enlargeAmount
    }
    }
  • 组件上使用 v-model(难以理解就后面再看)

        Vue.component('custom-input', {
    props: ['value'],
    template: `
    <input
    v-bind:value="value"
    v-on:input="$emit('input', $event.target.value)"
    >
    `
    })
      <custom-input v-model="searchText"></custom-input>
  • 过插槽分发内容

    和 HTML 元素一样,我们经常需要向一个组件传递内容

      Vue.component('alert-box', {
    template: `
    <div class="demo-alert-box">
    <strong>Error!</strong>
    <slot></slot>
    </div>
    `
    })
  • 动态组件

    示例代码1

    示例代码2

  • 解析 DOM 模板时的注意事项

    有些 HTML 元素,诸如 <ul><ol><table><select>,对于哪些元素可以出现在其内部是有严格限制的。而有些元素,诸如 <li><tr><option>,只能出现在其它某些特定的元素内部。错误示例:

      <table>
    <blog-post-row></blog-post-row>
    </table>

    这个自定义组件 会被作为无效的内容提升到外部,并导致最终渲染结果出错

    正确示例:

    <table>
    <tr is="blog-post-row"></tr>
    </table>

    需要注意的是如果我们从以下来源使用模板的话,这条限制是不存在的:

    • 字符串 (例如:template: '...')
    • 单文件组件 (.vue)
    • <script type="text/x-template">

从零开始的vue学习笔记(三)的更多相关文章

  1. vue学习笔记(三)class和style绑定

    前言 通过上一章的学习vue学习笔记(二)vue的生命周期和钩子函数,我们已经更近一步的知道了关于vue的一些知识,本篇博客将进一步探讨vue其它方面的内容,vue中关于class和style绑定,关 ...

  2. Vue学习笔记三:v-bind,v-on的使用

    目录 v-bind:绑定属性值,内容相当于js,缩写: v-on:绑定方法,缩写@ 总结 v-bind:绑定属性值,内容相当于js,缩写: 我添加了一个input标签,如下 <input typ ...

  3. 从零开始的vue学习笔记(五)

    单文件组件 Vue.component 来定义全局组件的缺点: 全局定义 (Global definitions) 强制要求每个 component 中的命名不得重复 字符串模板 (String te ...

  4. 从零开始的vue学习笔记(一)

    前言 项目要用vue.js,今天开始自学vue.js官方教程,记录下自己的学习摘要,方便后面查阅(此笔记按照学习天数,每天一篇) Vue.js是什么 Vue是一套用于构建用户界面的渐进式框架,Vue ...

  5. 从零开始的vue学习笔记(七)

    前言 今天花一天时间阅读完vuex的官方文档,简单的做一下总结和记录 Vuex是什么 Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式,以前的符合"单向数据流"理念的 ...

  6. 从零开始的vue学习笔记(八)

    前言 今天花一天时间阅读完Vue Router的官方文档的基础部分,简单的做一下总结和记录 Vue Router是什么 Vue Router 是 Vue.js 官方的路由管理器,用于构建单页应用(SP ...

  7. VUE 学习笔记 三 模板语法

    1.插值 a.文本 数据绑定最常见的形式就是使用“Mustache”语法 (双大括号) 的文本插值 <span>Message: {{ msg }}</span> v-once ...

  8. vue学习笔记(三):vue-cli脚手架搭建

    一:安装vue-cli脚手架: 1:为了确保你的node版本在4.*以上,输入 node -v 查看本机node版本,低于4请更新. 2:输入:  npm install -g vue-cli     ...

  9. 从零开始的vue学习笔记(二)

    数据与方法 当一个 Vue 实例被创建时,它将 data 对象中的所有的属性加入到 Vue 的响应式系统中.data的数据和视图同步更新. 实例创建后添加一个新的属性,对这个属性的的改动将不会触发任何 ...

随机推荐

  1. 教你如何关闭IIS服务

    由于IIS服务器和Apache的默认端口号都是80端口,有时我们需要关闭IIS服务,下面讲讲关闭IIS服务的方法.   方法如下:   1.services.msc,在里面找到一个“World Wid ...

  2. 本地Docker Jenkins构建dotnet core web应用到Linux服务器 Docker上

    1.准备工作 环境 本地: Windows.Docker 代码仓库:Git 服务器:Linux.Docker 前提准备 创建个有dockerfile文件的dotnet core 3 web项目 新建一 ...

  3. Netty实现丢弃服务协议(Netty4.X学习一)

    何为丢弃服务(Discard Protocol),丢弃服务就是一个协议,是最简单的协议,它的作用是接受到什么就丢弃什么,它对调试网路状态有一定的用处.基于TCP的丢弃服务,服务器实现了丢弃丢弃协议,服 ...

  4. 一招教你如何修复MySQL slave中继日志损坏问题

    [摘要]MySQL的Crash safe slave是指slave crash后,把slave重新拉起来可以继续从Master进行复制,不会出现复制错误也不会出现数据不一致. PS:华为云数据库特惠专 ...

  5. luogu P3830 [SHOI2012]随机树

    输入格式 输入仅有一行,包含两个正整数 q, n,分别表示问题编号以及叶结点的个数. 输出格式 输出仅有一行,包含一个实数 d,四舍五入精确到小数点后 6 位.如果 q = 1,则 d 表示叶结点平均 ...

  6. luogu P5514 [MtOI2019]永夜的报应

    题目背景 在这世上有一乡一林一竹亭,也有一主一仆一仇敌. 有人曾经想拍下他们的身影,却被可爱的兔子迷惑了心神. 那些迷途中的人啊,终究会消失在不灭的永夜中-- 题目描述 蓬莱山 辉夜(Kaguya)手 ...

  7. Python中 * 与 **, *args 与 **kwargs的用法

    * 用于传递位置参数(positional argument) ** 用于传递关键字参数(keyword argument) 首先,先通过一个简单的例子来介绍 * 的用法: def add_funct ...

  8. CF595 Div31249A,1249B1,1249B2,1249C1,1249C2,1249D1,1249D2,1249E,1249F)题解

    A:水题,先排序,有相连的输出2,否则输出1. #include<bits/stdc++.h> using namespace std; #define pii pair<int,i ...

  9. 小程序如何支持使用 async/await (构建npm版)

    前言 小程序本身是不支持async/await语法的,但有些应用场景,我们使用async/await会使得代码更简洁,也更易于维护,用过都知道是有多爽的.既然小程序不支持,那我们可以借助 fackbo ...

  10. ARTS-S 获取子线程返回值注意事项

    #include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <unistd.h& ...