Vue安装与简单使用

安装Node.js

在这里插入图片描述

  • 安装,直接下一步即可
  • 安装完成查看node版本号

在这里插入图片描述

  • 安装完成,node自带npm,查看npm版本号

在这里插入图片描述

  • 安装nrm(镜像切换工具),输入命令,等待安装好就行了

在这里插入图片描述

  • 查看所有镜像源 *代表当前所选镜像源

在这里插入图片描述

  • 如果不是taobao 可以更换taobao

在这里插入图片描述

IDEA操作Vue
  • IDEA安装vue插件

在这里插入图片描述

  • 创建一个空工程
    • File>>>New>>>Project>>>Empty Project>>>Empty Project>>>Next>>>输入Project Name>>>Finish
  • 创建一个Module
    • File>>>New>>>Module>Static Web>>>Static Web>>>Next>>>输入Module Name>>>Finish
  • 这时此Module还为空,打开IDEA最下面Terminal
  • 进行Module初始化,如果Terminal执行不了npm,需要设置一下cmd

在这里插入图片描述
在这里插入图片描述

  • 重启之后,再进入 IDEA 的 Terminal 进入当前的目录目录,输入下面命令npm init -y
  • 安装 放在node_modules下文件夹为 vuenpm install vue --save
  • 这时的工程解构

在这里插入图片描述

谷歌浏览器安装vue插件

  • GitHub搜索IMI-SOURCE-CODE,下载第一个crx的文件
  • 把.crx改.rar,再解压到一个文件夹,然后开发者模式添加

生命周期

在这里插入图片描述

初步操作

v-model v-on:click new Vue el data methods

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" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!--vue对象的html模版-->
<div id="app">
<!--双向绑定,v-model对应的值是数据模型-->
<input type="text"v-model="num">
<!--v-on:事件名=js表达式-->
<!--<input type="button" value="点击增加一位马仔" v-on:click="num++">-->
<input type="button" value="点击增加一位马仔" v-on:click="incr">
<!--两对大括号:js表达式,例如{{1+1}} 就是2-->
<h1>大家好,我是{{name}},手下有{{num}}位马仔</h1>
</div>
</body>
<!--引入vue.js-- 不要用"/>" 必须用"></script>"-->
<script src="node_modules/vue/dist/vue.js"></script>

<script>
//初始化一个vue实例
const app=new Vue({
el:"#app",//el即element,选择器
data:{//定义数据模型
name:"陶攀峰",
num:100
},
methods:{//定义方法
incr(){
//this表示Vue实例中的数据,可以this.属性 this.方法
this.num++;
}
}
});
</script>
</html>

created() mounted()

  • created()视图渲染前,还没有形成HTML
  • mounted()视图已经渲染,已形成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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!--vue对象的html模版-->
<div id="app">
<!--双向绑定,v-model对应的值是数据模型-->
<input type="text" v-model="num">
<!--v-on:事件名=js表达式-->
<!--<input type="button" value="点击增加一位马仔" v-on:click="num++">-->
<input type="button" value="点击增加一位马仔" v-on:click="incr">
<!--两对大括号:js表达式,例如{{1+1}} 就是2-->
<h1>大家好,我是{{name}},手下有{{num}}位马仔</h1>
</div>
</body>
<!--引入vue.js-- 不要用"/>" 必须用"></script>"-->
<script src="node_modules/vue/dist/vue.js"></script>

<script>
//初始化一个vue实例
const app = new Vue({
el: "#app",//el即element,选择器
data: {//定义数据模型
name: "陶攀峰",
num: 100
},
methods: {//定义方法
incr() {
//this表示Vue实例中的数据,可以this.属性 this.方法
this.num++;
}
},
created() {
//ajax
//可以覆盖data中的数据
this.num = 1801957499
},
mounted() {
//可以覆盖之前的created中数据
this.num=1801
}
});

</script>
</html>

数据使用

花括号

1
2
3
4
5
6
7
格式{{表达式}}

该表达式支持JS语法,可以调用js内置函数(必须有返回值)

表达式必须有返回结果。例如 {{1 + 1}},没有结果的表达式不允许使用,如:{{var a = 1 + 1}};

可以直接获取Vue实例中定义的数据或函数,使用函数{{方法名()}},使用属性{{属性名}}

单项绑定:v-text,v-html

1
2
3
4
5
6
7
8
<h1 v-text="vtext"></h1>
<h1 v-html="vhtml"></h1>


data: {//定义数据模型
vtext:"<p style='color: red'>这是测试v-text</p>",
vhtml:"<p style='color: red'>这是测试v-html</p>"
}

在这里插入图片描述

双向绑定:v-model

  • v-model的可使用的元素

    • input
    • select
    • textarea
    • checkbox
    • radio
    • components(Vue中的自定义组件)
  • 对应类型

    • 多个checkbox对应一个model时,model的类型是一个数组,单个checkbox值默认是boolean类型
    • radio对应的值是input的value值
    • text和textarea默认对应的model是字符串
    • select单选对应字符串,多选对应也是数组
  • 测试

    1
    2
    3
    4
    5
    6
    7
    8
    9
    ...
    <div id="app">
    <input type="checkbox" value="ios" v-model="language">ios<br>
    <input type="checkbox" value="java" v-model="language">java<br>
    <input type="checkbox" value="php" v-model="language">php<br>
    您选择了:{{language}}<br>
    您选择了:{{language.join(',')}}<br>
    </div>
    ...
    1
    2
    3
    4
    5
    6
    7
    8
    ...
    const app = new Vue({
    el: "#app",
    data: {
    language: []
    }
    });
    ...

    在这里插入图片描述

    v-on

    页面元素绑定事件

  • 语法v-on:事件名="js片段或函数名"

    v-on:click

    鼠标左键点击

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<div id="app">
<!--事件中直接写js片段-->
<button v-on:click="num++">增加一个</button><br/>
<!--事件指定一个回调函数,必须是Vue实例中定义的函数-->
<button v-on:click="decrement">减少一个</button><br/>
<h1>有{{num}}个女神迷恋峰哥</h1>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
var app = new Vue({
el:"#app",
data:{
num:100
},
methods:{
decrement(){
this.num--;
}
}
})
</script>

在这里插入图片描述

v-on:contextMenu

鼠标右键点击

  • 指令后缀
    • .stop阻止事件冒泡到父元素
    • .prevent阻止默认事件发生
    • .capture使用事件捕获模式
    • .self只有元素自身触发事件才执行。(冒泡或捕获的都不执行)
    • .once只执行一次
  • .prevent演示
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<div id="app">
<!--右击事件,并阻止默认事件发生-->
<button v-on:contextmenu.prevent="num++">增加一个</button>
<br/>
<!--右击事件,不阻止默认事件发生-->
<button v-on:contextmenu="decrement($event)">减少一个</button>
<br/>
<h1>有{{num}}个女神迷恋峰哥</h1>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
var app = new Vue({
el: "#app",
data: {
num: 100
},
methods: {
decrement(ev) {
//用也可以禁用默认事件,不会显示右击菜单 ev.preventDefault();
this.num--;
}
}
})
</script>

在这里插入图片描述

v-on:keyup

按键修饰符

  • enter 回车调用submit方法代码
1
2
3
<input v-on:keyup.enter="submit">
<!-- 缩写语法 -->
<input @keyup.enter="submit">
  • 事件类型,对应键盘字母
    • .enter
    • .tab
    • .delete (捕获“删除”和“退格”键)
    • .esc
    • .space
    • .up
    • .down
    • .left
    • .right
    • .13 等于.enter
    • .65表示a按键
    • .66表示b按键,以此类推
  • 组合件按钮,对应按键
    • .ctrl
    • .alt
    • .shift
1
2
3
4
5
6
7
<!-- Alt + C 因为65是a 66是b 67为c 依次类推 -->
<input @keyup.alt.67="clear">
<!-- Alt + C -->
<input @keyup.alt.c="clear">

<!-- Ctrl + Click 也就是Ctrl加上鼠标左键点击 -->
<div @click.ctrl="doSomething">Do something</div>

v-for

遍历数据

遍历数组

  • 语法v-for="元素别名 in 数组名"角标从0开始
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<div id="app">
<ul>
<li v-for="user in users">
{{user.name}} - {{user.gender}} - {{user.age}}
</li>
</ul>
</div>

<script>
var app = new Vue({
el: "#app",
data: {
users:[
{name:'大牛', gender:'女', age: 11},
{name:'二蛋', gender:'男', age: 36},
{name:'三驴', gender:'女', age: 24},
{name:'四毛', gender:'女', age: 98},
{name:'五虎', gender:'女', age: 29}
]
},
});
</script>

在这里插入图片描述

  • 数组角标语法v-for="(元素别名,角标别名) in 数组名"角标从0开始
1
2
3
4
5
<ul>
<li v-for="(user,aaa) in users">
{{aaa}}---{{user.name}} - {{user.gender}} - {{user.age}}
</li>
</ul>

在这里插入图片描述

遍历对象

  • 语法v-for="(value别名,key别名,角标别名) in 对象名"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<div id="app">
<ul>
<li v-for="(value1, key1, index1) in daniu">
{{index1 + 1}}. {{key1}} - {{value1}}
</li>
</ul>
</div>

<script>
var app = new Vue({
el: "#app",
data: {
daniu:
{name:'大牛', gender:'女', age: 11}
}
});
</script>

在这里插入图片描述

  • key 标注一个key数组索引,唯一,可以让你读取vue中的属性,并赋值给key属性
1
<li v-for="(value1, key1, index1) in daniu" :key=index1></li>

v-if,v-show

if效率高

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<div id="app">
<button v-on:click="show=!show">点我呀</button><br>
<h1 v-if="show">我是v-if</h1>
<h1 v-show="show">我是v-show</h1>
</div>

<script>
var app = new Vue({
el: "#app",
data: {
show: true
}
});
</script>
  • 默认显示

在这里插入图片描述

  • 点击一下

在这里插入图片描述

  • 点击两下

在这里插入图片描述

  • v-if与v-for并用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<div id="app">
<ul>
<li v-for="user in users" v-if="user.gender=='女'&&user.age>25">
{{user.name}} - {{user.gender}} - {{user.age}}
</li>
</ul>
</div>

<script>
var app = new Vue({
el: "#app",
data: {
users:[
{name:'大牛', gender:'女', age: 11},
{name:'二蛋', gender:'男', age: 36},
{name:'三驴', gender:'女', age: 24},
{name:'四毛', gender:'女', age: 98},
{name:'五虎', gender:'女', age: 29}
]
},
});
</script>

在这里插入图片描述

v-if与v-else-if与v-else结合

注意:中间不要间隔任何东西,例如br标签,p标签,span标签

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<div id="app">
<button v-on:click="random=Math.random()">点我呀</button><span>{{random}}</span>
<h1 v-if="random >= 0.75">看到我啦?!if</h1>
<h1 v-else-if="random > 0.5">看到我啦?!if 0.5</h1>
<h1 v-else-if="random > 0.25">看到我啦?!if 0.25</h1>
<h1 v-else>看到我啦?!else</h1>
</div>

<script type="text/javascript">
var app = new Vue({
el: "#app",
data: {
random: 1
}
});
</script>

在这里插入图片描述

v-bind 绑定

简写v-bind:class可以简写为: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
39
40
41
42
43
44
45
46
47
48
49
50
51
<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>a.html</title>
</head>
<style>
.diyclassred{
color: red;
}
.diyclassblue{
color: blue;
}
</style>
<body>
<div id="app">
<!--双向绑定,文本num中值变,num的值也改变-->
<input type="text" v-model="num">
<!--按钮显示字体绑定的value为context属性-->
<!--绑定class名称为diyclassblue,当num大于100的时候才启用diyclassblue-->
<input type="button" v-bind:value="context" v-bind:class="{diyclassblue:num>100}"><br>
<!--绑定自定义样式diystyle-->
<input type="button" value="我是v-style" v-bind:style="diystyle"><br>
<ul>
<!--如果用户性别为女并且年龄大于25使用class样式diyclassred-->
<li v-for="user in users" v-bind:class="{diyclassred:user.gender=='女'&&user.age>25}">
{{user.name}} - {{user.gender}} - {{user.age}}
</li>
</ul>
</div>
</body>
<script src="node_modules/vue/dist/vue.js"></script>

<script>
var app = new Vue({
el: "#app",
data: {
num:1,
context:"大于100字体变蓝色",
diystyle:"background-color:red;color:blue;",
users:[
{name:'大牛', gender:'女', age: 11},
{name:'二蛋', gender:'男', age: 36},
{name:'三驴', gender:'女', age: 24},
{name:'四毛', gender:'女', age: 98},
{name:'五虎', gender:'女', age: 29}
]
},
});
</script>
</html>

在这里插入图片描述

  • 如果文本框1改为大于100值

在这里插入图片描述

computed 计算属性

计算属性,里面也是定义方法,但是必须要有返回值,可以像数据模型去使用
与方法不同,无论birthday是否变化,方法都会重新执行一次
计算属性会对之前的结果进行缓存,如果birthday变化,才会重新执行计算属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<div id="app">
<h1>您的生日是:{{birth}} </h1>
</div>

<script>
var vm = new Vue({
el:"#app",
data:{
birthday:1429032123201 // 毫秒值
},
//计算属性,里面也是定义方法,但是必须要有返回值,可以像数据模型去使用
//与方法不同,无论birthday是否变化,方法都会重新执行一次
//计算属性会对之前的结果进行缓存,如果birthday变化,才会重新执行计算属性
computed:{
//错误使用{{birth()}}
//正确用{{birth}}
birth(){
const date = new Date(this.birthday);
return date.getFullYear() + "-" + date.getMonth() + "-" + date.getDay();
}
}
});
</script>

在这里插入图片描述

watch

watch可以让我们监控一个值的变化。从而做出相应的反应。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<div id="app">
<input type="text" v-model="message">
</div>

<script>
var vm = new Vue({
el:"#app",
data:{
message:""
},
watch:{
message(new_message,old_message){
console.log(new_message,old_message);
}
}
});
</script>
  • 依次输入123456789 显示

在这里插入图片描述

组件化

template中只能有一个根标签

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//可以
template: "\
<div>\
<button @click='part_incr'>加</button> \
<button @click='part_decr'>减</button> \
</div>"


//不可以
template: "\
<div>\
<button @click='part_incr'>加</button> \
<button @click='part_decr'>减</button> \
</div><span></span>"

全局组件,组件复用,可在其他vue模块内使用,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
<div id="app">
<!--每个标签不会互相影响效果-->
<counter></counter><br>
<counter></counter><br>
<counter></counter>
</div>

const app = new Vue({
el:"#app",
data:{
num: 0
}
});

Vue.component("counter",{
//定义全局组件,两个参数: 1,组件名称 2,组件参数
template:"<button @click='num++'>已点击{{num}}次</button>",
data(){
return{
num:0
}
}
});

在这里插入图片描述

局部组件,只能在自己vue中使用,引入之后才可使用,new Vue写下面
components就是当前vue对象子组件集合,在这里counter就为key,用双引号””,counter1就是value,组件对象名

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<div id="app">
<counter></counter>
</div>

const counter1 = {
template: "<button @click='num++'>已点击{{num}}次</button>",
data() {
return {
num: 0
}
}
};

//new Vue需要写在定义的组件下面
new Vue({
el: "#app",
components: {
//counter为标签名,counter1位自定义的组件
"counter": counter1
}
});

在这里插入图片描述

  • 点击两次按钮

在这里插入图片描述

组件通信

props

父向子传递,父自定义属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<div id="app">
<!--自定义属性num1,双向绑定num-->
<counter :num1="num"></counter>
</div>

<script>

Vue.component("counter",{
//两个num1是props接收的属性
template:"<button @click='num1++'>已点击{{num1}}</button>",
//通过props接收父组件传递的属性
props:["num1"]
});

new Vue({
el: "#app",
data:{
num:0
}
});

</script>

在这里插入图片描述

  • 点击两次后显示

在这里插入图片描述

$emit

子向父的通信,父自定义事件

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
<div id="app">
<h2>num: {{num}}</h2>
<diy_tag :diy_props="num" @diy_incr="global_incr" @diy_decr="global_decr"></diy_tag>
</div>

<script>
Vue.component("diy_tag", {
template: "\
<div>\
<button @click='part_incr'></button> \
<button @click='part_decr'></button> \
</div>",
props: ["diy_props"],
methods: {
part_incr() {
this.$emit("diy_incr");
},
part_decr() {
this.$emit("diy_decr");
}
}
});

var app = new Vue({
el: "#app",
data: {
num: 0
},
methods: { // 父组件中定义操作num的方法
global_incr() {
this.num++;
},
global_decr() {
this.num--;
}
}
});
</script>

在这里插入图片描述

vue-router

路由

安装vue-router

  • 进入IDEA下面Terminal
  • 进入项目cd hello-vue
  • 安装npm install vue-router --save

模块结构

在这里插入图片描述

  • index.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
30
31
32
33
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>src/index.html</title>
</head>
<body>

<div id="app">
<span>登录</span>
<span>注册</span>
<hr>
<!--使用login-form来匹配loginForm-->
<!--直接使用<loginForm></loginForm>会解析成<loginform></loginform>,会导致匹配不到-->
<login-form></login-form>
<register-form></register-form>
</div>
</body>
<script src="../node_modules/vue/dist/vue.js"></script></script>
<script src="js/login.js"></script>
<script src="js/register.js"></script>

<script>
const app=new Vue({
el:"#app",
components:{
//loginForm:loginForm, 缩写 loginForm,
loginForm,
registerForm
}
});
</script>
</html>
  • login.js
1
2
3
4
5
6
7
8
9
10
11
12
const loginForm = {
//组件内template只能有一个根标签
//&emsp;代表一个汉字
template: `
<div>
<h1>登录页</h1>
用户名:<input type="text"><br>
密&emsp;码:<input type="password"><br>
<input type="button" value="登录">
</div>
`
}
  • register.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
const registerForm = {
//组件内template只能有一个根标签
//&emsp;代表一个汉字
//&ensp;代表半个汉字
template: `
<div>
<h1>注册页</h1>
用&ensp;户&ensp;名:<input type="text"><br>
密&emsp;&emsp;码:<input type="password"><br>
确认密码:<input type="password"><br>
<input type="button" value="注册">
</div>
`
}

在这里插入图片描述

  • 使用vue-router,改写后index.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
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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>src/index.html</title>
</head>
<body>

<div id="app">
<!--<span>登录</span>
<span>注册</span>
<hr>
&lt;!&ndash;使用login-form来匹配loginForm&ndash;&gt;
&lt;!&ndash;直接使用<loginForm></loginForm>会解析成<loginform></loginform>,会导致匹配不到&ndash;&gt;
<login-form></login-form>
<register-form></register-form>-->
<span><router-link to="/login">登录</router-link></span>
<span><router-link to="/register">注册</router-link></span>
<hr>
<router-view></router-view>
</div>
</body>
<!--先引入vue.js再引入vue-router.js-->
<!--引入vue.js-->
<script src="../node_modules/vue/dist/vue.js"></script>
<!--引入vue-router.js-->
<script src="../node_modules/vue-router/dist/vue-router.js"></script>
<script src="js/login.js"></script>
<script src="js/register.js"></script>

<script>
//需要在Vue中引入才可使用
const router=new VueRouter({
routes:[
{
//路由路径,必须以/开头
path:"/login",
//组件名称
component:loginForm
},
{
//路由路径,必须以/开头
path:"/register",
//组件名称
component:registerForm
}
]
});

const app=new Vue({
el:"#app",
/*//使用路由vue-router后,不需再引入components
components:{
//loginForm:loginForm, 缩写 loginForm,
loginForm,
registerForm
},*/
router//引用上面定义的router对象
});

</script>
</html>

在这里插入图片描述

路径引入

在这里插入图片描述