事件处理

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. mysql那些事(6) WHERE条件 字符串的引号

    前言:所谓的坑,两个意思,一个是软件本身的bug,一个是使用者常犯的错误. phper在日常开发中经常和mysql打交道.特别是在没有分层的中小应用中,phper开发要关注sql语句的实现. 入正题, ...

  2. tomcat部署项目,详细!

    一.导出war包 1.先导出项目的war包(idea为例) 点+号,选择 之后点ok,确定,关闭窗口,回到idea主页面 在弹出窗口中选择新建的war,选build 之后在war导出目录,找到这个wa ...

  3. JS的Form表单转JSON格式

    一.serialize()方法 格式:var data = $("#formID").serialize(); 功能:将表单内容序列化成一个字符串. 注意:要使用params = ...

  4. 【nodejs原理&源码赏析(7)】【译】Node.js中的事件循环,定时器和process.nextTick

    目录 Event Loop 是什么? Event Loop 基本解释 事件循环阶段概览 事件循环细节 timers pending callbacks poll阶段 check close callb ...

  5. python中for循环删除不全的问题

    以前遇到过一次,删除列表中符合条件的元素,for循环挨个判断是否符合条件,符合就删除,删完结果发现有一个符合条件的没有删掉. 那么如果想删除某些列表中的元素,比如有一个a列表,a=[11,22,33, ...

  6. 60%的人不懂Python进程Process,你懂吗?

    前言本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理.作者:蒋狗    新手注意:如果你Python基础学的不够扎实,遇问题没人解答 ...

  7. Sql Server存储过程详解

    存储过程--查询: if (exists (select * from sys.objects where name = 'GetUser')) drop proc GetUser --判断存储过程是 ...

  8. 打开TXT文件并显示

    <!DOCTYPE html> <html> <head> <title></title> <script> function ...

  9. elasticsearch搜索QueryStringQueryBuilder时的一些问题记录

    首先看下原始数据 但是 如果使用英文查询的时候又和上面有点区别了,感觉还是分词器的问题

  10. Django ContentType 的使用

    引入 一切优化,最终都是关于需求的优化.本文介绍需求确定之后的数据库表结构设计优化. 程序员应该都知道,编程是数据结构和算法的结合.所谓数据就是用户需要访问和操作的资源,比如购物类App里面的商品,图 ...