Vue.js是什么

Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。

安装

Vue 不支持 IE8 及以下版本,因为 Vue 使用了 IE8 无法模拟的 ECMAScript 5 特性。但它支持所有兼容 ECMAScript 5 的浏览器。

Vue Devtools

在使用 Vue 时,推荐在你的浏览器上安装 Vue Devtools。它允许你在一个更友好的界面中审查和调试 Vue 应用。

直接用<script>引入

直接下载并用script标签引入,Vue 会被注册为一个全局变量。

对于制作原型或学习,你可以这样使用最新版本:

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

对于生产环境,我们推荐链接到一个明确的版本号和构建文件,以避免新版本造成的不可预期的破坏:

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

如果你使用原生 ES Modules,这里也有一个兼容 ES Module 的构建文件:

1
2
3
<script type="module">
import Vue from 'https://cdn.jsdelivr.net/npm/vue@2.6.11/dist/vue.esm.browser.js'
</script>

可以在 cdn.jsdelivr.net/npm/vue 浏览 NPM 包的源代码

NPM

在用 Vue 构建大型应用时推荐使用 NPM 安装。NPM 能很好地和诸如 webpackBrowserify 模块打包器配合使用。同时 Vue 也提供配套工具来开发单文件组件

1
$ npm install vue -g

命令行工具

Vue 提供了一个官方的 CLI,为单页面应用 (SPA) 快速搭建繁杂的脚手架。它为现代前端工作流提供了 batteries-included 的构建设置。只需要几分钟的时间就可以运行起来并带有热重载、保存时 lint 校验,以及生产环境可用的构建版本。更多详情可查阅 Vue CLI 的文档

1
$ npm install -g @vue/cli

关于旧版本

Vue CLI 的包名称由 vue-cli 改成了 @vue/cli。 如果你已经全局安装了旧版本的 vue-cli (1.x 或 2.x),你需要先通过 npm uninstall vue-cli -gyarn global remove vue-cli 卸载它。

Node 版本要求

Vue CLI 需要 Node.js 8.9 或更高版本 (推荐 8.11.0+)。你可以使用 nvmnvm-windows 在同一台电脑中管理多个 Node 版本。

1
vue --version	#查看版本信息是否安装成功

创建项目

1
$ vue create hello-world

警告

如果你在 Windows 上通过 minTTY 使用 Git Bash,交互提示符并不工作。你必须通过 winpty vue.cmd create hello-world 启动这个命令。不过,如果你仍想使用 vue create hello-world,则可以通过在 ~/.bashrc 文件中添加以下行来为命令添加别名。 alias vue='winpty vue.cmd' 你需要重新启动 Git Bash 终端会话以使更新后的 bashrc 文件生效。

你会被提示选取一个 preset。你可以选默认的包含了基本的 Babel + ESLint 设置的 preset,也可以选“手动选择特性”来选取需要的特性。

~/.vuerc

被保存的 preset 将会存在用户的 home 目录下一个名为 .vuerc 的 JSON 文件里。如果你想要修改被保存的 preset / 选项,可以编辑这个文件。

在项目创建的过程中,你也会被提示选择喜欢的包管理器或使用淘宝 npm 镜像源以更快地安装依赖。这些选择也将会存入 ~/.vuerc

查看帮助:

1
$ vue create --help

使用图形化界面

1
$ vue ui

会在浏览器启动一个图形化界面来创建项目,也可以通过此命令来图形化管理项目。

拉取 2.x 模板 (旧版本)

Vue CLI >= 3 和旧版使用了相同的 vue 命令,所以 Vue CLI 2 (vue-cli) 被覆盖了。如果你仍然需要使用旧版本的 vue init 功能,你可以全局安装一个桥接工具:

1
2
3
$ npm install -g @vue/cli-init
## `vue init` 的运行效果将会跟 `vue-cli@2.x` 相同
vue init webpack my-project

插件和 Preset

插件

Vue CLI 使用了一套基于插件的架构。如果你查阅一个新创建项目的 package.json,就会发现依赖都是以 @vue/cli-plugin- 开头的。插件可以修改 webpack 的内部配置,也可以向 vue-cli-service 注入命令。在项目创建的过程中,绝大部分列出的特性都是通过插件来实现的。

基于插件的架构使得 Vue CLI 灵活且可扩展。

可以通过 vue ui 命令使用 GUI 安装和管理插件。

在现有的项目中安装插件

每个 CLI 插件都会包含一个 (用来创建文件的) 生成器和一个 (用来调整 webpack 核心配置和注入命令的) 运行时插件。当你使用 vue create 来创建一个新项目的时候,有些插件会根据你选择的特性被预安装好。如果你想在一个已经被创建好的项目中安装一个插件,可以使用 vue add 命令:

1
$ vue add @vue/eslint

提示

vue add 的设计意图是为了安装和调用 Vue CLI 插件。这不意味着替换掉普通的 npm 包。对于这些普通的 npm 包,你仍然需要选用包管理器。

警告

我们推荐在运行 vue add 之前将项目的最新状态提交,因为该命令可能调用插件的文件生成器并很有可能更改你现有的文件。

这个命令将 @vue/eslint 解析为完整的包名 @vue/cli-plugin-eslint,然后从 npm 安装它,调用它的生成器。

如果不带 @vue 前缀,该命令会换作解析一个 unscoped 的包。例如以下命令会安装第三方插件 vue-cli-plugin-apollo

1
2
## 安装并调用 vue-cli-plugin-apollo
$ vue add apollo

你也可以基于一个指定的 scope 使用第三方插件。例如如果一个插件名为 @foo/vue-cli-plugin-bar,你可以这样添加它:

1
$ vue add @foo/bar

你可以向被安装的插件传递生成器选项 (这样做会跳过命令提示):

1
vue add eslint --config airbnb --lintOn save

如果一个插件已经被安装,你可以使用 vue invoke 命令跳过安装过程,只调用它的生成器。这个命令会接受和 vue add 相同的参数。

项目本地的插件

如果你需要在项目里直接访问插件 API 而不需要创建一个完整的插件,你可以在 package.json 文件中使用 vuePlugins.service 选项:

1
2
3
4
5
{
"vuePlugins": {
"service": ["my-commands.js"]
}
}

Preset

一个 Vue CLI preset 是一个包含创建新项目所需预定义选项和插件的 JSON 对象,让用户无需在命令提示中选择它们。

vue create 过程中保存的 preset 会被放在你的 home 目录下的一个配置文件中 (~/.vuerc)。你可以通过直接编辑这个文件来调整、添加、删除保存好的 preset。

这里有一个 preset 的示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
{
"useConfigFiles": true,
"cssPreprocessor": "sass",
"plugins": {
"@vue/cli-plugin-babel": {},
"@vue/cli-plugin-eslint": {
"config": "airbnb",
"lintOn": ["save", "commit"]
},
"@vue/cli-plugin-router": {},
"@vue/cli-plugin-vuex": {}
}
}

Preset 的数据会被插件生成器用来生成相应的项目文件。除了上述这些字段,你也可以为集成工具添加配置:

1
2
3
4
5
6
7
8
9
10
{
"useConfigFiles": true,
"plugins": {...},
"configs": {
"vue": {...},
"postcss": {...},
"eslintConfig": {...},
"jest": {...}
}
}

这些额外的配置将会根据 useConfigFiles 的值被合并到 package.json 或相应的配置文件中。例如,当 "useConfigFiles": true 的时候,configs 的值将会被合并到 vue.config.js 中。

Preset 插件的版本管理

你可以显式地指定用到的插件的版本:

1
2
3
4
5
6
7
8
{
"plugins": {
"@vue/cli-plugin-eslint": {
"version": "^3.0.0",
// ... 该插件的其它选项
}
}
}

注意对于官方插件来说这不是必须的——当被忽略时,CLI 会自动使用 registry 中最新的版本。不过我们推荐为 preset 列出的所有第三方插件提供显式的版本范围。

允许插件的命令提示

每个插件在项目创建的过程中都可以注入它自己的命令提示,不过当你使用了一个 preset,这些命令提示就会被跳过,因为 Vue CLI 假设所有的插件选项都已经在 preset 中声明过了。

在有些情况下你可能希望 preset 只声明需要的插件,同时让用户通过插件注入的命令提示来保留一些灵活性。

对于这种场景你可以在插件选项中指定 "prompts": true 来允许注入命令提示:

1
2
3
4
5
6
7
8
{
"plugins": {
"@vue/cli-plugin-eslint": {
// 让用户选取他们自己的 ESLint config
"prompts": true
}
}
}

远程 Preset

你可以通过发布 git repo 将一个 preset 分享给其他开发者。这个 repo 应该包含以下文件:

  • preset.json: 包含 preset 数据的主要文件(必需)。
  • generator.js: 一个可以注入或是修改项目中文件的 Generator
  • prompts.js 一个可以通过命令行对话为 generator 收集选项的 prompts 文件

发布 repo 后,你就可以在创建项目的时候通过 --preset 选项使用这个远程的 preset 了:

1
2
## 从 GitHub repo 使用 preset
vue create --preset username/repo my-project

GitLab 和 BitBucket 也是支持的。如果要从私有 repo 获取,请确保使用 --clone 选项:

1
2
vue create --preset gitlab:username/repo --clone my-project
vue create --preset bitbucket:username/repo --clone my-project

加载文件系统中的 Preset

当开发一个远程 preset 的时候,你必须不厌其烦的向远程 repo 发出 push 进行反复测试。为了简化这个流程,你也可以直接在本地测试 preset。如果 --preset 选项的值是一个相对或绝对文件路径,或是以 .json 结尾,则 Vue CLI 会加载本地的 preset:

1
2
3
4
5
## ./my-preset 应当是一个包含 preset.json 的文件夹
vue create --preset ./my-preset my-project

## 或者,直接使用当前工作目录下的 json 文件:
vue create --preset my-preset.json my-project

开始

你可以使用 vue servevue build 命令对单个 *.vue 文件进行快速原型开发,不过这需要先额外安装一个全局的扩展:

1
npm install -g @vue/cli-service-global

vue serve 的缺点就是它需要安装全局依赖,这使得它在不同机器上的一致性不能得到保证。因此这只适用于快速原型开发。

vue serve

1
2
3
4
5
6
7
8
9
10
Usage: serve [options] [entry]

在开发环境模式下零配置为 .js 或 .vue 文件启动一个服务器


Options:

-o, --open 打开浏览器
-c, --copy 将本地 URL 复制到剪切板
-h, --help 输出用法信息

你所需要的仅仅是一个 App.vue 文件:

1
2
3
<template>
<h1>Hello!</h1>
</template>

然后在这个 App.vue 文件所在的目录下运行:

1
vue serve

vue serve 使用了和 vue create 创建的项目相同的默认设置 (webpack、Babel、PostCSS 和 ESLint)。它会在当前目录自动推导入口文件——入口可以是 main.jsindex.jsApp.vueapp.vue 中的一个。你也可以显式地指定入口文件:

1
vue serve MyComponent.vue

如果需要,你还可以提供一个 index.htmlpackage.json、安装并使用本地依赖、甚至通过相应的配置文件配置 Babel、PostCSS 和 ESLint。

vue build

1
2
3
4
5
6
7
8
9
10
11
Usage: build [options] [entry]

在生产环境模式下零配置构建一个 .js 或 .vue 文件


Options:

-t, --target <target> 构建目标 (app | lib | wc | wc-async, 默认值:app)
-n, --name <name> 库的名字或 Web Components 组件的名字 (默认值:入口文件名)
-d, --dest <dir> 输出目录 (默认值:dist)
-h, --help 输出用法信息

你也可以使用 vue build 将目标文件构建成一个生产环境的包并用来部署:

1
vue build MyComponent.vue

vue build 也提供了将组件构建成为一个库或一个 Web Components 组件的能力。查阅构建目标了解更多。

其他

在项目目录下使用

1
npm run build

来构建,使用

1
npm run serve

来调试和预览效果。

创建实例

每个 Vue 应用都需要通过实例化 Vue 来实现。

语法格式如下:

1
2
3
var vm = new Vue({
// 选项
})

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>hello world</title>
</head>
<body>
<div id="app">
<div class="">
{{ msg }}
</div>
</div>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
msg: 'hello world',
}
});
</script>
</body>
</html>

可以看到在 Vue 构造器中有一个el 参数,它是 DOM 元素中的 id

和传统的开发模式相比:

1
2
3
4
5
6
<div id="msg"></div>
<script type="text/javascript">
var msg = 'hello world';
var div = document.getElementById('msg');
div.innerHTML = msg;
</script>

使用步骤

  1. 提供标签用于填充数据
  2. 引入vue.js文件
  3. 创建vue实例,使用vue语法功能
  4. 将vue提供的数据填充到标签中

在新建vue对象时,需要传入参数eldata ,双花括号 {{ }} 就是插值

  • el 参数:元素的挂载位置,值可以是CSS选择器或者DOM元素
  • data 参数:模型数据,值是一个对象
  • {{ }} :插值表达式,可以将数据填充到HTML标签中,且支持简单的计算操作,例如:{{1 + 2}} 或者字符串拼接{{'hello' + 'world'}}

模板语法

前端渲染

模板+数据=>渲染==静态内容

模板语法概览

  • 插值表达式
  • 指令
  • 事件绑定
  • 属性绑定
  • 样式绑定
  • 分支循环结构

指令

指令的本质就是自定义属性,指令一般以v- 开头,比如v-cloak

v-cloak指令用法

插值表达式存在一个问题,就是它是先显示<div> 中的内容再替换成它的值,如果数据较多,资源较复杂就会存在延迟和内容闪动,就可以使用v-cloak 指令解决。

原理就是先隐藏该区块内容,等替换好值之后再显示最终的值。

  1. 提供样式

    1
    2
    3
    [v-cloak]{
    display: none;
    }
  2. 在插值表达式所在的标签中添加指令

    1
    2
    3
    4
    5
    6
    7
    8
    9
    <style type="text/css">
    [v-cloak]{
    display: none;
    }
    </style>
    //---------------------------分割线
    <div id="app">
    <div v-cloak>{{msg}}</div>
    </div>

数据绑定指令

  • v-text :填充纯文本,相比插值表达式更加简洁
  • v-html :填充HTML片段,但是存在安全问题,且本网站内部数据可用,来自第三方数据不可用
  • v-pre :填充原始信息,跳过编译过程

例如:

1
2
3
4
5
6
7
8
<div id="app">
<div v-text='msg'></div>
<div>{{msg}}</div>
</div>

//输出:
hello world
hello world

考虑到用户体验或者开发者方便推荐使用指令,插值表达式如果写的完美还需要用到v-cloak 指令,比较麻烦

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<div id="app">
<div>{{ msg }}</div>
<div v-text='msg'></div>
<div v-html='msg1'></div>
</div>

<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
msg: 'hello world',
msg1: '<h1>hello</h1>',
}
});
</script>

输出:

在网站上动态渲染任意HTML是非常危险的,非常容易导致XSS攻击,所以只可以在可信任的内容上使用v-html 指令,切记不要在用户提交的内容上。

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<div id="app">
<div>{{ msg }}</div>
<div v-pre>{{ msg }}</div>
</div>

<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
msg: 'hello world',
}
});
</script>
输出:
hello world
{{msg}}

数据响应式

HTML中的响应式是屏幕的尺寸变化会导致样式的变化,数据响应式是指数据的变化导致页面内容的变化。

v-once 指令指编译一次,显示内容之后不再具有响应式的功能。应用场景:如果显示的信息后续不需要修改,就可以使用这个指令,可以提高性能。

例如:

1
2
3
4
<div id="app">
<div>{{ msg }}</div>
<div v-once>{{ msg1 }}</div>
</div>

这样一来,在开发者工具控制台中,可以通过vm.msg=123来修改msg的显示但是不能通过vm.msg1=123 来修改msg1的内容。

双向数据绑定

双向数据绑定就是例如显示一串内容,有一个输入框,在输入框中输入数据,显示的内容会实时更新。即用户可以修改页面内容

双向数据绑定要用到v-mode 指令:

1
<input type='text' v-mode='msg'/>

MVVM设计思想

就是把不同的功能的代码放在不同的模块里,再通过特定的方式联系起来。

  • M:model
  • V:view
  • VM:view-model

事件绑定

vue如何处理事件

v-on 指令用法:

1
<input type='button' v-on:click='num++'/>

v-on 简写:

1
<input type='button' @click='num++'/>

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>hello world</title>
</head>
<body>
<div id="app">
<div>{{ num }}</div>
<div>
<button v-on:click='num++'>点击+1</button>
</div>
</div>

<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
num: 0,
}
});
</script>
</body>
</html>

按钮每点击一下网页内容加一显示。

事件函数的调用方式

直接绑定函数的名称:

1
<button v-on:click='say'>test</button>

调用函数:

1
<button v-on:click-'say()'>test</button>

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>hello world</title>
<style type="text/css">
[v-cloak]{
display: none;
}
</style>
</head>
<body>
<div id="app">
<div v-cloak>{{ num }}</div>
<div>
<button v-on:click='num++'>点击+1</button>
<button @click='num++'>点击+1</button>
<button v-on:click='handle'>点击+1</button>
<button v-on:click='handle()'>点击+1</button>
</div>
</div>

<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
num: 0,
},
methods: {
handle: function(){
//这里的this是vue的实例对象
console.log(this === vm);
this.num++;
},
},
});
</script>
</body>
</html>

事件函数参数传递

普通的参数和事件对象:

1
<button v-on:click='say("hi",$event)'>test</button>

如果事件直接绑定函数名称,那么默认会传递事件对象作为事件函数的第一个参数;如果事件绑定函数调用,那么事件对象必须作为最后一个参数显示传递,并且事件对象的名称必须是$event

事件修饰符

.stop 阻止冒泡:

1
<a v-on:click.stop="handle">跳转</a>

.prevent 阻止默认行为:

1
<a v-on:click.prevent="handle">跳转</a>

什么是冒泡?例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div class="" id="app">
<div class="">
{{num}}
</div>
<div class="" v-on:click='handle0'>
<button type="" name="" v-on:click='handle1'>点击</button>
</div>
</div>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
num: 0
},
methods: {
handle0: function(){
this.num++;
},
handle1: function(event){

},
},
})
</script>
</body>
</html>

每点击一次num就加一,但是点击这个事件是handle1的,handle0之所以被触发,是因为冒泡到按钮外面的div从而触发num++ ,这就是冒泡。

阻止冒泡:

1
2
3
handle1: function(event){
event.stopPropagation();
}

此时再点击按钮就不会进行加一,这就是传统方式的阻止冒泡。

这是Vue的语法:

1
<button type="" name="" v-on:click.stop='handle1'>点击</button>

默认行为:

1
<a href="https://www.baidu.com">百度</a>

点击百度就会进行跳转,如果阻止这个默认行为:

1
2
3
4
5
<a href="https://www.baidu.com" v-on:click="handle2">百度</a>

handle2: function(event){
event.preventDefault();
}

现在点击百度就不会进行跳转,这是原生js的写法,vue的语法为:

1
<a href="https://www.baidu.com" v-on:click.prevent="handle2">百度</a>

还有其他的修饰符:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!-- 提交事件不再重载页面 -->
<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>

具体可以参考官方文档

按键修饰符

.enter回车键

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

.delete 删除键

1
<input v-on:keyup.delete='handle'>

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="app">
<form class="" action="" method="">
<div class="">
用户名:
<input type="text" v-model='uname'>
</div>
<div class="">
密码:
<input type="text" name="" value="" v-model='pwd'>
</div>
<div class="">
<input type="button" v-on:click='handleSubmit' name="" value="提交">
</div>
</form>
</div>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
uname: '',
pwd: '',
},
methods: {
handleSubmit: function(){
console.log(this.uname, this.pwd);
},
},
});
</script>
</body>
</html>

这时只有点击提交按钮才会才控制台看到输入结果,如果想要按一下回车也可以进行提交就需要按键绑定:

1
<input type="text" name="" value="" v-on:keyup.enter='handleSubmit' v-model='pwd'>

这样在输完密码直接按回车键就可以提交了。如果用户名输入错了,就要删除,一个一个删除很麻烦,使用按键绑定让按一次删除键就清空输入框:

1
2
3
4
5
<input type="text" v-on:keyup.delete='clear' v-model='uname'>

clear: function(){
this.uname='';
},

官方还有很多其他的按键修饰符,请看官方文档,除此之外,还有自定义按键修饰符

全局config.keyCodes 对象:

1
Vue.config.keyCodes.fi = 112

键盘上的每一个键都有对应的值,那么怎么获取呢:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div class="" id="app">
<input type="text" name="" value="" v-on:keyup="handle" v-model="info">
</div>
<script type="text/javascript" src="js/vue.js">

</script>
<script type="text/javascript">
var vm = new Vue({
el: "#app",
data: {
info: "",
},
methods: {
handle: function(event){
console.log(event.keyCode)
},
},
});
</script>
</body>
</html>

这样在输入框按下键的时候在控制台就会输出对应的按键值。

如何自定义按键值呢?就用到上面提到的那个全局对象:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div class="" id="app">
<input type="text" name="" value="" v-on:keyup.aaa="handle" v-model="info">
</div>
<script type="text/javascript" src="js/vue.js">

</script>
<script type="text/javascript">
Vue.config.keyCodes.aaa = 65
var vm = new Vue({
el: "#app",
data: {
info: "",
},
methods: {
handle: function(event){
console.log(event.keyCode)
},
},
});
</script>
</body>
</html>

名称是自定义的,但是对应的值必须是按键对应event.keyCode 的值。

案例:简单计算器

步骤:

  • 通过v-model 指令实现数值双向绑定,获取输入的数值
  • 给计算按钮绑定事件,实现计算
  • 将计算结果绑定到指定位置

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div class="" id="app">
<h1>简单计算器</h1>
<div class="">
<span>数值A:</span>
<span>
<input type="text" name="" value="" v-model="a">
</span>
</div>
<div class="">
<span>数值B:</span>
<span>
<input type="text" name="" value="" v-model="b">
</span>
</div>
<div class="">
<button type="button" name="button" v-on:click="handle">计算</button>
</div>
<div class="">
<span>计算结果:</span>
<span v-text="result"></span>
</div>
</div>
<script type="text/javascript" src="js/vue.js">

</script>
<script type="text/javascript">
var vm = new Vue({
el: "#app",
data: {
a: "",
b: "",
result: "",
},
methods: {
handle: function(){
this.result = parseInt(this.a) + parseInt(this.b);
},
},
});
</script>
</body>
</html>

属性绑定

v-bind 指令用法:

1
<a v-bind:href="url">跳转</a>

缩写:

1
<a :href="url">跳转</a>

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div class="" id="app">
<a v-bind:href="url" v-text="name"></a>
<a :href="url" v-text="name"></a>
<button type="button" name="button" v-on:click="handle">切换查询方式</button>
</div>

<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el: "#app",
data: {
url: "https://www.baidu.com",
name: "BaiDu",
},
methods: {
handle: function(){
this.url="https://www.csdn.net";
this.name="CSDN";
},
},
});
</script>
</body>
</html>

v-model 指令双向数据绑定的底层设计

1
<input v-bind:value="msg" v-on:input="msg=$evemt.target.value"

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div class="" id="app">
<div class="" v-text="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>

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