Vue基础

第一章: 安装vue

如果没有装cnpm可以全局安装

1
npm install cnpm -g

命令行工具(CLI)

  1. 全局安装 vue-cli

    1
    npm install  vue-cli -g
  2. 需要创建一个基于 webpack 模板的新项目

    1
    vue init webpack my-project	//1 vue指令, 2 初始化 3 webpack 4 项目名
  3. 安装依赖,走你

    1
    2
    3
    cd my-project	//进入到当前目录下
    npm install //安装依赖
    npm run dev //运行项目

第一步:

1
npm install  vue-cli -g

img-1

第二步:

1
vue init webpack my-project
  • webpack是vue-cli的webpack模板
  • my-project是项目名称

2

可以看到文件夹中多了一个my-project文件夹

3

目录文件介绍:

  • buildconfig是webpack的配置文件

  • node_modules中存放的是npm install安装的文件依赖代码库

  • src文件是存放的是项目源码

  • static存放的是第三方的静态资源,里面只有.gitkeep这个文件的意思是当这个目录为空也是可以提交git代码仓库里,如果没有这个文件git会忽略这个目录

  • .babelrc这个文件是babel的一些配置,主要就是用于将es6的代码转成es5的,详细介绍:babel

  • .editorconfig是编辑器的一些配置

  • .gitignore用于向git声明需要忽略提交的文件

  • .postcssrc.js这个文件是postCSS的配置文件,postCSS是一款通过JS插件来转换CSS的工具,这些插件能帮你校验你的CSS代码、转换未来的CSS语法、支持变量和混写、以及内联图片等等,其中自动前缀插件是PostCSS最受欢迎预处理器之一。默认就配置使用了autoprefixer也就是自动前缀的这个插件

  • index.html就是入口的html文件,在编译打包过程中会将资源文件插入到这个html文件中

  • 1
    package.json

    项目的配置文件,这个文件中是我们在初始化vue-clic的时候填入的信息:

    • 最重要的就是里面的scripts属性,表示的是我们可以执行的一些命令,比如npm run dev就是执行的node build/dev-server.js这个命令,然后npm run build就是执行的node build/build.js也就是打包的操作,我们也自己在scripts中去配置一些脚本
    • dependencies里面放的项目生产环境的一些依赖,然后在安装一些模块的时候可以通过--save保存到这个属性下,比如要使用vue-router就可以使用npm install vue-router --save
    • devDependencies里面放的编译过程中的一些依赖,在最后打包的时候不存在
  • README.md就是项目的描述文件

第三步:

​安装依赖

1
2
3
$ cd my-project		//跳到当前的项目文件夹
$ npm install //安装依赖
$ npm run dev //运行项目

第二章: vue的基本语法

2.1 引用vue

1.在页面中引入vue.js远程文件或者本地文件

1
<script src="https://unpkg.com/vue/dist/vue.js"></script>

2.本地引入vue.js

1
<script type="text/javascript" src="js/vue.js"></script>

2.2 数据绑定

vue允许采用简洁的模板语法来声明式的将数据渲染进 DOM

最简单的小例子

例1:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>test1</title>
<script src="js/vue.min.js"></script>
</head>
<body>
<div id="app">
{{message}}
</div>

<script>
new Vue({
el:"#app",
data:{
message:"First Vue"
}
})
</script>
</body>
</html>

new 一个vue对象的时候,你可以设置它的属性,其中最重要的包括三个,分别是data, methods, watch

data代表vue对象的数据,methods代表vue的方法,watch设置了对象监听的方法

vue对象里的设置通过html指令进行关联

重要的指令包括:

  • v-text 渲染数据 (ng-bind)
  • v-if 控制显示
  • v-on 绑定事件
  • v-for 循环渲染 等
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
new Vue({
data:{
a:1,
b:[]
}
methods:{
doSomething:function(){
console.log('a')
}
}
watch:{
'a':function(val, oldVal) {
console.log(val, oldVal)
}
}
})

2.3 常用指令

1. v-text

预期string

更新元素的 textContent。如果要更新部分的 textContent ,需要使用 插值。

不能解析HTML标签

1
2
3
4
5
6
7
8
9
10
11
12
13
<div id="app" v-text="message"></div>
<--等价于-->
<div>{{message}}</div>

<script>
new Vue({
el:"#app",
data:{
message:"First Vue",
},
})
</script>
=> First Vue

2. v-html

  • 预期string

  • 详细

    更新元素的 innerHTML注意:内容按普通 HTML 插入 - 不会作为 Vue 模板进行编译。如果试图使用 v-html 组合模板,可以重新考虑是否通过使用组件来替代。

    就是能够解析HTML标签

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<div id="app" v-html="html">

</div>

<script>
new Vue({
el:"#app",
data:{
message:"First Vue",
html:'<span>我是span标签</span>'
},
})
</script>
=> 我是span标签

3. 条件渲染

1. v-if

在上面的例子中,我们是利用v-show='isShow'来实现元素隐藏显示

在 Vue.js ,我们使用 v-if 指令实现同样的功能

1.直接使用v-if

1
2
3
4
5
6
7
8
9
10
11
12
13
<body>
<div id="app">
<div v-if="ok">yes</div>
</div>
<script>
new Vue({
el:"#app",
data:{
ok:true
},
})
</script>
</body>

2.也可以用 v-else 添加一个 “else” 块:

1
2
3
4
<div  id="app">
<div v-if="ok">yes</div>
<div v-else>no</div>
</div>

注:v-else 元素必须紧跟在 v-if 或者 v-else-if 元素的后面——否则它将不会被识别

3.在<template></template>中配合v-if 条件渲染一整组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<div  id="app">
<template v-if="ok"> //显示
<h1 v-else>Title</h1> //隐藏
<p v-else>Paragraph 1</p> //隐藏
<p>Paragraph 2</p> //显示
</template>
</div>

<script>
new Vue({
el:"#app",
data:{
ok:true
},
})
</script>
=> 页面只显示
Paragraph

4.配合v-else-if使用

充当”if”的一个”else-if块”

可以链式的多次使用

2. v-show

根据表达式之真假值,切换元素的 display CSS 属性。

当条件变化时该指令触发过渡效果。

当和 v-if 一起使用时,v-show 的优先级比 v-if 更高。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<body>
<div id="app" v-text="message" v-show="isShow"></div>

<script>
new Vue({
el:"#app",
data:{
message:"First Vue",
isShow:false
},
})
</script>
</body>

=>改变isShow的值控制div的隐藏

4. v-for

预期Array | Object | number | string

用法和ng-repeat一样

遍历数组:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<body>
<div id="app">
<ul>
<li v-for="(item, index) in arr">{{item.name}}</li>
</ul>
</div>
<script>
new Vue({
el:"#app",
data:{
arr:[
{name:'买牙膏', down:false},
{name:'打台球', down:false},
{name:'听歌', down:false},
{name:'游戏', down:false}
]
},
})
</script>
</body>

遍历对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<div  id="app">
<ul>
<li v-for="(val, key) in obj">{{key}}:{{val}}:{{index}}</li>
</ul>
</div>
<script>
new Vue({
el:"#app",
data:{
obj: {name:'王先生', age:21, sex:'男'},
},
})
</script>
=>
name:'王先生' :0
age:21 :1
sex:'男' :2

遍历数字

1
2
3
<div>
<span v-for="n in 10">{{ n }} </span>
</div>

结果:

1
1 2 3 4 5 6 7 8 9 10

v-for 和 v-if

当它们处于同一节点,v-for 的优先级比 v-if 更高,这意味着 v-if 将分别重复运行于每个 v-for 循环中。当你想为仅有的一些项渲染节点时,这种优先级的机制会十分有用,如下:

1
2
3
<li v-for="todo in todos" v-if="!todo.isComplete">
{{ todo }}
</li>

上面的代码只传递了未 complete 的 todos。

而如果你的目的是有条件地跳过循环的执行,那么可以将 v-if 置于外层元素 (或 [`)上。如:

1
2
3
4
5
6
<ul v-if="todos.length">	//只有当数组todos的长度大于0时才会执行循环
<li v-for="todo in todos">
{{ todo }}
</li>
</ul>
<p v-else>No todos left!</p>

组件中的v-for

在组件中使用v-for,任何数据都不会被自动传递到组件里,因为组件有自己独立的作用域。为了把迭代数据传递到组件里,我们要用 props

1
2
3
4
5
6
<my-component
v-for="(item, index) in items"
v-bind:item="item"
v-bind:index="index"
v-bind:key="item.id"
></my-component>

不自动将 item 注入到组件里的原因是,这会使得组件与 v-for 的运作紧密耦合。明确组件数据的来源能够使组件在其他场合重复使用。

具体看第三章组件中的Prop.

5. v-on

  • 缩写@
  • 预期Function | Inline Statement | Object
  • 参数event

语法:

1.方法处理器 v-on:event="functionName"

例1:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<div  id="app">
<button v-on:click="doThis">点击</button>
</div>
<script>
new Vue({
el:"#app",
data:{
obj: {name:'王先生', age:21, sex:'男'},
},
methods:{
doThis() {
alert('点击了我')
}
}
})
</script>

2.对象语法 v-on="{ event1: functionName1, event2:functionName2 }"

例1也可以这样写:

1
<button v-on="{click: doThis}">点击</button>

3.缩写语法 @event ="functionName"

1
<button @click="doThis">点击</button>

修饰符

vue中对事件也有一些修饰符,这些修饰符能帮我们省去很多事

  • .stop - 调用 event.stopPropagation()
  • .prevent - 调用 event.preventDefault()
  • .capture - 添加事件侦听器时使用 capture 模式。
  • .self - 只当事件是从侦听器绑定的元素本身触发时才触发回调。
  • .{keyCode | keyAlias} - 只当事件是从特定键触发时才触发回调。
  • .native - 监听组件根元素的原生事件。
  • .once - 只触发一次回调。
  • .left - (2.2.0) 只当点击鼠标左键时触发。
  • .right - (2.2.0) 只当点击鼠标右键时触发。
  • .middle - (2.2.0) 只当点击鼠标中键时触发。
  • .passive - (2.3.0) 以 { passive: true } 模式添加侦听器

用法:

如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!-- 停止冒泡 -->
<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">
<!-- 点击回调只会触发一次 -->
<button v-on:click.once="doThis"></button>

6. v-bind

  • 缩写:
  • 预期any (with argument) | Object (without argument)
  • 参数数组(attr) Or 组件(Prop) 都是可选的(optional)
  • 修饰符
    • .prop - 被用于绑定 DOM 属性 (property).
    • .camel将 kebab-case 特性名转换为 camelCase. (从 2.1.0 开始支持)
    • .sync 语法糖,会扩展成一个更新父组件绑定值的 v-on 侦听器。
  • 用法

动态地绑定一个或多个特性,或一个组件 prop 到表达式。

1.绑定属性

例1:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<body>
<div id="app">
<img v-bind:src="imgSrc" alt="">
<-- 也可以简写为 -->
<img :src="imgSrc" alt="">
</div>
<script>
new Vue({
el:"#app",
data:{
imgSrc:'img/img1.jpg'
},
})
</script>
</body>
2.绑定class

v-bind:class=””

:class=””

参数可以是一个判断语句,也可以直接传变量

用法和ng-class一样

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>test1</title>
<script src="js/vue.min.js"></script>
<style>
#app{
width: 500px;
height: 500px;
background: red;
}
#app div{
width: 200px;
height: 200px;
}
.isRed{
background: red;
}
.isBlue{
background: blue;
}
</style>
</head>
<body>
<div id="app">
<div :class="{true: 'isRed', false: 'isBlue'}[isClass]"></div>
</div>
<script>
new Vue({
el:"#app",
data:{
isClass: false
},
})
</script>
</body>
</html>
3. 绑定style

v-bind:style

:style

1
2
3
4
5
<div :style="{background: 'blue', fontSize: 14 + 'px' }"></div>
<div :style="styleObject"></div>

styleObject:[{background: 'blue'},{fontSize: 14 + 'px'}],
styleObject:{background: 'blue', fontSize: 14 + 'px'}

ps:当 v-bind:style 使用需要特定前缀的 CSS 属性时,如 transform ,Vue.js 会自动侦测并添加相应的前缀.

若要改变背景图片

1
2
3
<div :style="styleObject"></div>

styleObject: {backgroundImage:'url('+require('./images/img1.png')+')'}
4. 案例tab切换
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
50
51
52
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script type="text/javascript" src="js/vue.js"></script>
<style type="text/css">
#app button.active{
background-color: yellow;
}
#app div{
width: 200px;
height: 200px;
background-color: #ccc;
display: none;
}
#app div.active{
display: block;
}
</style>
</head>
<body>
<div id="app">
<button v-for="(item,index) in tabs" :class="{active:activeIndex==index}" @click="changeIndex(index)">

</button>
<div v-for="(item,index) in tabs" :class="{active:activeIndex==index}">

</div>
</div>
</body>
<script type="text/javascript">

// 父组件
var vm = new Vue({
el:"#app",
data:{
tabs: [
{btn:"按钮1", content: "买菜", id:1},
{btn:"按钮2", content: "学习ng",id:2},
{btn:"按钮3", content: "打游戏",id:3}
],
activeIndex: 0
},
methods: {
changeIndex:function (index){
this.activeIndex = index
}
}
})
</script>
</html>
5. 案例留言板
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script type="text/javascript" src="js/vue.min.js"></script>
<style type="text/css">
*{
list-style: none
}
#app button.active{
background-color: yellow;
}
#app div{
width: 200px;
height: 200px;
background-color: #ccc;
display: none;
}
#app div.active{
display: block;
}
</style>
</head>
<body>
<div id="app">
姓名: <input type="text" v-model="name"><br>
内容: <textarea v-model="content"></textarea><br>
<button @click="add()">提交</button><br>
<h1>显示留言</h1>
<ul>
<li v-for="(item,index) in arr">
<span>{{item.name}}</span>
<p>{{item.content}}<a href="###" @click="del(index)">删除</a></p>
</li>
</ul>
</div>
</body>
<script type="text/javascript">

// 父组件
var vm = new Vue({
el:"#app",
data:{
name:'',
content:'',
arr: []
},
methods: {
add() {
let msg = {
name: this.name,
content: this.content
}
this.arr.push(msg)
this.name = ''
this.content = ''
},
del(index) {
this.arr.splice(index, 1)
}
},
})
</script>
</html>

7. v-model

你可以用 v-model 指令在表单控件元素上创建双向数据绑定。类似于ng-model

随表单控件类型不同而不同

使用对象:

  • <input>

  • <select>

  • <textarea>

  • components

    修饰符:

  • .lazy - 取代 input 监听 change 事件
  • .number - 输入字符串转为数字
  • .trim - 输入首尾空格过滤

#####1.文本或多行文本

1
2
3
4
5
<input v-model="message" placeholder="edit me">
<p>Message is: {{ message }}</p>

<textarea v-model="message" placeholder="add multiple lines"></textarea>
<p>Message is: {{ message }}</p>

注:在文本区域插值 (<textarea></textarea>) 并不会生效,应用 v-model 来代替

2.复选框checkox

for绑定的是input中的id值

1
2
<input type="checkbox" id="checkbox" v-model="checked">
<label for="checkbox">{{ checked }}</label>

多个复选框绑定到同一个数组,

复选框内允许选择多项,所以被勾选中的复选框的value都会被传入数组中,并显示出来

1
2
3
4
5
6
7
8
9
10
<div  id="app">
<input type="checkbox" id="Jack" value="Jack" v-model="checkedNames">
<label for="Jack">Jack</label>
<input type="checkbox" id="John" value="John" v-model="checkedNames">
<label for="John">John</label>
<input type="checkbox" id="Eile" value="Eile" v-model="checkedNames">
<label for="Eile">Eile</label>
<br>
<span>checkedNames:{{checkedNames}}</span>
</div>
1
2
3
4
5
6
new Vue({
el: '#app',
data: {
checkedNames: []
}
})
3. 单选框radio

同一块的单选框只允许有一个值

在span标签中只能显示一个value值,一个单选框被勾中后,另一个就会被取消

1
2
3
4
5
6
7
8
9
<div id="example-4">
<input type="radio" id="one" value="One" v-model="picked">
<label for="one">One</label>
<br>
<input type="radio" id="two" value="Two" v-model="picked">
<label for="two">Two</label>
<br>
<span>Picked: {{ picked }}</span>
</div>
1
2
3
4
5
6
new Vue({
el: '#example-4',
data: {
picked: '' //就算picked是一个数组,也只能显示一个
}
})
4.选择列表select

注:

1
2
<option></option>中有value,则selected的值就是value,若没有value值,则是标签里的值
但记住value要用v-bind:value=""

1.单选列表

单选列表中选择哪一项,span中就显示哪一项的内容,不需要value值

1
2
3
4
5
6
7
8
9
<div id="example-5">
<select v-model="selected">
<option disabled value="">请选择</option> //第一个选项为不能选取,为防止IOS引发change事件
<option>A</option>
<option>B</option>
<option>C</option>
</select>
<span>Selected: {{ selected }}</span>
</div>
1
2
3
4
5
6
new Vue({
el: '...',
data: {
selected: ''
}
})

2.多选列表

select中加入multiple属性就可以使select变为多选

多选列表,按住Ctrl键点击选项,可以选择多项

1
2
3
4
5
6
7
8
9
<div id="example-6">
<select v-model="selected" multiple style="width: 50px;">
<option>A</option>
<option>B</option>
<option>C</option>
</select>
<br>
<span>Selected: {{ selected }}</span>
</div>
1
2
3
4
5
6
new Vue({
el: '#example-6',
data: {
selected: [] //数组
}
})

3.动态选项

v-for 渲染:

1
2
3
4
5
6
<select v-model="selected">
<option v-for="option in options" v-bind:value="option.value">
{{ option.text }}
</option>
</select>
<span>Selected: {{ selected }}</span>
1
2
3
4
5
6
7
8
9
10
11
new Vue({
el: '...',
data: {
selected: 'A',
options: [
{ text: 'One', value: 'A' },
{ text: 'Two', value: 'B' },
{ text: 'Three', value: 'C' }
]
}
})

效果图:

4

8. v-pre

  • 不需要表达式

  • 用法

    跳过这个元素和它的子元素的编译过程。可以用来显示原始 Mustache 标签。跳过大量没有指令的节点会加快编译。

  • 示例

    1
    <span v-pre>{{ this will not be compiled }}</span>

9. v-cloak

  • 不需要表达式

  • 用法

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

1
2
3
[v-cloak] {
display: none;
}
1
2
3
<div v-cloak>
{{ message }}
</div>

不会显示,直到编译结束。

10. v-once

  • 不需要表达式

  • 详细

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

例1:

p标签内的内容为'我是第一次的数据',虽然input绑定了'msg'数据,但只要添加了v-once无论'msg'数据怎样改变,p标签内的内容都不变

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<div id="app">
<input type="text" v-model="msg">
<p v-once>{{msg}}</p>
</div>
<script>
new Vue(
{
el: '#app',
data: {
msg: '我是第一次的数据'
},
}
)
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
<!-- 单个元素 -->
<span v-once>This will never change: {{msg}}</span>
<!-- 有子元素 -->
<div v-once>
<h1>comment</h1>
<p>{{msg}}</p>
</div>
<!-- 组件 -->
<my-component v-once :comment="msg"></my-component>
<!-- `v-for` 指令-->
<ul>
<li v-for="i in list" v-once>{{i}}</li>
</ul>

评论