Node.js概述
2008年,google的Chrome发布,随后就以极快的速度占领市场,超过IE成为浏览器市场的主导者。
2009年,Ryan Dahl在在谷歌的Chrome V8引擎基础之上,打造了基于事件循环的异步IO框架:Node.js。
- 基于事件循环的异步IO
- 单线程运行,避免多线程的变量同步问题
- js可以编写后台代码前后台同一编程语言
Node.js的伟大之处不在于让js迈向了后端开发,而是构建了一个庞大的生态系统。
2010年,NPM作为Node.js的包管理系统首次发布,开发人员可以遵循Common.js的规范来编写Node.js模块,然后发布到NPM上供其他开发人员使用。目前已经是世界上最大的包管理系统。
随后,在Node.js的基础之上,涌现了一大批的前端框架:
MVVM概述
- M:即Model,模型,包括数据和一些基本操作。
- V:即View,视图,页面渲染结果。
- VM:即View-Model,模型与数据间的双向操作(无需开发人员干涉)。
在MVVM之前,开发人员从后端获取需要的数据模型,然后要通过DOM操作Model渲染到View中,而后当用户操作视图,我们还需要通过DOM获取View中的数据,然后同步到Model中。
而MVVM中的VM要做的事情就是把DOM操作完全封装起来,开发人员不用再关心Model和View之间是如何互相影响的:
- 只要Model发生了改变,View上自然就会显示出来。
- 当用户修改了View,Model中的数据也会随着更改。
这样主要就是将开发人员从繁琐的DOM操作中解放出来,把关注点放在如何操作Model上。
Vue概述
Vue是一套用于构建用户界面的渐进式框架。与其他的大型框架不同的是,Vue被设计为可以自底向上逐层应用。Vue的核心库只关注视图层,不仅易于上手,还便于与第三方库和既有项目整合。另一方面,当与现代化的工业链以及各种支持类库结合使用时,Vue也完全能够为复杂的单页应用提供驱动。
准备Vue.js的开发环境
在项目中使用Vue.js的方式有很多,在此,采用安装Node.js和NPM的环境来使用Vue.js。
1、安装Node.js
下载安装包之后直接单击安装:
安装结束之后在cmd命令窗口输入node -v查看是否安装成功:
2、安装NPM
事实是在安装好Node.js之后就会自带NPM的环境,可以通过在命令窗口输入npm -v来查看:
之后就通过NPM来下载相关的插件来进行Vue的使用。
但是NPM的默认仓库是在国外站点,下载插件速度较慢,在此可以设置到淘宝镜像进行下载。
在此,通过切换镜像的工具nrm来进行镜像切换:
3、安装nrm切换NPM的镜像仓库
①使用npm install nrm -g命令安装nrm
安装成功!
补充:安装nrm报错如下:
通过https://blog.csdn.net/sinat_31465609/article/details/88689571该博客解决方案解决了问题。
②通过nrm命令更换NPM仓库
nrm ls命令:显示所有可用的镜像仓库
nrm use 镜像名称:更换镜像仓库
安装完毕之后记得重启电脑!!!
安装完毕之后记得重启电脑!!!
安装完毕之后记得重启电脑!!!
接下来,就开始进入Vue的世界。
入门案例
1、创建静态项目HelloVue,用于做Demo演示。
2、初始化npm
在窗口中输入命令npm init -y来初始化。
然后刷新项目,就可以看到多的package.json文件,该文件就相当于Maven中的pom.xml文件,用于依赖导入。
3、使用NPM本地安装Vue
使用npm install vue --save命令可以进行Vue的本地安装。
安装结束之后在项目之中就会出现安装的Vue插件:
相对应的,package.json文件中也会新增关于vue的坐标信息:
如此,接下来就可以使用Vue.js了。
4、入门案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hello,Vue</title>
</head>
<body>
<div id="app">
你好!我是{{name}}
</div>
</body>
<script type="text/javascript" src="node_modules/vue/dist/vue.js"></script>
<script>
const app=new Vue({
el : "#app",
data : {
name : "刘德华"
}
});
</script>
</html>
以上就是Vue的入门案例,入门页面中包含以下几个注意点:
- Vue.js通过实例的Vue对象来管理页面模块,在案例中通过app对象的el属性绑定了页面中的id为app的div,表示该Vue对象就可以管理该div与其中的所有元素。
- app对象的data属性表示的是数据模型,在页面中通过{{name}}插值表达式进行动态绑定,可以实现数据的动态显示。
- 引入Vue.js的js文件,script标签必须成对出现。
5、入门案例优化:双向绑定及事件
在入门案例中,通过Vue对象的属性值影响页面上的显示效果称之为Vue的声明式渲染,同时,页面上的数据改变也会影响数据模型的改变:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hello,Vue</title>
</head>
<body>
<div id="app">
<input type="text" v-model="num">
你好!我是{{name}}。有{{num}}位美女喜欢我!
</div>
</body>
<script type="text/javascript" src="node_modules/vue/dist/vue.js"></script>
<script>
const app=new Vue({
el : "#app",
data : {
name : "刘德华",
num : 100
}
});
</script>
</html>
在上面案例中,通过input输入框中的v-model属性就可以实现input框的值与数据模型的值之间的绑定。修改input的值,也会影响数据模型的值,称之为Vue的双向绑定。
同时,也可以通过Vue的时间绑定来对数据模型产生影响:
<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Hello,Vue</title>
</head>
<body>
<div id="app">
<input type="text" v-model="num">
<br>
<input type="button" v-on:click="num++" value="美女+1">
<br>
你好!我是{{name}}。有{{num}}位美女喜欢我!
</div>
</body>
<script type="text/javascript" src="node_modules/vue/dist/vue.js"></script>
<script>
const app=new Vue({
el : "#app",
data : {
name : "刘德华",
num : 100
}
});
</script>
</html>
Vue中的事件格式为:v-on:事件名="js表达式或者方法名"
<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Hello,Vue</title>
</head>
<body>
<div id="app">
<input type="text" v-model="num">
<br>
<input type="button" v-on:click="incr" value="美女+1">
<br>
你好!我是{{name}}。有{{num}}位美女喜欢我!
</div>
</body>
<script type="text/javascript" src="node_modules/vue/dist/vue.js"></script>
<script>
const app=new Vue({
el : "#app",
data : {
name : "刘德华",
num : 100
},
methods :{
incr(){
this.num++;
}
}
});
</script>
</html>
Vue的生命周期
每个Vue实例被创建时都要经历一系列的初始化过程:创建实例,装载模板,渲染模板等等。Vue为生命周期中的每个状态都设置了钩子函数(监听函数)。每当Vue实例处于不同的生命周期时,对应的函数就会被触发调用。
指令
什么是指令?
指令是带有v-前缀的特殊特性。指令特性的预期值是:单个JavaScript表达式。指令的职责是,当表达式的值发生改变时,将其产生的连带影响,响应式的作用于DOM。
例如在入门案例中的v-on,代表绑定事件。
1、插值表达式
格式:{{表达式}}
说明:
- 该表达式支持JS语法,可以调用JS内置函数(函数必须有返回值)。
- 表达式必须有返回结果,没有返回结果的表达式不允许使用。
- 可以直接获取Vue实例中定义的数据和函数。
插值闪烁问题:
当使用插值表达式进行数据的动态渲染的时候,当后台响应速度或者网速较慢的时候,数据渲染会出现一定的时间差,此时网页上有可能直接将为渲染的插值表达式显示出来,这样的用户体验是不好的。
为解决这个问题,Vue推出了v-text和v-html指令来代替插值表达式。
v-text和v-html:
说明:
- v-text:将数据输出到元素内部,如果输出的数据有HTML代码,会作为普通文本输出。
- v-html:将数据输出到元素内部,如果输出的数据有HTML代码,会被渲染。
实例:
<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Hello,Vue</title>
</head>
<body>
<div id="app">
你好!我是<span v-text="name"></span>。有<span v-text="num"></span>位美女喜欢我!
</div>
</body>
<script type="text/javascript" src="node_modules/vue/dist/vue.js"></script>
<script>
const app=new Vue({
el : "#app",
data : {
name : "刘德华",
num : 100
}
});
</script>
</html>
效果:
2、v-model
v-text和v-html可以看作是数据和视图的单向绑定,数据影响了视图渲染,但是反过来就不行。
而v-model可以实现数据和视图的双向绑定,也就是说在视图中可以修改数据。既然是可以修改数据,就限定了v-model能够使用的元素类型,目前能够使用v-model的元素有:
- input
- select
- textarea
- checkbox
- radio
- components(Vue中的自定义组件)
基本上除了最后一项,其他的都是表单的输入项。
实例:
<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Hello,Vue</title>
</head>
<body>
<div id="app">
<input type="checkbox" value="python" v-model="language">python<br>
<input type="checkbox" value="java" v-model="language">java<br>
<input type="checkbox" value="php" v-model="language">php<br>
世界上最好的语言是:<span v-text="language.join(',')"></span>
</div>
</body>
<script type="text/javascript" src="node_modules/vue/dist/vue.js"></script>
<script>
const app=new Vue({
el : "#app",
data : {
language : []
}
});
</script>
</html>
注意:
- 多个checkbox对应一个model时,Model的类型应是一个数组,单个checkbox值默认是boolean类型。
- redio对应的值是input的value值。
- text和textarea默认对应的model是字符串。
- select单选对应字符串,多选对应也是数组。
3、v-on
v-on指令用于给页面元素绑定事件。
语法:v-on:事件名=“js片段或者函数名”
简写模式:v-on可以简写为@,例如"v-on:click"可以简写为"@click"
事件修饰符
在普通的事件处理中,有时候需要通过DOM操作来禁用某些组件的默认事件,例如如下案例:
<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Hello,Vue</title>
</head>
<body>
<div id="app">
数字:<span v-text="num"></span>
<br>
<input type="button" value="数字+1" @contextMenu="incr($event)">
</div>
</body>
<script type="text/javascript" src="node_modules/vue/dist/vue.js"></script>
<script>
const app=new Vue({
el : "#app",
data : {
num : 1
},
methods : {
incr(event){
event.preventDefault(); //禁用默认事件
this.num++;
}
}
});
</script>
</html>
在该案例中,是通过按钮的右击事件来实现数字的++,但是正常情况下在网页中右击会唤醒菜单。所以我们需要传递按钮的DOM对象到方法中,使用preventDefault()方法来禁用默认事件。
但是Vue讲究的是只关心数据业务逻辑,而不关心DOM操作,所以为了针对这种情况,Vue为v-on提供了事件修饰符,修饰符是由点开头的指令后缀来表示的。
- .stop:阻止默认事件冒泡到父元素
- .prevent:阻止默认事件的发生
- .captrue:使用事件捕获模式
- .self:只有元素自身触发事件才执行。(冒泡或捕获的都不执行)
- .once:只执行一次
接下来,我们使用.prevent事件修饰符来优化案例:
<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Hello,Vue</title>
</head>
<body>
<div id="app">
数字:<span v-text="num"></span>
<br>
<input type="button" value="数字+1" @contextMenu.prevent="incr">
</div>
</body>
<script type="text/javascript" src="node_modules/vue/dist/vue.js"></script>
<script>
const app=new Vue({
el : "#app",
data : {
num : 1
},
methods : {
incr(){
this.num++;
}
}
});
</script>
</html>
按键修饰符
Vue给我们提供了按键修饰符以监听键盘事件。
例如:
<input type="button" value="数字+1" @keyup.13="incr">
其中keyup.13的意思是,只有在按键编码为13的按键按起的时候才会触发incr()方法。
在键盘中,13编码代表回车键,字母按键从65开始,逐渐递增。
记住所有的按键编码是比较困难的,所以Vue为常用的按键提供了按键别名。
例如,以上案例可以改造为:
<input type="button" value="数字+1" @keyup.enter="incr">
Vue提供的全部的按键别名:
- .enter
- .tab
- .delete(捕获删除和退格键)
- .esc
- .space
- .up
- .down
- .left
- .right
组合按键:
Vue同时也支持组合按键的事件监听,例如Alt+C触发事件:
<input type="button" value="数字+1" @keyup.alt.67="incr">
常用组合键的别名:
- .ctrl
- .alt
- .shift
4、v-for
v-for用于遍历数据渲染页面。
语法:v-for=“item in items”
- items:遍历的目标数组,需要在Vue对象的data中定义好
- item:迭代得到的数组元素的别名
<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Hello,Vue</title>
</head>
<body>
<div id="app">
<ul>
<li v-for="(user,index) in users">
<span v-text="index+1"></span>-
<span v-text="user.name"></span>-
<span v-text="user.sex"></span>
</li>
</ul>
</div>
</body>
<script type="text/javascript" src="node_modules/vue/dist/vue.js"></script>
<script>
const app=new Vue({
el : "#app",
data : {
users : [
{name : "张三" , sex : "女"},
{name : "李四" , sex : "女"},
{name : "王五" , sex : "男"}
]
},
methods : {
}
});
</script>
</html>
同时,可以在v-for中同时获取数组的下标,当获取多个参数时需要用括号包起来。
例如:v-for="(user,index) in users"
v-for不仅能够遍历数组,也能够遍历对象,同时可以获取对象中所有的属性和属性名称以及属性对应的下标:
<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Hello,Vue</title>
</head>
<body>
<div id="app">
<ul>
<li v-for="(val,key,index) in user">
<span v-text="index+1"></span>-
<span v-text="key"></span>-
<span v-text="val"></span>
</li>
</ul>
</div>
</body>
<script type="text/javascript" src="node_modules/vue/dist/vue.js"></script>
<script>
const app=new Vue({
el : "#app",
data : {
user : {name : "张三" , sex : "女"}
},
methods : {
}
});
</script>
</html>
v-for的key:
当Vue.js使用v-for正在更新已经渲染过的元素列表时,它默认使用”就地复用策略“。如果数据项的顺序被改变,Vue将不会移动DOM元素来匹配数据项的顺序,而是简单复用此处的每个元素 ,并且确保它在特定索引下显示已被渲染过的每个元素。
这个功能可以有效的提高渲染的效率。
但是要实现这个功能,你需要自己去设置Key的值,并且要保证Key是每项都有且不唯一的数据。这样有助于追踪节点的身份,从而重用和重新排序现有元素。
<li v-for="(val,key,index) in user" :key="index"></li>
5、v-if和v-show
v-if:条件判断,当所得结果为true时,所在的元素才会被渲染。
语法:v-if=“布尔表达式”
v-if和v-show的使用方式和结果都相同,但是本质上是有根本区别的:
<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Hello,Vue</title>
</head>
<body>
<div id="app">
<input type="button" value="点击出现" @click="flag=!flag"><br>
<span v-if="flag">我出现了!if</span><br>
<span v-show="flag">我出现了!show</span>
</div>
</body>
<script type="text/javascript" src="node_modules/vue/dist/vue.js"></script>
<script>
const app=new Vue({
el : "#app",
data : {
flag : true
},
methods : {
}
});
</script>
</html>
v-if在表达式结果为false的时候所在的元素是不进行渲染的,而v-show只是在元素上加上了display:none来将元素隐藏起来。
所以,应当优先使用v-if。
除此之外,v-if还支持类似于java中的if-else分支:
<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Hello,Vue</title>
</head>
<body>
<div id="app">
<input type="button" value="点击生成随机数" @click="random=Math.random()">
<span v-text="random"></span>
<br>
<span v-if="random>0.75">random现在大于0.75</span>
<span v-else-if="random>0.2 && random<0.5">random现在在0.2-0.5之间</span>
<span v-else-if="random<0.2">random现在小于0.2</span>
<span v-else></span><br>
</div>
</body>
<script type="text/javascript" src="node_modules/vue/dist/vue.js"></script>
<script>
const app=new Vue({
el : "#app",
data : {
random : 0
},
methods : {
}
});
</script>
</html>
需要注意的是,v-else-if和java中的一样,else必须紧跟在if后面,所以两个span标签之间不能有任何的标签间隔。
6、v-bind
我们可以通过插值表达式或者v-text来完成页面数据的渲染,而v-bind则是用来对页面元素的属性值进行渲染的。
用处最多的地方是让元素的style样式根据数据模型而发生变化,例如,当有库存的时候购买按钮可以点击,库存为0的时候则不能点击:
<!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>Hello,Vue</title>
<style>
.ok{
background-color: aquamarine;
}
</style>
</head>
<body>
<div id="app">
<input type="text" v-model="num">
<br>
<input type="button" value="可购买" v-bind:class="{ok : num >0}">
</div>
</body>
<script type="text/javascript" src="node_modules/vue/dist/vue.js"></script>
<script>
const app=new Vue({
el : "#app",
data : {
num : 0
},
methods : {
}
});
</script>
</html>
v-bind:class="{ok : num >0}"表示动态的绑定class样式ok,当num值大于0的时候才会绑定该样式。
v-bind的简写模式:在动态绑定的属性前加一个":"即可。
例如:v-bind:class等于:class
7、计算属性
通过之前的学习,我们知道:在插值表达式中,不仅可以编译js表达式,也可以使用带返回值的函数。
在此,Vue提供了计算属性的概念。计算属性与data、methods一样都是Vue对象的属性,计算属性中必须是带有返回值的方法。
在使用计算属性中的方法的时候直接使用方法名称调用即可,Vue会将计算属性方法返回值的结果与方法名称编译为类似于数据模型的键值对,可以直接使用方法名称来进行调用。
<!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>Hello,Vue</title>
</head>
<body>
<div id="app">
计算属性方法生成的随机数:<span v-text="random"></span>
</div>
</body>
<script type="text/javascript" src="node_modules/vue/dist/vue.js"></script>
<script>
const app=new Vue({
el : "#app",
data : {
},
methods : {
},
computed : {
random(){
return Math.random();
}
}
});
</script>
</html>
8 、watch监听
在Vue中,可以使用watch监听来监听某个数据模型的变化。
watch也是Vue对象的属性,其中的内容都是方法,方法名称必须与被监听的数据模型名称相同。每个监听方法默认都有两个参数,参数一代表当前数据模型的值,参数二代表数据模型发生变化前的值,也就是旧的值。
我们在监听方法中,就可以通过这两个参数动态的产生效果。
组件化
在大型应用开发的时候,页面可以划分为很多部分。往往不同的页面也会有相同的部分,例如可能会有相同的头部导航。
但是如果每个页面都独自开发,这无疑增加了我们开发的成本。所以我们会把页面的不同部分拆分成独立的组件,然后在不同的页面就可以共享这些组件,避免重复开发。
在Vue中,每个Vue对象都是组件,默认实例化的Vue对象为父组件,定义的可重用组件为子组件。
1、全局组件
<!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>Hello,Vue</title>
</head>
<body>
<div id="app">
<!--直接使用组件名调用组件-->
<counter></counter>
</div>
</body>
<script type="text/javascript" src="node_modules/vue/dist/vue.js"></script>
<script>
/**
* 定义全局组件,第一个参数是组件名,第二个参数是组件的具体实现
*/
Vue.component("counter",{
//template是代表组件要渲染的html内容
template : "<button @click='num++'>点我+1,{{num}}</button>",
//定义数据源
data(){
return {
num : 0
}
}
})
const app=new Vue({
el : "#app",
data : {
}
});
</script>
</html>
Vue的全局组件是使用Vue对象的component属性进行创建并绑定,创建完毕之后可以在页面的任何地方使用组件名进行使用。
并且组件之间是可复用的,哪怕复制的全局组件,数据源之间也不是通用的。
2、局部组件
<!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>Hello,Vue</title>
</head>
<body>
<div id="app">
<hello1></hello1>
</div>
</body>
<script type="text/javascript" src="node_modules/vue/dist/vue.js"></script>
<script>
const hello={
template : "<div>大家好,我是{{name}}</div>",
data(){
return {
name : "张旭"
}
}
}
const app=new Vue({
el : "#app",
data : {
},
components : {
hello1 : hello
}
});
</script>
</html>
局部组件使用创建实例对象的形式创建,创建完毕之后需要在父组件Vue对象中使用components来进行绑定,绑定的是以键值对的形式,然后就可以使用键值对的key值进行组件的调用。
3、组件之间的通信
①props(父向子传递)
- 父组件使用子组件时,在调用的子组件上自定义属性(属性名称任意,属性值为要传递的数据)
- 子组件通过props接收父组件数据,通过自定义属性的属性名
<!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>Hello,Vue</title>
</head>
<body>
<div id="app">
<!--直接使用组件名调用组件-->
<counter :num1="num"></counter>
</div>
</body>
<script type="text/javascript" src="node_modules/vue/dist/vue.js"></script>
<script>
/**
* 定义全局组件,第一个参数是组件名,第二个参数是组件的具体实现
*/
Vue.component("counter",{
//template是代表组件要渲染的html内容
template : "<button @click='num1++'>点我+1,{{num1}}</button>",
props : ['num1']
})
const app=new Vue({
el : "#app",
data : {
num : 0
}
});
</script>
</html>
在以上实例中,实现了父组件向子组件之间的通信。子组件并没有定义数据源,而是父组件在调用子组件的时候通过:num1='num’的形式,使用v-bind动态绑定了父组件中的数据源num,然后子组件再荣国props=[‘num1’]的形式获取父组件绑定的数据源。
但是,这样只是完成了父组件往子组件之间的通信,子组件在修改数据的时候并不会对父组件的数据源产生影响,因为子组件没有与父组件产生通信。
props验证:
子组件不仅可以通过psops属性来接收父组件传递的数据,同时也可以对数据进行校验。
props : {
num1 : {
//数据类型
type : Number,
//默认值
default :0,
//是否必须
required : true
}
}
校验的三个选项如上案例,但是此校验并不是当校验失败的时候就不执行,无论校验是否成功都会显示在页面上,只不过如果校验错误的时候会在浏览器的控制台输出错误信息。
props校验提供的常用的数据类型:
- String
- Number
- Boolean
- Array
- Object
- Date
- Function
- Symbol
②$emit()(子向父通信)
<!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>Hello,Vue</title>
</head>
<body>
<div id="app">
<!--直接使用组件名调用组件-->
<counter :num1="num" @incr1="incr()"></counter>
</div>
</body>
<script type="text/javascript" src="node_modules/vue/dist/vue.js"></script>
<script>
/**
* 定义全局组件,第一个参数是组件名,第二个参数是组件的具体实现
*/
Vue.component("counter",{
//template是代表组件要渲染的html内容
template : "<button @click='subIncr'>点我+1,{{num1}}</button>",
props : {
num1 : {
type : Number,
default :0,
required : true
}
},
methods : {
subIncr(){
this.$emit("incr1");
}
}
})
const app=new Vue({
el : "#app",
data : {
num : 0
},
methods : {
incr(){
this.num++;
}
}
});
</script>
</html>
子组件事实上是无法直接向父组件传递数据的,不过传递数据的本质是进行数据的同步和共享,也就是说只要能实现在子组件中对数据进行修改的同时,父组件的数据源也能发生改变即可。
所以子向父传递的本质是除了传递数据源之外,将子组件对数据的操作由直接操作传递过来的数据修改为使用父组件传递的方法修改父组件的数据,父组件的数据修改之后,自组件的数据也会随之自动修改。
所以,除了传递数据源之外还要根据需求传递修改数据的方法,在调用子组件的标签上使用自定义的事件来传递方法,然后在子组件中可以通过$emit来获取自定义事件所绑定的方法。
路由
接下来,通过案例实现注册组件和登录组件之间的相互跳转来接触Vue的路由。
1、案例准备工作
准备index.html用于展示效果,准备login.js定义登录页的组件,准备registry.js定义注册页的组件。
login.js:
const loginForm=({
template : `
<div>
<h1>登录页</h1>
用户名:<input type="text"><br>
密 码:<input type="password"><br>
<input type="button" value="登录">
</div>
`
})
registry.js:
const registryForm=({
template : `
<div>
<h1>注册页</h1>
用 户 名:<input type="text"><br>
密  码:<input type="password"><br>
确认密码:<input type="password"><br>
<input type="button" value="注册">
</div>
`
})
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>index</title>
</head>
<body>
<div id="app">
<a href="#">登录</a>
<a href="#">注册</a>
<hr>
<login-Form></login-Form>
<registry-Form></registry-Form>
</div>
</body>
<script src="../node_modules/vue/dist/vue.js"></script>
<script src="js/login.js"></script>
<script src="js/registry.js"></script>
<script>
const app=new Vue({
el : "#app",
components : {
loginForm,
registryForm
}
})
</script>
</html>
页面效果:
预期实现:点击登录的时候页面只显示登录页组件,点击注册的时候只显示注册页组件。
vue-router
我们可以使用vue-router来完成组件之间的路由。
1、安装vue-router
使用npm install vue-router --save来安装vue-router
2、引入vue-router并且配置路由
<script src="../node_modules/vue-router/dist/vue-router.js"></script>
<script>
//配置路由对象
const router=new VueRouter({
routes : [
{
//配置路由和路由对应的组件=
path:"/login",
component:loginForm
},{
path:"/registry",
component: registryForm
}
]
})
const app=new Vue({
el : "#app",
router
})
</script>
配置路由和路由对应的组件之后,需要在Vue对象中引用这个路由对象。然后因为在路由对象中引用了组件,所以Vue对象中就不需要再引用组件。
3、使用vue-router定义的标签来配置路由触发和锚点
<div id="app">
<router-link to="/login">登录</router-link>
<router-link to="/registry">注册</router-link>
<hr>
<!--路由锚点-->
<router-view></router-view>
</div>
<router-link>标签中的to属性代表对应可以激活的路由,而激活的组件是显示在<router-view>锚点位置。