爱前端

Vue.js 基础入门

懒癌发作了好久,一直没有更新文章,罪过罪过,这段时间没更博但也没闲着,新注册了域名(备案中),计划憋个大招,小伙伴们敬请期待···

当然,技术上也不能停滞,该学还是要学习,想必大家近来都看过那篇文章 《2016年里做前端是怎样一种体验》,又被这文章里面提到的种种技术模糊了视线,别拦我让我哭会···

好了,哭完了我们继续说这篇文章,文章里面提及了好多前端相关的新技术,新框架,新工具,那作为一名与(bu)时(xue)俱(bu)进(xing)的前端开发人员,当然要马不停蹄的学习啊,这篇文章是近几天学习 Vue.js 的一些笔记,高手请绕行。

Vue.js 介绍

Vue.js 官网上有一句话是 数据驱动的组件,为现代化的 Web 界面而生,Vue.js 是一个轻巧、高性能、可组件化的MVVM库

一、Vue.js 安装

1、命令行工具

Vue.js 的安装十分方便,Vue.js 提供一个官方命令行工具 vue-cli ,可用于快速搭建大型单页应用。

# 全局安装 vue-cli
# 安装过慢或出错,可使用淘宝镜像
# npm install -g cnpm --registry=https://registry.npm.taobao.org
# cnpm install -g vue-cli
$ npm install --global vue-cli
# 创建一个基于 webpack 模板的新项目
$ vue init webpack my-project
# 安装依赖,走你
$ cd my-project
$ npm install
$ npm run dev

2、独立使用

Vue.js 还支持独立使用,即把 Vue.js 作为外部 js 文件引入使用,大型项目里面不建议这么干哦。

二、模板语法

1、文本

Vue.js 使用了基于 HTML 的模版语法,允许开发者声明式地将 DOM 绑定至底层 Vue 实例的数据。所有 Vue.js 的模板都是合法的 HTML ,所以能被遵循规范的浏览器和 HTML 解析器解析。

在底层的实现上, Vue 将模板编译成虚拟 DOM 渲染函数。结合响应系统,在应用状态改变时, Vue 能够智能地计算出重新渲染组件的最小代价并应用到 DOM 操作上。

如果你熟悉虚拟 DOM 并且偏爱 JavaScript 的原始力量,你也可以不用模板,直接写渲染(render)函数,使用可选的 JSX 语法。

Vue.js 支持双向数据绑定,数据绑定是通过 {{ xxxx }} 的形式来传递的( “Mustache” 语法)。

2、属性

Mustache 不能在 HTML 属性中使用,应使用 v-bind 指令。

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

3、使用 Javascript 表达式

Vue.js 支持简单的 Javascript 表达式

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

4、过滤器

Vue.js 允许你自定义过滤器,被用作一些常见的文本格式化。过滤器应该被添加在 mustache 插值的尾部,由“管道符”指示:

{{ message | capitalize }}

Vue 2.x 中,过滤器只能在 mustache 绑定中使用。为了在指令绑定中实现同样的行为,应该使用计算属性。

三、指令

敲黑板,这部分是 Vue.js 基础里面的重点,务必把握的部分。

指令(Directives)是带有v-前缀的特殊属性。指令属性的值预期是单一JavaScript表达式(除了v-for,之后再讨论)。指令的职责就是当其表达式的值改变时相应地将某些行为应用到 DOM 上

1、v-text 与 v-html

v-text 更新元素的内容,内容为纯文本,不解析。v-html 更新元素的 html 内容,内容为 html,会按照html 标签解析。 二者的区别类似于 innerText 与 innerHTML 的区别。

2、v-if 与 v-show 与 v-else

  • v-if 根据表达式的值的真假条件渲染元素。在切换时元素及它的数据绑定 / 组件被销毁并重建
  • v-show 根据表达式之真假值,切换元素的 display CSS 属性。
  • v-else 元素必须立即跟在 v-if 或 v-show 元素的后面——否则它不能被识别。

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

v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做——在条件第一次变为真时才开始局部编译(编译会被缓存起来)。

相比之下, v-show 简单得多——元素始终被编译并保留,只是简单地基于 CSS 切换。

一般来说, v-if 有更高的切换消耗而 v-show 有更高的初始渲染消耗。因此,如果需要频繁切换 v-show 较好,如果在运行时条件不大可能改变 v-if 较好。

3、v-for

v-for 用于多条数据的遍历渲染

<ul>
    <li v-for="item in items">
        {{ item.text }}
    </li>
</ul>

A: 遍历的数据是数组,v-for 还支持一个可选的第二个参数为当前项的索引

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

执行结果如下:

B: 遍历的数据是 Object 对象,v-for 还支持一个可选的第二个参数为键名,第三个参数为索引

new Vue({
    el: '#repeat-object',
    data: {
        object: {
            FirstName: 'John',
            LastName: 'Doe',
            Age: 30
        }
    }
})
<ul id="repeat-object">
    <li v-for="(value, key, index) in object">
        {{ index }}-{{ key }}:{{ value }}
    </li>
</ul>

执行结果如下:

4、v-on

v-on 绑定事件监听器。

  • 事件类型由参数指定。表达式可以是一个方法的名字或一个内联语句,如果没有修饰符也可以省略。
  • 用在普通元素上时,只能监听 原生 DOM 事件。用在自定义元素组件上时,也可以监听子组件触发的自定义事件。
  • 在监听原生 DOM 事件时,方法以事件为唯一的参数。如果使用内联语句,语句可以访问一个 $event 属性:

v-on 绑定的事件有修饰符可用:

  • .stop - 调用 event.stopPropagation()。
  • .prevent - 调用 event.preventDefault()。
  • .capture - 添加事件侦听器时使用 capture 模式。
  • .self - 只当事件是从侦听器绑定的元素本身触发时才触发回调。
  • .{keyCode | keyAlias} - 只当事件是从侦听器绑定的元素本身触发时才触发回调。
  • .native - 监听组件根元素的原生事件。

v-on 绑定有简写的方法 省略 v-on: 写为 @

来看几个示例

<!-- 方法处理器 -->
<button v-on:click="doThis"></button>
<!-- 内联语句 -->
<button v-on:click="doThat('hello', $event)"></button>
<!-- 缩写 -->
<button @click="doThis"></button>
<!-- 停止冒泡 -->
<button @click.stop="doThis"></button>
<!-- 阻止默认行为 -->
<button @click.prevent="doThis"></button>
<!-- 阻止默认行为,没有表达式 -->
<form @submit.prevent></form>
<!--  串联修饰符 -->
<button @click.stop.prevent="doThis"></button>
<!-- 键修饰符,键别名 -->
<input @keyup.enter="onEnter">
<!-- 键修饰符,键代码 -->
<input @keyup.13="onEnter">

自定义组件可以绑定自定义事件,例如:

<my-component @my-event="handleThis"></my-component>
<!-- 内联语句 -->
<my-component @my-event="handleThis(123, $event)"></my-component>
<!-- 组件中的原生事件 -->
<my-component @click.native="onClick"></my-component>

5、v-bind

  • 动态地绑定一个或多个特性,或一个组件 prop 到表达式。
  • 在绑定 class 或 style 特性时,支持其它类型的值,如数组或对象。
  • 在绑定 prop 时,prop 必须在子组件中声明。可以用修饰符指定不同的绑定类型。
  • 没有参数时,可以绑定到一个包含键值对的对象。注意此时 class 和 style 绑定不支持数组和对象。

可以简写 v-bind,把 v-bind: 简写为 :

示例:

<!-- 绑定一个属性 -->
<img v-bind:src="imageSrc">
<!-- 缩写 -->
<img :src="imageSrc">
<!-- class 绑定 -->
<div :class="{ red: isRed }"></div>
<div :class="[classA, classB]"></div>
<div :class="[classA, { classB: isB, classC: isC }]"></div>
<!-- style 绑定 -->
<div :style="{ fontSize: size + 'px' }"></div>
<div :style="[styleObjectA, styleObjectB]"></div>
<!-- 绑定一个有属性的对象 -->
<div v-bind="{ id: someProp, 'other-attr': otherProp }"></div>
<!-- 通过 prop 修饰符绑定 DOM 属性 -->
<div v-bind:text-content.prop="text"></div>
<!-- prop 绑定. “prop” 必须在 my-component 中声明。 -->
<my-component :prop="someThing"></my-component>
<!-- XLink -->
<svg><a :xlink:special="foo"></a></svg>

6、v-model

v-model 用来监控表单控件的变化,在表单控件或组件上实现双向绑定,适用于 <input><textarea><select> 三个原生标签和自定义组件。

7、v-pre

跳过这个元素和它的子元素的编译过程。可以用来显示标签内容本身有 {{}} 的情况。跳过大量没有指令的节点会加快编译。

8、v-cloak

这个指令保持在元素上直到关联实例结束编译。和 CSS 规则如 [v-cloak] { display: none } 一起用时,这个指令可以隐藏未编译的 Mustache 标签直到实例准备完毕。

9、v-once

只渲染元素和组件一次。随后的重新渲染,元素/组件及其所有的子节点将被视为静态内容并跳过。这可以用于优化更新性能。

四、组件之间传参

组件(Component)是 Vue.js 最强大的功能之一。组件可以扩展 HTML 元素,封装可重用的代码。在较高层面上,组件是自定义元素, Vue.js 的编译器为它添加特殊功能。在有些情况下,组件也可以是原生 HTML 元素的形式,以 is 特性扩展。

1、父向子组件传参

参数以属性的形式存在,这种形式的关键是在子组件里面要选择子组件要接收的参数,需要使用 props 属性显式的引入该参数,例:

父组件:

<template>
    <div class="hello">
        <h1 v-text="title"></h1>
        <List formFaHello="Hello form father!!!"></List>
    </div>
</template>
import List from './components/List';

export default {
    name: 'hello',
    data () {
        return {
            title: 'This is a vue todoList!'
        }
    },
    components: { List }
}

其中我们要传给子组件 List formFaHello 参数,这里作为 List 的属性存在,父组件要引入子组件,通过 components

子组件:

<p>{{ formFaHello }}</p>
export default {
    name: 'list',
    props: [ 'formFaHello' ]
}

子组件 List 为了能接收到 formFaHello 参数,要通过 props 来标记接收的参数,以数组形式存在哦!

这样我们就可以在页面里面看到 Hello form father!!! 这句话了。

2、子向父组件传参

我们把子组件换为如下

<p>
    {{ childWords }}
</p>