Vue全家桶之Vue基础(1)

目录

  • 1. 目标
  • 2. Vue概述
  • 3. Vue基本使用
  • 4. Vue模板语法
    • 4.1 指令
      • 4.1.1 v-cloak指令用法
      • 4.1.2 数据填充的三个指令
      • 4.1.3 v-once指令的使用
      • 4.1.4 双向数据绑定指令
      • 4.1.5 事件绑定
      • 4.1.6 属性绑定
      • 4.1.7 绑定内联样式
      • 4.1.8 分支结构
      • 4.1.9 循环结构
  • 5. 基础案例
    • 5.1 Tab选项栏演示效果
    • 5.2 案例: 实现步骤
    • 5.3 示例代码

1. 目标

通过本文,读者可以掌握以下的相关技能:

  1. 能够说出 Vue基本用法
  2. 能够说出 Vue模板语法
  3. 能够说出 Vue常用特性
  4. 能够基于 Vue 实现 案例效果

2. Vue概述

优秀的一款 国产 框架,接下来我们就满怀敬意的去了解一下 Vue 的作者。
Vue全家桶之Vue基础(1)_第1张图片
尤雨溪,著名渐进式 JavaScript 框架 vuejs.org 的创造者,饱含我们程序员的特有气质 。Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的 渐进式框架 (声明式渲染–>组件系统–>客户端路由–>集中式状态管理–>项目构建)。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与 现代化的工具链 以及各种 支持类库 结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。看看下面这张漂亮的 Logo. Vue官网
Vue全家桶之Vue基础(1)_第2张图片
特点:

  1. 易用:熟悉HTML、CSS、 JavaScript知识后,可快速上手Vue。
  2. 灵活:不断繁荣的生态系统,可以在一个库和一套完整框架之间自如伸缩。
  3. 高效:20kB min+gzip 运行大小 超快虚拟DOM 最省心的优化

3. Vue基本使用

接下来和笔者开始 Vue 的基本使用,无论我们学习什么框架,一般都是从最简单的一个案例 (Hello World) 入手,即在页面上显示输出一句 Hello World,案例虽然简单,但是有句话是这么说的 麻雀虽小,五脏俱全. 接下来我们通过这个简单的案例去熟悉 Vue 的基本语法步骤和代码整体的语法结构,另外可以先用传统的方式去实现,接着用 Vue 去重构,体会会更加深刻一点。原生 JS 实现如下图所示:
Vue全家桶之Vue基础(1)_第3张图片
jQuery 实现如下图所示:
Vue全家桶之Vue基础(1)_第4张图片
因为考虑到有些读者不会使用 ES6,所以本文会在某些地方采取ES5 的写法。尽管 jQuery 已经大大地提高了我们的编程体验,但是程序员嘛,对吧就是 懒.
Vue全家桶之Vue基础(1)_第5张图片
所以才有了更加高级的框架诞生,接下来请读者穿上你的滑板鞋,跟着笔者在 Vue 知识的海洋里,摩擦摩擦又摩擦。使用 Vue 开发 Hello World 的基本步骤如下:

  1. 需要提供标签用于填充数据
    Vue全家桶之Vue基础(1)_第6张图片
  2. 引入 vue.js 库文件
  3. 可以使用 vue 的语法做功能了
    Vue全家桶之Vue基础(1)_第7张图片
  4. vue 提供的数据填充到标签中
    Vue全家桶之Vue基础(1)_第8张图片

完整的使用 VueHelloWorld 渲染到页面上示例代码如下:


<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue之Hello Worldtitle>
head>

<body>

    
    <div id="app">
        <div>{{msg}}div>
        <div>{{1+2}}div>
        <div>{{"Amo " + "So " + "Cool~~~"}}div>
    div>

body>

html>
<script src="js/vue.js">script>
<script>
    let vm = new Vue({
        el: "#app", // el: 元素的挂载位置(值可以是CSS选择器或者DOM元素)
        data: { // data: 模型数据(值是一个对象)
            msg: "Hello World"
        }
    });
script>

上述代码执行结果为:
Vue全家桶之Vue基础(1)_第9张图片
Vue 代码运行原理分析:
Vue全家桶之Vue基础(1)_第10张图片

4. Vue模板语法

在学习模板语法之前,我们需要对 前端渲染 有一定的了解。前端渲染:把数据填充到HTML标签中。如下图所示:
Vue全家桶之Vue基础(1)_第11张图片
前端渲染 的方式大致有以下几种:

  1. 原生 js 拼接字符串 基本上就是将数据以字符串的方式拼接到HTML标签中,前端代码风格大体上如下图所示。
    Vue全家桶之Vue基础(1)_第12张图片
    缺点: 不同开发人员的代码风格差别很大,随着业务的复杂,后期的维护变得逐渐困难起来。
  2. 使用前端模板引擎 下方代码是基于模板引擎 art-template 的一段代码,与拼接字符串相比,代码明显规范了很多, 它拥有自己的一套模板语法规则。
    Vue全家桶之Vue基础(1)_第13张图片
    优点: 大家都遵循同样的规则写代码,代码可读性明显提高了,方便后期的维护。 缺点: 没有专门提供事件机制。
  3. 使用 Vue 特有的模板语法:
    • 插值表达式
    • 指令
    • 事件绑定
    • 属性绑定
    • 样式绑定
    • 分支循环结构

4.1 指令

指令的本质就是 自定义属性,指令的格式:以 v- 开始(如v-cloak)

4.1.1 v-cloak指令用法

  1. 插值表达式存在的问题 闪动
  2. 如何解决该问题:使用 v-cloak 指令
  3. 解决该问题的原理:先隐藏,替换好值之后再显示最终的值,示例代码如下:
    Vue全家桶之Vue基础(1)_第14张图片

4.1.2 数据填充的三个指令

  1. v-text 指令用于将数据填充到标签中,作用于插值表达式类似,但是没有闪动问题。如果数据中有 HTML 标签会将 HTML 标签一并输出(即填充纯文本)。注意:此处为单向绑定,数据对象上的值改变,插值会发生变化,但是当插值发生变化并不会影响数据对象的值。示例代码如下:
    Vue全家桶之Vue基础(1)_第15张图片
  2. v-html 用法和 v-text 相似,但是它可以将 HTML 片段填充到标签中。在网站上动态渲染任意 HTML 是非常危险的,因为容易导致 XSS 攻击。只在可信内容上使用 v-html,永不用在用户提交的内容上。它与 v-text 区别在于 v-text 输出的是纯文本,浏览器不会对其再进行 HTML 解析,但 v-html 会将其当 HTML 标签解析后输出。示例代码如下:
    Vue全家桶之Vue基础(1)_第16张图片
  3. v-pre 显示原始信息跳过编译过程,跳过这个元素和它的子元素的编译过程。一些静态的内容不需要编译加这个指令可以加快渲染。示例代码如下:
    Vue全家桶之Vue基础(1)_第17张图片
  4. 上述三个指令的所有代码如下:

<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>数据填充的三个指令title>
head>

<body>
    <div id="app">
        
        <div>{{msg}}div>
        
        <div v-text="msg1">div>
        <div v-html="msg1">div>
        <div>{{msg}}div>
        <div v-pre>{{msg}}div>
    div>
body>

html>
<script src="js/vue.js">script>
<script>
    let vm = new Vue({
        el: "#app",
        data: {
            msg: "

amo so cool~~~

"
, msg1: "

amo so cool~~~

"
} });
script>

4.1.3 v-once指令的使用

在学习 v-once 之前,我们需要了解一下数据的响应式。那么如何理解数据的响应式呢? HTML5 中的响应式(屏幕尺寸的变化导致样式的变化) 。数据 的响应式(数据的变化导致页面内容的变化)。数据绑定指的是将数据填充到标签中,例如在 4.1.2 中学习的三个指令,v-once 只编译一次,显示内容之后不再具有响应式功能。示例代码如下:

v-once 执行 一次性 的插值,当数据改变时,插值处的内容不会继续更新。视频讲解如下:

v-once指令讲解

4.1.4 双向数据绑定指令

什么是双向数据绑定? 如下图所示:
Vue全家桶之Vue基础(1)_第18张图片
双向数据绑定分析,需要使用到 v-model 指令,用法如下:
Vue全家桶之Vue基础(1)_第19张图片
关于双向数据绑定,还有一个非常重要的概念与之相关,其实就是所谓的 MVVM 设计思想,也是 Vue 比较核心的思想。简单理解是 分而治之,就是将不同功能的代码放到不同的模块中,在以特定的方式让它们建立起关联。如下图所示:
Vue全家桶之Vue基础(1)_第20张图片

4.1.5 事件绑定

Vue 如何处理事件? 语法格式如下:


<input type="button" v-on:click="num++" value="点击">

<input type="button" @click="num++" value="点击1">

事件函数的调用方式,如下:


<input type="button" @click="handle1" value="点击2">

<input type="button" @click="handle1()" value="点击3">

完整示例代码如下:


<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>事件基本用法title>
head>

<body>
    <div id="app">
        <div>{{num}}div>
        <input type="button" v-on:click="num++" value="点击">
        
        <input type="button" @click="num++" value="点击1">
        
        
        <input type="button" @click="handle1" value="点击2">
        
        <input type="button" @click="handle1()" value="点击3">
    div>
body>

html>
<script src="js/vue.js">script>
<script>
    let vm = new Vue({
        el: "#app",
        data: {
            num: 0
        },
        methods: {
            handle1: function() {
                //注意这里要写上this 否则是没有效果的
                this.num++;
            }
        }
    });
script>

事件函数参数传递,普通参数和事件对象,示例代码如下:


<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>事件函数传参title>
head>

<body>
    <div id="app">
        <div>{{num}}div>
        
        <button @click="handle1">传参1button>
        
        <button @click="handle2(1,2,3,$event)">传参2button>
    div>
body>

html>
<script src="js/vue.js">script>
<script>
    let vm = new Vue({
        el: "#app",
        data: {
            num: 0
        },
        methods: {
            handle1: function(event) {
                this.num++;
                //输出打印标签名字
                console.log(event.target.tagName);
                //输出标签中的内容
                console.log(event.target.innerHTML);
            },
            handle2: function(p, p1, p2, event) {
                console.log(p, p1, p2);
                console.log(event.target.tagName);
            }
        }
    });
script>

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

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

  1. stop
  2. prevent
  3. capture
  4. self
  5. once
  6. 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>



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


<a v-on:click.once="doThis">a>

不像其它只能对原生的 DOM 事件起作用的修饰符,.once 修饰符还能被用到自定义的组件事件上。

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


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

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

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

在上述示例中,处理函数只会在 $event.key 等于 PageDown 时被调用。使用 keyCode attribute 也是允许的:

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

keyCode 的事件用法已经被废弃了并可能不会被最新的浏览器支持。为了在必要的情况下支持旧浏览器,Vue 提供了绝大多数常用的按键码的别名:

  1. enter
  2. tab
  3. delete (捕获 删除退格 键)
  4. esc
  5. space
  6. up
  7. down
  8. left
  9. right

有一些按键 (.esc 以及所有的方向键) 在 IE9 中有不同的 key 值, 如果你想支持 IE9,这些内置的别名应该是首选。 你还可以通过全局 config.keyCodes 对象 自定义按键修饰符别名

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

按键修饰符的案例如下:


<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>按键修饰符title>
head>

<body>
    <div id="app">
        <form action="">
            <div>
                用户名:
                <input type="text" v-model="uname" v-on:keyup.delete="clearContent">
            div>
            <div>
                密码:
                <input type="text" v-model="upsd" v-on:keyup.enter="handleSubmit">
                
                
            div>
            <div>
                <input type="button" value="提交" v-on:click="handleSubmit">
            div>
            <div>
                <input type="text" v-on:keyup="handle">
            div>
        form>
    div>
body>

html>
<script src="js/vue.js">script>
<script>
    Vue.config.keyCodes.aaa = 13; //自定义键位别名
    let vm = new Vue({
        el: "#app",
        data: {
            uname: "",
            upsd: ""
        },
        methods: {
            //按delete键位的时候 清空用户名
            clearContent: function() {
                this.uname = "";
            },
            handleSubmit: function() {
                console.log(this.uname, this.upsd);
            },
            handle: function(event) {
                console.log(event.keyCode);
            }
        }
    });
script>

在学习了上面的知识之后,我们可以去做一个关于加法计算器的小案例,请看下面视频讲解:

加法计算器小案例.mp4


为什么在 HTML 中监听事件? 你可能注意到这种事件监听的方式违背了关注点分离(separation of concern) 这个长期以来的优良传统。但不必担心,因为所有的 Vue.js 事件处理方法和表达式都严格绑定在当前视图的 ViewModel上,它不会导致任何维护上的困难。实际上,使用 v-on 有几个好处:

  1. 扫一眼 HTML 模板便能轻松定位在 JavaScript 代码里对应的方法。
  2. 因为你无须在 JavaScript 里手动绑定事件,你的 ViewModel 代码可以是非常纯粹的逻辑,和 DOM 完全解耦,更易于测试。
  3. 当一个 ViewModel 被销毁时,所有的事件处理器都会自动被删除。你无须担心如何清理它们。

4.1.6 属性绑定

基本用法: 如绑定 a 标签中的 href 属性,通过点击 button 切换 url 的地址,实现不同的跳转,示例代码如下:
Vue全家桶之Vue基础(1)_第21张图片
在学习了基本的属性绑定使用之后,我们大致就能够知道 v-model 的实现原理了,html 结构如下:

<body>
    <div id="app">
        <div>
            <div>{{msg}}div>
            <input type="text" v-bind:value="msg" v-on:input="handle">
            <input type="text" v-bind:value="msg" v-on:input="msg=$event.target.value">
            <input type="text" v-model="msg">
        div>
    div>
body>

js 代码如下:

<script src="js/vue.js"></script>
<script>
    let vm = new Vue({
        el: "#app",
        data: {
            msg: "HelloWorld"
        },
        methods: {
            handle: function(event) {
                //使用输入域中最新的数据覆盖原来的数据
                this.msg = event.target.value;
            }
        }
    });
</script>

操作元素的 class 列表和 内联样式 是数据绑定的一个常见需求。因为它们都是 attribute,所以我们可以用 v-bind 处理它们:只需要通过表达式计算出字符串结果即可。不过,字符串拼接麻烦且易错。因此,在将 v-bind 用于 classstyle 时,Vue.js 做了专门的增强。表达式结果的类型除了字符串之外,还可以是 对象数组

对象语法: 我们可以传给 v-bind:class 一个对象,以动态地切换 class

<div v-bind:class="{ active: isActive }">div>

你可以在对象中传入更多字段来动态切换多个 class。此外,v-bind:class 指令也可以与普通的 class attribute 共存。当有如下模板:

<div
  class="static"
  v-bind:class="{ active: isActive, 'text-danger': hasError }"
>div>

和如下 data

data: {
  isActive: true,
  hasError: false
}

结果渲染为:

<div class="static active">div>

isActive 或者 hasError 变化时,class 列表将相应地更新。例如,如果 hasError 的值为 trueclass 列表将变为 "static active text-danger"。绑定的数据对象不必内联定义在模板里:
Vue全家桶之Vue基础(1)_第22张图片
渲染的结果和上面一样。
数组语法:我们可以把一个数组传给 v-bind:class,以应用一个 class 列表:
Vue全家桶之Vue基础(1)_第23张图片
渲染为:

<div class="active text-danger">div>

如果你也想根据条件切换列表中的 class,可以用三元表达式:

<div v-bind:class="[isActive ? activeClass : '', errorClass]">div>

这样写将始终添加 errorClass,但是只有在 isActivetruthy 时才添加 activeClass。不过,当有多个条件 class 时这样写有些繁琐。所以在数组语法中也可以使用对象语法:

<div v-bind:class="[{ active: isActive }, errorClass]">div>

4.1.7 绑定内联样式

v-bind:style 的对象语法十分直观——看着非常像 CSS,但其实是一个 JavaScript 对象。CSS property 名可以用 驼峰式(camelCase) 或 短横线 分隔 (kebab-case,记得用引号 括起来) 来命名:

<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }">div>
data: {
  activeColor: 'red',
  fontSize: 30
}

直接绑定到一个样式对象通常更好,这会让模板更清晰:

<div v-bind:style="styleObject">div>
data: {
  styleObject: {
    color: 'red',
    fontSize: '13px'
  }
}

v-bind:style 的数组语法可以将多个样式对象应用到同一个元素上:

<div v-bind:style="[baseStyles, overridingStyles]">div>

v-bind:style 使用需要添加浏览器引擎前缀的 CSS property 时,如 transformVue.js 会自动侦测并添加相应的前缀。

4.1.8 分支结构

v-if 指令用于 条件性 地渲染一块内容。这块内容只会在指令的表达式返回 truthy 值的时候被渲染。示例代码如下:
Vue全家桶之Vue基础(1)_第24张图片
因为 v-if 是一个指令,所以必须将它添加到一个元素上。但是如果想切换多个元素呢?此时可以把一个