Vue入门

Vue入门

现在前端比较火的三大家就VueReactAngular,当然现在逐渐兴趣和完善的Fullter,现在也有一些大厂开始用Fullter来开发应用了。但是我还是希望等它再成熟一点之后再开始入手,这样可以少采一些坑嘛。这次,我们先来总结一下Vue的一些基础知识,为什么要学Vue呢,因为它易用、灵活、高效.

环境准备

我们首先需要安装Node.js,去Nodejs官网下载,安装很方便直接下一步即可:

验证是否安装成功:

1
2
3
4
C:\Users\lenovo>node -v
v13.5.0
C:\Users\lenovo>npm -v
6.13.4

使用npm安装vue-cli脚手架构建工具:

1
2
3
4
5
6
7
8
C:\Users\lenovo>npm install -g vue-cli
npm WARN deprecated vue-cli@2.9.6: This package has been deprecated in favour of @vue/cli
npm WARN deprecated coffee-script@1.12.7: CoffeeScript on NPM has moved to "coffeescript" (no hyphen)
C:\Users\lenovo\AppData\Roaming\npm\vue -> C:\Users\lenovo\AppData\Roaming\npm\node_modules\vue-cli\bin\vue
C:\Users\lenovo\AppData\Roaming\npm\vue-init -> C:\Users\lenovo\AppData\Roaming\npm\node_modules\vue-cli\bin\vue-init
C:\Users\lenovo\AppData\Roaming\npm\vue-list -> C:\Users\lenovo\AppData\Roaming\npm\node_modules\vue-cli\bin\vue-list
+ vue-cli@2.9.6
added 4 packages from 1 contributor, removed 1022 packages and updated 237 packages in 162.365s

当然,npm会因为网络问题,会下载很慢甚至导致失败。这里可以使用cnpm或者nvm来更改镜像地址。为了方便,我们还是选择cnpm吧,在cmd中安装cnpm:

1
2
3
4
  C:\Users\lenovo> npm install -g cnpm --registry=http://registry.npm.taobao.org
C:\Users\lenovo\AppData\Roaming\npm\cnpm -> C:\Users\lenovo\AppData\Roaming\npm\node_modules\cnpm\bin\cnpm
+ cnpm@6.1.1
added 31 packages from 27 contributors, removed 29 packages, updated 119 packages and moved 1 package in 130.257s

1
2
3
4
5
6
7
8
9
10
C:\Users\lenovo>cnpm -v
cnpm@6.1.1 (C:\Users\lenovo\AppData\Roaming\npm\node_modules\cnpm\lib\parse_argv.js)
npm@6.13.4 (C:\Users\lenovo\AppData\Roaming\npm\node_modules\cnpm\node_modules\npm\lib\npm.js)
node@13.5.0 (D:\Program Files\nodejs\node.exe)
npminstall@3.25.2 (C:\Users\lenovo\AppData\Roaming\npm\node_modules\cnpm\node_modules\npminstall\lib\index.js)
prefix=C:\Users\lenovo\AppData\Roaming\npm
win32 x64 10.0.18362
registry=https://r.npm.taobao.org
C:\Users\lenovo>vue -V
2.9.6

创建项目

我们先来看一下vue命令工具:

1
2
3
4
5
6
7
8
9
10
11
12
13
C:\Users\lenovo>vue -help
Usage: vue <command> [options]

Options:
-V, --version output the version number
-h, --help output usage information

Commands:
init 从模板生成新项目
list 列出可用的模板
build prototype a new project
create (for v3 warning only)
help [cmd] display help for [cmd]

我这里创建一个名为myresume:

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
E:\vue>vue init webpack myresume

? Project name myresume
? Project description A Vue.js project
? Author eyiadmin <326076105@qq.com>
? Vue build standalone
? Install vue-router? Yes
? Use ESLint to lint your code? Yes
? Pick an ESLint preset Standard
? Set up unit tests No
? Setup e2e tests with Nightwatch? No
? Should we run `npm install` for you after the project has been created? (recommended) no

vue-cli · Generated "myresume".

# Project initialization finished!
# ========================

To get started:

cd myresume
npm install (or if using yarn: yarn)
npm run lint -- --fix (or for yarn: yarn run lint --fix)
npm run dev

Documentation can be found at https://vuejs-templates.github.io/webpack

一般默认既可以,在最后的Should we runnpm installfor you after the project has been created,我选择No,在模版创建好后,自己手动安装。

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
E:\vue>cd myresume
E:\vue\myresume>cnpm install
| [30/47] Installing url-loader@^0.5.8platform unsupported babel-loader@7.1.5 › webpack@3.12.0 › watchpack@1.6.0 › chokidar@2.1.8 › fsevents@^1.2.7 Package require os(darwin) not compatible with your platform(win32)
| [30/47] Installing postcss-normalize-unicode@^4.0.1[fsevents@^1.2.7] optional install error: Package require os(darwin) not compatible with your platform(win32)
√ Installed 47 packages
√ Linked 805 latest versions
[1/3] scripts.postinstall babel-loader@7.1.5 › webpack@3.12.0 › uglifyjs-webpack-plugin@^0.4.6 run "node lib/post_install.js", root: "E:\\vue\\myresume\\node_modules\\_uglifyjs-webpack-plugin@0.4.6@uglifyjs-webpack-plugin"
[1/3] scripts.postinstall babel-loader@7.1.5 › webpack@3.12.0 › uglifyjs-webpack-plugin@^0.4.6 finished in 556ms
[2/3] scripts.postinstall babel-plugin-transform-runtime@6.23.0 › babel-runtime@6.26.0 › core-js@^2.4.0 run "node -e \"try{require('./postinstall')}catch(e){}\"", root: "E:\\vue\\myresume\\node_modules\\_core-js@2.6.11@core-js"
Thank you for using core-js ( https://github.com/zloirock/core-js ) for polyfilling JavaScript standard library!

The project needs your help! Please consider supporting of core-js on Open Collective or Patreon:
> https://opencollective.com/core-js
> https://www.patreon.com/zloirock

Also, the author of core-js ( https://github.com/zloirock ) is looking for a good job -)

[2/3] scripts.postinstall babel-plugin-transform-runtime@6.23.0 › babel-runtime@6.26.0 › core-js@^2.4.0 finished in 216ms
[3/3] scripts.postinstall webpack-bundle-analyzer@2.13.1 › ejs@^2.5.7 run "node ./postinstall.js", root: "E:\\vue\\myresume\\node_modules\\_ejs@2.7.4@ejs"
Thank you for installing EJS: built with the Jake JavaScript build tool (https://jakejs.com/)

[3/3] scripts.postinstall webpack-bundle-analyzer@2.13.1 › ejs@^2.5.7 finished in 136ms
√ Run 3 scripts
peerDependencies link ajv@5.5.2 in E:\vue\myresume\node_modules\_ajv-keywords@2.1.1@ajv-keywords unmet with E:\vue\myresume\node_modules\ajv(6.10.2)
deprecate autoprefixer@7.2.6 › browserslist@^2.11.3 Browserslist 2 could fail on reading Browserslist >3.0 config used in other tools.
deprecate css-loader@0.28.11 › cssnano@3.10.0 › autoprefixer@6.7.7 › browserslist@^1.7.6 Browserslist 2 could fail on reading Browserslist >3.0 config used in other tools.
deprecate eslint@4.19.1 › file-entry-cache@2.0.0 › flat-cache@1.3.4 › circular-json@^0.3.1 CircularJSON is in maintenance only, flatted is its successor.
deprecate babel-plugin-transform-runtime@6.23.0 › babel-runtime@6.26.0 › core-js@^2.4.0 core-js@<3 is no longer maintained and not recommended for usage due to the number of issues. Please, upgrade your dependencies to the actual version of core-js@3.
deprecate webpack-bundle-analyzer@2.13.1 › bfj-node4@^5.2.0 Switch to the `bfj` package for fixes and new features!
Recently updated (since 2019-12-24): 5 packages (detail see file E:\vue\myresume\node_modules\.recently_updates.txt)
Today:
→ optimize-css-assets-webpack-plugin@3.2.1 › cssnano@4.1.10 › postcss@^7.0.0(7.0.26) (08:11:16)
√ All packages installed (1005 packages installed from npm registry, used 56s(network 52s), speed 66.01kB/s, json 852(1.95MB), tarball 1.4MB)

安装完成后就可以初步看看我们的项目模版:

1
2
3
4
5
6
7
8
9
10
11
E:\vue\myresume>npm run dev

> myresume@1.0.0 dev E:\vue\myresume
> webpack-dev-server --inline --progress --config build/webpack.dev.conf.js

13% building modules 33/37 modules 4 active ...yresume\src\components\HelloWorld.vue{ parser: "babylon" } is deprecated; we now treat it as { parser: "babel" }.
95% emitting

DONE Compiled successfully in 3332ms 下午6:20:31

I Your application is running here: http://localhost:8080

在浏览器访问http://localhost:8080/#/

基础介绍

模板语法

Vue.js 使用了基于 HTML 的模板语法,允许开发者声明式地将 DOM 绑定至底层 Vue 实例的数据。所有 Vue.js 的模板都是合法的 HTML ,所以能被遵循规范的浏览器和 HTML 解析器解析。在底层的实现上,Vue 将模板编译成虚拟 DOM 渲染函数。结合响应系统,Vue 能够智能地计算出最少需要重新渲染多少组件,并把 DOM 操作次数减到最少。

文本

数据绑定最常见的形式就是使用Mustache语法 (双大括号) 的文本插值:

1
<span>我会变: {{ msg }}</span>

Mustache标签将会被替代为对应数据对象上 msg 属性的值。无论何时,绑定的数据对象上 msg 属性发生了改变,插值处的内容都会更新。通过使用 v-once 指令,你也能执行一次性地插值,当数据改变时,插值处的内容不会更新。但请留心这会影响到该节点上的其它数据绑定:

1
<span v-once>我不会改变: {{ msg }}</span>

我们来看看这二者的效果:

原始 HTML

双大括号会将数据解释为普通文本,而非 HTML 代码。为了输出真正的 HTML,你需要使用 v-html 指令:

1
2
3
4
5
6
7
8
9
10
11
12
<p>Using mustaches: {{ rawHtml }}</p>
<p>Using v-html directive: <span v-html="rawHtml"></span></p>
<script>
export default {
name: 'HelloWorld',
data () {
return {
rawHtml:'<span>html代码</span>'
}
}
}
</script>


这个 span 的内容将会被替换成为属性值 rawHtml,直接作为 HTML——会忽略解析属性值中的数据绑定。注意,你不能使用 v-html 来复合局部模板,因为 Vue 不是基于字符串的模板引擎。反之,对于用户界面 (UI),组件更适合作为可重用和可组合的基本单位。
你的站点上动态渲染的任意 HTML 可能会非常危险,因为它很容易导致 XSS 攻击。请只对可信内容使用 HTML 插值,绝不要对用户提供的内容使用插值。

特性

Mustache 语法不能作用在 HTML 特性上,遇到这种情况应该使用 v-bind 指令:

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

对于布尔特性 (它们只要存在就意味着值为 true),v-bind 工作起来略有不同,在这个例子中:

1
<button v-bind:disabled="isButtonDisabled">Button</button>

如果 isButtonDisabled 的值是 nullundefinedfalse,则 disabled 特性甚至不会被包含在渲染出来的 <button> 元素中。

使用 JavaScript 表达式

迄今为止,在我们的模板中,我们一直都只绑定简单的属性键值。但实际上,对于所有的数据绑定,Vue.js 都提供了完全的 JavaScript 表达式支持。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
{{ number + 1 }}

{{ ok ? 'YES' : 'NO' }}

{{ message.split('').reverse().join('') }}

<div v-bind:id="'list-' + id"></div>
<script>
export default {
name: 'HelloWorld',
data () {
return {
id:1,
ok:1,
message:'reverse',
number:1,
}
}
}
</script>


这些表达式会在所属 Vue 实例的数据作用域下作为 JavaScript 被解析。有个限制就是,每个绑定都只能包含单个表达式,所以下面的例子都不会生效。

1
2
3
4
5
<!-- 这是语句,不是表达式 -->
{{ var a = 1 }}

<!-- 流控制也不会生效,请使用三元表达式 -->
{{ if (ok) { return message } }}

模板表达式都被放在沙盒中,只能访问全局变量的一个白名单,如 Math 和 Date 。你不应该在模板表达式中试图访问用户定义的全局变量。

指令

指令 (Directives) 是带有 v- 前缀的特殊特性。指令特性的值预期是单个 JavaScript 表达式 (v-for 是例外情况,稍后我们再讨论)。指令的职责是,当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM。回顾我们在介绍中看到的例子:

1
2
3
4
5
6
7
8
9
10
11
<p v-if="seen">现在你看到我了</p>
<script>
export default {
name: 'HelloWorld',
data () {
return {
seen:true
}
}
}
</script>


这里,v-if 指令将根据表达式 seen 的值的真假来插入/移除 <p> 元素。

参数

一些指令能够接收一个“参数”,在指令名称之后以冒号表示。例如,v-bind 指令可以用于响应式地更新 HTML 特性:

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

在这里 href 是参数,告知 v-bind 指令将该元素的 href 特性与表达式 url 的值绑定。

另一个例子是 v-on 指令,它用于监听 DOM 事件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 <a v-on:click="doSomething">hello vue</a>
<script>
export default {
name: 'HelloWorld',
data () {
return {

}
},
methods:{
doSomething:function(){
alert("hello vue");
}
}
}
</script>


在这里参数是监听的事件名。我们也会更详细地讨论事件处理。

动态参数
2.6.0 新增

从 2.6.0 开始,可以用方括号括起来的 JavaScript 表达式作为一个指令的参数:

1
2
3
4
<!--
注意,参数表达式的写法存在一些约束,如之后的“对动态参数表达式的约束”章节所述。
-->
<a v-bind:属性名="url"> ... </a>

这里的属性名 会被作为一个 JavaScript 表达式进行动态求值,求得的值将会作为最终的参数来使用。例如,如果你的 Vue 实例有一个 data 属性 属性名,其值为 “href”,那么这个绑定将等价于 v-bind:href
示例:

1
2
3
4
5
6
7
8
9
10
11
<a v-bind:href="url"> baidu </a>
export default {
name: 'HelloWorld',
data () {
return {
url:"https://www.baidu.com"
}
},

}
</script>


同样地,你可以使用动态参数为一个动态的事件名绑定处理函数:

1
<a v-on:事件名="doSomething"> ... </a>

在这个示例中,当 事件名 的值为 “focus” 时,v-on:事件名 将等价于 v-on:focus。

对动态参数的值的约束
动态参数预期会求出一个字符串,异常情况下值为 null。这个特殊的 null 值可以被显性地用于移除绑定。任何其它非字符串类型的值都将会触发一个警告。

对动态参数表达式的约束
动态参数表达式有一些语法约束,因为某些字符,如空格和引号,放在 HTML attribute 名里是无效的。例如:

1
2
<!-- 这会触发一个编译警告 -->
<a v-bind:['foo' + bar]="value"> ... </a>

变通的办法是使用没有空格或引号的表达式,或用计算属性替代这种复杂表达式。

在 DOM 中使用模板时 (直接在一个 HTML 文件里撰写模板),还需要避免使用大写字符来命名键名,因为浏览器会把 attribute 名全部强制转为小写:

1
2
3
4
5
<!--
在 DOM 中使用模板时这段代码会被转换为 `v-bind:[someattr]`。
除非在实例中有一个名为“someattr”的 property,否则代码不会工作。
-->
<a v-bind:[someAttr]="value"> ... </a>

修饰符
修饰符 (modifier) 是以半角句号 . 指明的特殊后缀,用于指出一个指令应该以特殊方式绑定。例如,.prevent 修饰符告诉 v-on 指令对于触发的事件调用 event.preventDefault():

1
<form v-on:submit.prevent="onSubmit">...</form>

在接下来对 v-onv-for 等功能的探索中,你会看到修饰符的其它例子。

缩写
v- 前缀作为一种视觉提示,用来识别模板中 Vue 特定的特性。当你在使用 Vue.js 为现有标签添加动态行为 (dynamic behavior) 时,v- 前缀很有帮助,然而,对于一些频繁用到的指令来说,就会感到使用繁琐。同时,在构建由 Vue 管理所有模板的单页面应用程序 (SPA - single page application) 时,v- 前缀也变得没那么重要了。因此,Vue 为 v-bindv-on 这两个最常用的指令,提供了特定简写:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
v-bind 缩写
<!-- 完整语法 -->
<a v-bind:href="url">...</a>

<!-- 缩写 -->
<a :href="url">...</a>


v-on 缩写
<!-- 完整语法 -->
<a v-on:click="doSomething">...</a>

<!-- 缩写 -->
<a @click="doSomething">...</a>

它们看起来可能与普通的 HTML 略有不同,但 : 与 @ 对于特性名来说都是合法字符,在所有支持 Vue 的浏览器都能被正确地解析。而且,它们不会出现在最终渲染的标记中。缩写语法是完全可选的。

Class 与 Style 绑定

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

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

上面的语法表示 active 这个 class 存在与否将取决于数据属性 isActivetruthiness.

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

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

和如下 data:

1
2
3
4
data: {
isActive: true,
hasError: false
}

结果渲染为:

1
<div class="static active"></div>

isActive 或者 hasError 变化时,class 列表将相应地更新。例如,如果 hasError 的值为 trueclass 列表将变为 “static active text-danger”。

绑定的数据对象不必内联定义在模板里:

1
2
3
4
5
6
7
<div v-bind:class="classObject"></div>
data: {
classObject: {
active: true,
'text-danger': false
}
}

渲染的结果和上面一样。我们也可以在这里绑定一个返回对象的计算属性。这是一个常用且强大的模式:

1
2
3
4
5
6
7
8
9
10
11
12
13
<div v-bind:class="classObject"></div>
data: {
isActive: true,
error: null
},
computed: {
classObject: function () {
return {
active: this.isActive && !this.error,
'text-danger': this.error && this.error.type === 'fatal'
}
}
}

数组语法
我们可以把一个数组传给 v-bind:class,以应用一个 class 列表:

1
2
3
4
5
<div v-bind:class="[activeClass, errorClass]"></div>
data: {
activeClass: 'active',
errorClass: 'text-danger'
}

渲染为:

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

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

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

这样写将始终添加 errorClass,但是只有在 isActivetruthy[1] 时才添加 activeClass

不过,当有多个条件 class 时这样写有些繁琐。所以在数组语法中也可以使用对象语法:

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

条件渲染

v-if 指令用于条件性地渲染一块内容。这块内容只会在指令的表达式返回 truthy 值的时候被渲染。

1
<h1 v-if="awesome">Vue is awesome!</h1>

也可以用 v-else 添加一个else 块

1
2
<h1 v-if="awesome">Vue is awesome!</h1>
<h1 v-else>Oh no 😢</h1>

你可以使用 v-else 指令来表示v-if 的”else 块”:

1
2
3
4
5
6
<div v-if="Math.random() > 0.5">
Now you see me
</div>
<div v-else>
Now you don't
</div>

v-else 元素必须紧跟在带 v-if或者 v-else-if(2.1.0 新增) 的元素的后面,否则它将不会被识别。
v-else-if,顾名思义,充当 v-if 的”else-if 块”,可以连续使用:

1
2
3
4
5
6
7
8
9
10
11
12
<div v-if="type === 'A'">
A
</div>
<div v-else-if="type === 'B'">
B
</div>
<div v-else-if="type === 'C'">
C
</div>
<div v-else>
Not A/B/C
</div>

类似于v-elsev-else-if 也必须紧跟在带 v-if 或者 v-else-if 的元素之后。

该问的内容是从https://cn.vuejs.org/v2/guide/拷贝来的,然后自己在验证一下。

#
You forgot to set the qrcode for Alipay. Please set it in _config.yml.
You forgot to set the qrcode for Wechat. Please set it in _config.yml.
You forgot to set the business and currency_code for Paypal. Please set it in _config.yml.
You forgot to set the url Patreon. Please set it in _config.yml.
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×