Vue从零到实战

一、Vue核心知识了解

1.1、初识VUE,走进VUE的世界

历史介绍

angular 09年,年份较早,一开始大家是拒绝 star:59.3k
react 2013年, 用户体验好,直接拉到一堆粉丝 star:119k
vue 2014年, 用户体验好 star:124k

Vue等框架与jQuery的区别

jQuery是基于操作dom的库
Vue框架是以数据驱动和组件化开发为核心

1.2、引包、留坑、实例化 、插值表达式{{}}

引包
确认已经下载了node,然后执行命令 npm install vue (如需下载自己要的版本在vue后面加上@版本号);
页面引入刚下载的包:

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

留坑

即留一个vue模板插入的地方或者是vue代码对其生效的地方

实例化 即启动Vue

启动:
 new Vue({el:目的地,template:模板内容});实例化传入的是一个对象options

options
目的地 el 对应上面留坑的坑位,可通过id名,类名,标签名来查找 。方式和jq一样
内容 template
数据 data 值为函数形式也可是对象,但是都是用函数,因为用的函数最后也是return一个对象

插值表达式:{{ }}

插值表达式内填入data里面的变量即可在页面取到变量值{{ data里的变量 }}

实例:

<!DOCTYPE html>
<html>
<head>
	<title></title>
</head>
<body>
	<!-- 留坑,为了后边在这里插值 -->
	<div id="app"></div>

	<!-- 引包 -->
	<script type="text/javascript" src="vue.js"></script>
	<script type="text/javascript">
		// 实例化启动vue
		new Vue({
			el:'#app',//目的的,可以识别类名、id名和标签名,如果做到极致优化可以直接用document.getElementById获取
			template:`     //注意:template模板内容里的根节点只能有一个(最外层只能有一个div,不能再有span、div等节点了)
			<div>
				<div>我这里是模板内容{{ msg }}</div>
				<div>111</div>
			</div>
			`,
			data:function(){
				return {
					msg:'Hello Vue!'
				}
			}
		})
	</script>
</body>
</html>

结果:
在这里插入图片描述

1.3、熟悉及使用常用指令

什么是指令

在vue中提供一些对于页面+数据的更为方便的操作,这些操作就叫做指令。
指令就是以数据去驱动DOM行为的,简化DOM操作;
如在HTML页面中这样使用<div v-xxx=''></div>,在vue中v-xxx就是vue的指令;

常用的指令及怎么使用这些指令

v-text 不可解析html标签   必须是双标签
v-html 可解析html标签

v-if 判断后,做元素的插入(append)和移除(remove)操作
v-else-if
v-else

v-show  判断是否隐藏,display:none 和display:block的切换

v-for

数组 item,index
对象 value,key ,index

代码案例:

<!DOCTYPE html>
<html>
<head>
	<title></title>
</head>
<body>
	<div id="app"></div>
	<script type="text/javascript" src="vue.js"></script>
	<script type="text/javascript">
		
		new Vue({
			el:'#app',
			template:`
			<div>
					<!--测试v-text-->
					<div v-text='mytext'></div>
					</hr>
					<!--测试v-html-->
					<div v-html='myhtml'></div>
					<!--测试v-if  v-else-if  v-else-->
					<button v-if='num==1'>测试v-if</button>
					<button v-else-if='num==2'>测试v-else-if</button>
					<button v-else>测试v-else</button>

					<!--测试v-show-->
					<div v-show='checkshow'>我是V-SHOW</div>
					
					<!--循环数组-->
					<ul>
					<!--item:数组里的每一项,index:数组索引-->
					<li v-for='(item,index) in arrayfor'>
					{{ item }}-{{index}}
					</li>
					</ul>
					
					<ul>
					<!--循环对象-->
					<li v-for='(oj,key) in ojfor'>
					{{key}}:{{oj}}
					</li>
					</ul>
			</div>
			`,
			data:function(){
				return {
					mytext:'<h1>我这里是v-text</h1>',
					myhtml:'<h1>我这里是v-html</h1>',
					//1:测试v-if  2:测试v-else-if  其他值:测试v-else
					num:6,
					//true:显示,false:隐藏
					checkshow:true,
					//定义数组
					arrayfor:['篮球','足球','乒乓球'],
					//定义一对象
					ojfor:{play:'篮球',people:'ming',age:'19'}
				}
			}
		})
	</script>
</body>
</html>

效果:
在这里插入图片描述

1.4、阐述vue单双向数据流及事件绑定

vue单向数据流绑定属性值 v-bind: (属性) 简写 :(属性)

单向数据绑定 内存(js)改变影响页面改变(js的改变会影响页面,但是页面的改变不会影响js)
例子:<input v-bind:value="name" v-bind:class="name">
v-bind就是对属性的简单赋值,当内存中值改变,还是会触发重新渲染

vue双向数据流 v-model 只作用于有value属性的元素

例子:<input v-model="name" v-bind:class="name">
双向数据绑定 页面对于input的value改变,能影响内存中name变量
内存js改变name的值,会影响页面重新渲染最新值

单双向数据流代码

<!DOCTYPE html>
<html>
<head>
	<title></title>
</head>
<body>
	<div id="app"></div>

	<script type="text/javascript" src="vue.js"></script>
	<script type="text/javascript">
		console.log(this)
		new Vue({
			el:"#app",
			template:`
				<div>
				单向数据绑定
				<input type='text' v-bind:value="name" :class="name"><br>
				双向数据绑定
				<input type='text' v-model="name"></br>
				{{ name }}
				</div>
			`,
			data:function(){
				return {
					name:'hello'
				}
			}
			
		})
	</script>
</body>
</html>

效果:
在这里插入图片描述
事件绑定:v-on:事件名=“表达式||函数名”, 简写: @事件名=“表达式||函数名”

事件名可以是原生也可以是自定义的
<!DOCTYPE html>
<html>
<head>
	<title></title>
</head>
<body>
	<div id="app"></div>

	<script type="text/javascript" src="vue.js"></script>
	<script type="text/javascript">
		console.log(this)
		new Vue({
			el:"#app",
			template:`
				<div>
				单向数据绑定
				<input type='text' v-bind:value="name" :class="name"><br>
				双向数据绑定
				<input type='text' v-model="name"></br>
				{{ name }}
				<button v-on:click="change">点击我改变name变量</button>
				</div>

			`,
			data:function(){
				return {
					name:'hello'
				}
			},
			methods:{
				change:function(){
					//console.log(this)
					this.name='我改变了,是在方法属性里面定义的方法'
				},
			}
		})
	</script>
</body>
</html>

效果:
在这里插入图片描述
总结

v-model 双向数据绑定:
vue页面改变影响内存(js)
内存(js)改变影响vue页面;

v-bind 单向数据绑定只是内存(js)改变影响vue页面

1.5、过滤器

简介:如何给数据添加一个管道进行进一步处理再输出

过滤器就是可以对我们的数据进行添油加醋然后再显示

过滤器有全局过滤器和组件内的过滤器

全局过滤器Vue.filter('过滤器名',过滤方式fn );
组件内的过滤器 filters:{ '过滤器名',过滤方式fn }
{{ msg | 过滤器名}}
最终都是在过滤方式fn里面return产出最终你需要的数据

vue中的this是vue封装好给我们使用的,跟平常方法里面的this是不同的

代码展示:

<!DOCTYPE html>
<html>
<head>
	<title>过滤器</title>
</head>
<body>
		<div id="app">
			我输入的:<input type="text" name="" v-model='instring'></br>
			我输出的:{{ instring }}</br>
			<!--将instring作为参数传到reversal过滤器里,这里最后显示的结果就是过滤器返回的结果-->
			翻转输出::{{ instring | reversal}}
		</div>

		<script type="text/javascript" src="vue.js"></script>
		<script type="text/javascript">
			new Vue({
				el:'#app',
				data(){
					return {
						instring:''
					}
				},
				//组件内过滤器
				 filters:{
				    //reversal:过滤器名字
				 	reversal(val){
				    // 字符串转数组后进行翻转,将翻转后的数组转为字符串
					return  val.split('').reverse().join('')
				 	}
				 }
			})
		</script>
</body>
</html>

结果:
在这里插入图片描述
上边是组件内过滤器,下边介绍全局过滤器

<!DOCTYPE html>
<html>
<head>
	<title>过滤器</title>
</head>
<body>
		<div id="app">
			我输入的:<input type="text" name="" v-model='instring'></br>
			我输出的:{{ instring }}</br>
			{{ instring | reversal('翻转输出:')}}
		</div>

		<script type="text/javascript" src="vue.js"></script>
		<script type="text/javascript">
		//过滤器名字加引号
			Vue.filter('reversal',function(val,arg2){
				return  arg2+val.split('').reverse().join('')
			})
			new Vue({
				el:'#app',
				data(){
					return {
						instring:''
					}
				}
			})
		</script>
</body>
</html>

1.6、数据监听watch与计算属性computed

数据的单个监听以及多个监听还有深度监听的不同

watch监听单个,computed监听多个

思考业务场景:

类似淘宝,当我输入某个人名字时,我想触发某个效果
利用vue做一个简单的计算器
当watch监听的是复杂数据类型的时候需要做深度监听(写法如下)

watch:{
            msg:{
              handler(val){
               if(val.text=='love'){
                alert(val.text)
               }
              },
              deep:true//开启深度监听
            }
          }
computed 监视对象,写在了函数内部, 凡是函数内部有this.相关属性,改变都会触发当前函数

代码展示:
监听一般数据类型:

<!DOCTYPE html>
<html>
<head>
	<title></title>
</head>
<body>
	<div id="app">
		<div>watch监听数据</div>
		<input type="text" name="" v-model='msg'>
	</div>

	<script type="text/javascript" src="vue.js"></script>
	<script type="text/javascript">
		
		new Vue({
			el:'#app',
			data(){
				return {
					msg:‘’
				}
			},

			watch:{
				msg:{
					msg(newval,oldval){
						if(newval.text=='love'){
							alert(newval.text)
						}
					}
				}
			}
		})
	</script>
</body>
</html>

复杂数据类型监听

<!DOCTYPE html>
<html>
<head>
	<title></title>
</head>
<body>
	<div id="app">
		<div>watch监听数据</div>
		<input type="text" name="" v-model='msg.text'>
	</div>

	<script type="text/javascript" src="vue.js"></script>
	<script type="text/javascript">
		
		new Vue({
			el:'#app',
			data(){
				return {
					msg:{text:''}
				}
			},

			watch:{
				msg:{
					handler(newval,oldval){
						if(newval.text=='love'){
							alert(newval.text)
						}
					},
					//开启深度监听(监听复杂数据时开启深度监听,一层一层监听里边的数据)
					deep:true
				}
			}
		})
	</script>
</body>
</html>

效果:
在这里插入图片描述
计算属性,做一个计算器

<!DOCTYPE html>
<html>
<head>
	<title></title>
</head>
<body>
	<div id="app">
		<div>computed计算属性</div>
		(<input type="text" name="" v-model='n1'>+
		<input type="text" name="" v-model='n2'>)*
		<input type="text" name="" v-model='n3'>={{result}}
	</div>

	<script type="text/javascript" src="vue.js"></script>
	<script type="text/javascript">
		
		new Vue({
			el:'#app',
			data(){
				return {
					n1:'',
					n2:'',
					//默认值设置为1
					n3:'1'
				}
			},
			computed:{
				result(){
					return (Number(this.n1)+Number(this.n2))*Number(this.n3)
				}
			}
		})
	</script>
</body>
</html>

结果:
在这里插入图片描述

二、组件化开发知识介绍

2.1、组件化开发

简介:讲述页面拆分为组件进行开发和维护

创建组件的两种方式:
方式一、var Header = { template:'模板' , data是一个函数,methods:功能,components:子组件们 }//局部声明​
方式二、Vue.component('组件名',组件对象);//全局注册 等于注册加声明了
 
组件类型:
通用组件(例如表单、弹窗、布局类等)
业务组件(抽奖、机器分类)
页面组件(单页面开发程序的每个页面的都是一个组件、只完成功能、不复用)
组件开发三步曲:声明、注册、使用

代码展示:

<!DOCTYPE html>
<html>
<head>
	<title>组件化开发</title>
</head>
<body>
	<div id="app">
		
	</div>

	<script type="text/javascript" src="vue.js"></script>
	<script type="text/javascript">
	    //局部声明组件
		var MyHeader={
			template:`
				<div>我是头部</div>
			`,

		}
		//局部声明组件
		var MyBody=Vue.extend({
			template:`
				<div>我是身体</div>
			`
		})
		//这个是语法糖
		// var MyBody={
		// 	template:`
		// 		<div>我是身体</div>
		// 	`
		// }
		//全局创建组件
		Vue.component('MyFooter',{
			template:`
				<div>我是尾部</div>
			`
		})
		new Vue({
			el:'#app',
			//注册组件
			components:{
				MyHeader,
				MyBody
			},
			template:`
			    //使用组件
				<div>
					<my-header></my-header>
					<my-body></my-body>
					<my-footer></my-footer>
				</div>
			`,
			data(){
				return{}
			},
		})
	</script>
</body>
</html>

效果:
在这里插入图片描述

2.2、slot插槽和ref、$parent

简介:讲述如何设计可扩展组件及获取子组件和父组件实例

slot插槽(组件嵌套组件的话就使用slor)

slot就是子组件里给DOM留下的坑位
<子组件>DOM</子组件>
slot是动态的DOM
ref获取子组件实例

识别:在子组件或元素上使用属性ref="xxxx"
获取:this.$refs.xxxx 获取元素
$el 是拿其DOM
$parent获取父组件实例(可在子组件直接使用this.$parent即可)

代码展示:

<!DOCTYPE html>
<html>
<head>
	<title>组件化开发</title>
</head>
<body>
	<div id="app">
		
	</div>

	<script type="text/javascript" src="vue.js"></script>
	<script type="text/javascript">
		var Parent={
			template:`
				<div>
				我是父组件
				<slot name='hello'></slot>
				</div>
			`,
		}
		
		new Vue({
			el:'#app',
			components:{
				Parent
			},
			template:`
				<div>
					<parent>
					    //不指定name值,这里是无效的
						<div>我是插槽内容</div>
						//指定了name值,是有效果的
						<div slot='hello'>我是插槽内容2</div>
					</parent>
				</div>
			`,
			data(){
				return{}
			},
		})
	</script>
</body>
</html>

效果:
在这里插入图片描述
代码展示2:

<!DOCTYPE html>
<html>
<head>
	<title>组件化开发</title>
</head>
<body>
	<div id="app">
		
	</div>

	<script type="text/javascript" src="vue.js"></script>
	<script type="text/javascript">
		var Child={
			template:`
				<div>我是子组件</div>
			`,
			data(){
				return {
					msg:'hello'
				}
			},
			created(){
				console.log(this.$parent)
			}

		}
		var Parent={
			template:`
				<div>
				我是父组件
				<slot name='hello'></slot>
				<child ref='childs'></child>
				</div>
			`,
			components:{
				Child
			},
			data(){
				return {
					parents:'我是父组件'
				}
			},
			mounted(){
				// console.log(this.$refs.childs)
			}
		}
		
		new Vue({
			el:'#app',
			components:{
				Parent
			},
			template:`
				<div>
					<parent>
						<div>我是插槽内容</div>
						<div slot='hello'>我是插槽内容2</div>
					</parent>
				</div>
			`,
			data(){
				return{}
			},
		})
	</script>
</body>
</html>

效果:
在这里插入图片描述

2.3、父子组件的通信

简介:搭起专属于父子组件之间的沟通桥梁

父传子:(父亲传递数据给子)
父用子的时候通过属性传递
子要声明props:['属性名'] 来接收
子收到后就是自己的了,随便用
     1、在template中 直接可以用
     2、在js中使用   this.属性名  的方式用

子传父:(子传递数据给父亲)
子组件里通过$emit('自定义事件名',变量1,变量2)触发
父组件@自定义事件名=‘事件名’监听
子组件方法里  this.$emit('sendfather',val1,val2)触发自定义事件
父组件里  <child @sendfather='mymethods'></child>

父传子实例展示:

<!DOCTYPE html>
<html>
<head>
	<title>父子组件的通信</title>
</head>
<body>
	<div id="app">
		
	</div>

	<script type="text/javascript" src="vue.js"></script>
	<script type="text/javascript">
		//定义子组件,子组件定义好了props,接收到数据后直接用
		var Child={
			template:`
				<div>
				我是子组件{{sendchild}}
				</div>
			`,
			//这里接收父亲传递过来的数据,接收到以后,像上边那样随便用即可
			props:['sendchild'],
		}
		//定义一个父组件,父组件通过属性sendchild传递了数据给子组件
		var Parent={
			template:`
				<div>
				我是父组件
				<child sendchild='父亲给你的' ></child>
				</div>
			`,
			components:{
				Child
			}
		}
		
		new Vue({
			el:'#app',
			components:{
				Parent
			},
			template:`
				<div>
				<parent></parent>
				</div>
			`,
			data(){
				return {

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

效果:
在这里插入图片描述
子传父实例展示:

<!DOCTYPE html>
<html>
<head>
	<title>父子组件的通信</title>
</head>
<body>
	<div id="app">
		
	</div>

	<script type="text/javascript" src="vue.js"></script>
	<script type="text/javascript">
		//子组件定义好了props直接用
		var Child={
			template:`
				<div>
				我是子组件{{sendchild}}
				<button @click='sendparent'>我要反馈东西给父亲</button>
				</div>
			`,
			props:['sendchild'],
			methods:{
				sendparent(){
					this.$emit('baba','这是儿子组件给你的')
				}
			}

		}
		//父组件通过属性sendchild传递了数据给子组件
		var Parent={
			template:`
				<div>
				我是父组件{{ msg }}
				//@baba,监听事件,监听子传递来的数据
				<child sendchild='父亲给你的' @baba='reserve'></child>

				</div>
			`,
			components:{
				Child
			},
			data(){
				return {
					msg:''
				}
			},
			methods:{
				reserve(val){
						this.msg=val
				}
			}
		}
		
		new Vue({
			el:'#app',
			components:{
				Parent
			},
			template:`
				<div>
				<parent></parent>
				</div>
			`,
			data(){
				return {

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

效果:
在这里插入图片描述
在这里插入图片描述

2.4、非父子组件之间的通信

简介:建立Bus总线机制实施非父子组件通讯(相当于通过中间的一个东西实现父子通信)

创建一个空实例(bus中央事件总线也可以叫中间组件)
利用$emit $on的触发和监听事件实现非父子组件的通信
Vue.prototype.$bus=new Vue()//在vue上面挂载一个$bus作为中央处理组件
this.$bus.$emit('自定义事件名','传递的数据')//触发自定义事件传递数据
this.$bus.$on('自定义事件名',fn)//监听自定义事件获取数据
解决的方案还有vuex、provide/inject是解决同根往下派发、本地存储也可以进行非父子组件之间的通信

案例展示

<!DOCTYPE html>
<html>
<head>
	<title>非父子组件的通信</title>
</head>
<body>
	<div id="app">
		
	</div>

	<script type="text/javascript" src="vue.js"></script>
	<script type="text/javascript">
        //创建一个空实例,$bus可以自定义的,不是写死的
		Vue.prototype.$bus=new Vue()
		
		var MyHeader={
			template:`
				<div>
				我是头部
				{{ headermsg }}
				</div>
			`,
			data(){
				return {
					headermsg:'我是头部的信息'
				}
			},
			created(){
			    //写法一
				// var self=this
				// self.$bus.$on('sending',function(val){
				// 	self.headermsg=val
				// })
				//写法二
				this.$bus.$on('sending',val=>{
					this.headermsg=val
				})
			}
		}
		var MyBody={
			template:`
				<div>我是身体</div>
			`,
		}
		var MyFooter={
			template:`
				<div>我是底部<button @click='sendhead'>我要跟头部通信</button></div>
			`,
			methods:{
				sendhead(){
					this.$bus.$emit('sending','我是底部的数据')
				}
			}
		}
		new Vue({
			el:'#app',
			components:{
				MyHeader,
				MyBody,
				MyFooter
			},
			template:`
				<div>
					<my-header></my-header><hr>
					<my-body></my-body><hr>
					<my-footer></my-footer>
				</div>
			`,
			data(){
				return {}
			},
		})
	</script>
</body>
</html>

效果:
在这里插入图片描述
在这里插入图片描述

2.5、vue的生命周期

vue生命周期官方介绍

简介:详述vue所有的生命周期钩子函数的作用

需要频繁的创建和销毁组件
比如页面中部分内容显示与隐藏,但是用的是v-if
组件缓存
内置组件中
被其包裹的组件,在v-if=false的时候,不会销毁,而是停用
v-if="true" 不会创建,而是激活
避免频繁创建组件对象的性能损耗
组件的激活和停用
activated 和 deactivated
成对比较
created 和 beforeCreate
A 可以操作数据 B 数据没有初始化
mounted 和 beforeMount
A 可以操作DOM B 还未生成DOM
updated 和 beforeUpdate
A 可以获取最终数据 B 可以二次修改
destroyed 和 beforeDestroy
性能调优:频繁销毁创建的组件使用内置组件包裹

html:

<!DOCTYPE html>
<html>
<head>
	<title>vue的生命周期</title>
</head>
<body>
	<div id="app">
		
	</div>

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


	</script>
</body>
</html>

js:

 // created 和 beforeCreate 

		 // A 可以操作数据 B 数据没有初始化

		 // mounted 和 beforeMount

		 // A 可以操作DOM B 还未生成DOM

		 // updated 和 beforeUpdate

		 //  A 可以获取最终数据 B 可以二次修改

		 // destroyed 和 beforeDestroy
		var Test={
			template:`
				<div>我是Test组件{{ msg }}
				<button @click="msg+='1'">msg+1</button>
				</div>
			`,
			data(){
				return{
					msg:'HELLO VUE'
				}
			},
			//组件创建前
			beforeCreate(){
				console.log('组件创建前')
				console.log(this.msg)
			},
			//组件创建后
			created(){
				console.log('组件创建后')
				console.log(this.msg)
			},
			//Dom挂载前
			// beforeMount(){
			// 	console.log('Dom挂载前')
			// 	console.log(document.body.innerHTML)
			// },
			// //Dom挂载后
			// mounted(){
			// 	console.log('Dom挂载后')
			// 	console.log(document.body.innerHTML)
			// }
			//基于数据更新前
			beforeUpdate(){
					console.log('数据更新前')
					console.log(document.body.innerHTML)
			},

			//基于数据更新后
			updated(){
					console.log('数据更新后')
					console.log(document.body.innerHTML)
			},
			//销毁前
			beforeDestroy(){
				console.log('销毁前')
			},
			//销毁后
			destroyed(){
				console.log('销毁后')
			},
			//组件停用
			deactivated(){
				console.log('组件停用')
			},
			//组件激活
			activated (){
				console.log('组件激活')
			}
		}
		new Vue({
			el:'#app',
			components:{
				Test	
			},
			template:`
				<div>
					<keep-alive><test v-if='testshow'></test></keep-alive></br>
					<button @click='clickbut'>销毁组件</button>
				</div>
			`,
			data(){
				return {
					testshow:true
				}
			},
			methods:{
				clickbut(){
					this.testshow=!this.testshow
				}
			}
		})

效果:

每测试一步,可以自己在浏览器的控制台查看

三、Vue核心插件之路由模块

3.1、路由的跳转原理(哈希模式)

简介:了解vue核心插件的工作原理

单页应用的路由模式有两种
哈希模式(常用的模式):利用hashchange 事件监听 url的hash 的改变
history模式:使用此模式需要后台配合把接口都打到我们打包后的index.html上

哈希模式原理:
window.addEventListener('hashchange', function(e) {
  console.log(e)
})

哈希模式核心是锚点值的改变,我们监听到锚点值改变了就去局部改变页面数据,不是做跳转。跟传统开发模式url改变后,立刻发起请求,
响应整个页面,渲染整个页面比路由的跳转用户体验更好;

代码展示:

<!DOCTYPE html>
<html>
<head>
	<title></title>
</head>
<body>
	<a href="#/login">登录</a>
	|
	<a href="#/register">注册</a>
	<div id="app"></div>

	<script type="text/javascript">
		var appdiv=document.getElementById('app')

		window.addEventListener('hashchange', function(e) {
			  console.log(location.hash)
			  switch(location.hash){
			  	case '#/login':
			  	appdiv.innerHTML='我是登录页面';
			  	break;
			  	case '#/register':
			  	appdiv.innerHTML='我是注册页面';
			  	break;
			  }
			})
	</script>
</body>
</html>

效果:
在这里插入图片描述

3.2、 安装和使用路由

简介:引入路由插件,简单了解单页应用的实现

路由是以插件的形式引入到我们的vue项目中来的

vue-router是vue的核心插件:
1:下载 npm i vue-router -S
2:安装插件Vue.use(VueRouter);
3:创建路由对象 var router = new VueRouter();
4:配置路由规则 router.addRoutes([路由对象]);
路由对象{path:'锚点值',component:要(填坑)显示的组件}
5:将配置好的路由对象交给Vue
在options中传递-> key叫做 router
6:留坑(使用组件) <router-view></router-view>

代码:

<!DOCTYPE html>
<html>
<head>
	<title>路由的安装和使用</title>
</head>
<body>
	<div id="app">
		
	</div>

	<script type="text/javascript" src="vue.js"></script>
	<!-- 引入路由插件 -->
	<script type="text/javascript" src="vue-router.js"></script>
	<script type="text/javascript">
		var Login={
			template:`
				<div>我是登录页面</div>
			`,
		}
		//安装路由插件
		Vue.use(VueRouter);
		//创建路由对象
		var router= new VueRouter({
			//配置路由对象
			routes:[
				{path:'/login',name:'login',component:Login}
			]
		})
		new Vue({
			el:'#app',
			//将配置好的路由对象交给Vue
			router,
			template:`
				<div>
					<p>请在链接上加上login测试路由功能</p>
					<!--使用组件-->
					<router-view></router-view>
				</div>
			`,
			data(){
				return {}
			},
		})
	</script>
</body>
</html>

3.3、路由的跳转

简介:简述路由的几种跳转方式及他们之间的异同

路由的跳转方式有:
通过标签:<router-link to='/login'></router-link>
通过js控制跳转this.$router.push({path:'/login'})

区别:
this.$router.push() 跳转到指定的url,会向history插入新记录
this.$router.replace() 同样是跳转到指定的url,但是这个方法不会向history里面添加新的记录,点击返回,
会跳转到上上一个页面。上一个记录是不存在的。
this.$router.go(-1) 常用来做返回,读history里面的记录后退一个

vue-router中的对象:
$route 路由信息对象,只读对象
$router 路由操作对象,只写对象

代码展示

<!DOCTYPE html>
<html>
<head>
	<title>路由的跳转</title>
</head>
<body>
	<div id="app">
		
	</div>

	<script type="text/javascript" src="vue.js"></script>
	<!-- 引入路由插件 -->
	<script type="text/javascript" src="vue-router.js"></script>
	<script type="text/javascript">

		var Login={
			template:`
				<div>我是登录页面</div>
			`,
		}
		var Register={
			template:`
				<div>我是注册页面</div>
			`,
		}
	
		//安装路由插件
		Vue.use(VueRouter);
		//创建路由对象
		var router= new VueRouter({
			//配置路由对象
			routes:[
				{path:'/login',name:'login',component:Login},
				{path:'/register',name:'register',component:Register}
			]
		})
		new Vue({
			el:'#app',
			router,
			template:`
				<div>
					<router-link to='/login'>去登录</router-link>
					|
					<router-link to='/register'>去注册</router-link>
				
					<router-view></router-view>
				</div>
			`,
			data(){
				return {}
			}
		})
	</script>
</body>
</html>

效果:
在这里插入图片描述
通过js跳转

<!DOCTYPE html>
<html>
<head>
	<title>路由的跳转</title>
</head>
<body>
	<div id="app">
		
	</div>

	<script type="text/javascript" src="vue.js"></script>
	<!-- 引入路由插件 -->
	<script type="text/javascript" src="vue-router.js"></script>
	<script type="text/javascript">

		var Login={
			template:`
				<div>我是登录页面</div>
			`,
		}
		var Register={
			template:`
				<div>我是注册页面</div>
			`,
		}
		var Buy={
			template:`
				<div>我要买东西</div>
			`,
		}
		//安装路由插件
		Vue.use(VueRouter);
		//创建路由对象
		var router= new VueRouter({
			//配置路由对象
			routes:[
				{path:'/login',name:'login',component:Login},
				{path:'/register',name:'register',component:Register},
				{path:'/buy',name:'buy',component:Buy},
			]
		})
		new Vue({
			el:'#app',
			router,
			template:`
				<div>
					<router-link to='/login'>去登录</router-link>
					|
					<router-link to='/register'>去注册</router-link>
					<div>
						<button @click='goregister'>我要去买东西</button>
						<button @click='back'>返回上一页</button>
					</div>
					<router-view></router-view>
				</div>
			`,
			data(){
				return {}
			},
			methods:{
				goregister(){
					//push跟replace是达到同样效果,但是replace是不会向history插入记录
					// this.$router.push({path:'/register'})
					this.$router.replace({path:'/buy'})
					
				},
				back(){
					this.$router.go(-1)
				}
			}
		})
	</script>
</body>
</html>

3.4、路由的传参和取参

简介:详解路由之间的沟通交流

查询参
配置(传参) :to="{name:'login',query:{id:loginid}}"
获取(取参) this.$route.query.id
路由参数

配置(传参) :to="{name:'register',params:{id:registerid} }"
配置路由的规则 { name:'detail',path:'/detail/:id'}
获取 this.$route.params.id

总结:
:to传参的属性里 params是和name配对的 query和name或path都可以
使用路由参数必须要配置路由规则里面配置好参数名,否则刷新页面参数会丢失

代码展示:

<!DOCTYPE html>
<html>
<head>
	<title>路由的跳转</title>
</head>
<body>
	<div id="app">
		
	</div>

	<script type="text/javascript" src="vue.js"></script>
	<!-- 引入路由插件 -->
	<script type="text/javascript" src="vue-router.js"></script>
	<script type="text/javascript">
		var Login={
			template:`
				<div>我是登录页面 
					<span>这是我获取到的参数: {{ msg }}</span>
				</div>
			`,
			data(){
				return { 
					msg:''
				}
			},
			created(){
				this.msg=this.$route.query.id
			}
		}
		var Restiger={
			template:`
				<div>我是注册页面
					<span>这是我获取到的路由参数:{{ foo }}</span>
				</div>
			`,
			props:['foo']
			// data(){
			// 	return {
			// 		restigerfoo:''
			// 	}
			// },
			// created(){
			// 	this.restigerfoo=this.$route.params.foo
			// }
		}
		//安装路由插件
		Vue.use(VueRouter);
		//创建路由对象
		var router= new VueRouter({
			//配置路由对象
			routes:[
				{path:'/login',name:'login',component:Login},
				{path:'/restiger/:foo',name:'restiger',props:true, component:Restiger},
			]
		})
		new Vue({
			el:'#app',
			router,
			template:`
				<div>
					<router-link :to="{name:'login',query:{id:'123'}}">去登录</router-link>
					|
					<router-link :to="{name:'restiger',params:{foo:'bar'}}">去注册</router-link>
					<button @click='jslink'>js跳转去登录</button>
					<router-view :key="$route.fullPath"></router-view>
				</div>
			`,
			data(){
				return {}
			},
			methods:{
				//js跳转传参是一样的
				jslink(){
					this.$router.push({name:'login',query:{id:'456'}})
				}
			}
		})
	</script>
</body>
</html>

3.5、嵌套路由

简介:了解嵌套路由的使用场景和如何实现

补充上一节知识点:js跳转路由传参和标签传参,路由相同而参数不同时页面不做刷新的问题
解决方案:<router-view :key="$route.fullPath"></router-view>

代码思想
1:router-view的细分
router-view第一层中,包含一个router-view
2:每一个坑挖好了,要对应单独的组件
路由配置
routes: [
           {
               path:'/nav',
               name:'nav',
               component:Nav,
               //路由嵌套增加此属性
               children:[
               //在这里配置嵌套的子路由
               ]
           }
       ]
       
案例
进入首页下面会有导航,个人中心、首页、资讯、我的之类的

代码展示:

<!DOCTYPE html>
<html>
<head>
	<title>路由的跳转</title>
</head>
<body>
	<div id="app">
		
	</div>

	<script type="text/javascript" src="vue.js"></script>
	<!-- 引入路由插件 -->
	<script type="text/javascript" src="vue-router.js"></script>
	<script type="text/javascript">
		var Nav={
			template:`
				<div>
					<router-view></router-view>
					<router-link :to="{name:'nav.index'}">首页</router-link>
					|
					<router-link :to="{name:'nav.pensonal'}">个人中心</router-link>
					|
					<router-link :to="{name:'nav.message'}">资讯</router-link>
					|
					<router-link :to="{name:'nav.mine'}">我的</router-link>
				</div>
			`,
		}
		var Index={
			template:`
				<div>首页</div>
			`,
		}
		var Pensonal={
			template:`
				<div>个人中心</div>
			`,
		}
		var Message={
			template:`
				<div>资讯</div>
			`,
		}
		var Mine={
			template:`
				<div>我的</div>
			`,
		}
		//安装路由插件
		Vue.use(VueRouter);
		//创建路由对象
		var router= new VueRouter({
			//配置路由对象
			routes:[
				{
					path:'',
					redirect:'/nav'
				},
				{
					path:'/nav',
					name:'nav',
					component:Nav,
					//嵌套路由增加这个属性
					children:[
						//配置我们的嵌套路由
						{path:'',redirect:'/nav/index'},
						{path:'index',name:'nav.index',component:Index},
						{path:'pensonal',name:'nav.pensonal',component:Pensonal},
						{path:'message',name:'nav.message',component:Message},
						{path:'mine',name:'nav.mine',component:Mine},
					]
				}
			]
		})
		new Vue({
			el:'#app',
			router,
			template:`
				<div>
					<router-view></router-view>
				</div>
			`,
			data(){
				return {}
			},
			methods:{
			}
		})
	</script>
</body>
</html>

3.6、路由守卫

简介:了解路由守卫的作用和如何使用

const router = new VueRouter({ ... }
//前置的钩子函数 最后要执行next()才会跳转
router.beforeEach((to, from, next) => {
  // ...
})
//后置的钩子函数 已经跳转了不需要next
router.afterEach((to, from) => {
  // ...
})
主要是简单介绍一下,路由守卫主要用于检验是否登录了,没登录就跳转到登录页面不让他在其他页面停留,但是现在这种处理主要的都用请求的全局拦截来做了。大致了解一下路由守卫即可

代码展示:

<!DOCTYPE html>
<html>
<head>
	<title>路由守卫</title>
</head>
<body>
	<div id="app">
		
	</div>

	<script type="text/javascript" src="vue.js"></script>
	<!-- 引入路由插件 -->
	<script type="text/javascript" src="vue-router.js"></script>
	<script type="text/javascript">
		var Nav={
			template:`
				<div>
					<router-view></router-view>
					<router-link :to="{name:'nav.index'}">首页</router-link>
					|
					<router-link :to="{name:'nav.pensonal'}">个人中心</router-link>
					|
					<router-link :to="{name:'nav.message'}">资讯</router-link>
					|
					<router-link :to="{name:'nav.mine'}">我的</router-link>
				</div>
			`,
		}
		var Index={
			template:`
				<div>首页</div>
			`,
		}
		var Pensonal={
			template:`
				<div>个人中心</div>
			`,
		}
		var Message={
			template:`
				<div>资讯</div>
			`,
		}
		var Mine={
			template:`
				<div>我的</div>
			`,
		}
		//安装路由插件
		Vue.use(VueRouter);
		//创建路由对象
		var router= new VueRouter({
			//配置路由对象
			routes:[
				{
					path:'',
					redirect:'/nav'
				},
				{
					path:'/nav',
					name:'nav',
					component:Nav,
					//嵌套路由增加这个属性
					children:[
						//配置我们的嵌套路由
						{path:'',redirect:'/nav/index'},
						{path:'index',name:'nav.index',component:Index},
						{path:'pensonal',name:'nav.pensonal',component:Pensonal},
						{path:'message',name:'nav.message',component:Message},
						{path:'mine',name:'nav.mine',component:Mine},
					]
				}
			]
		})
		new Vue({
			el:'#app',
			router,
			template:`
				<div>
					<router-view></router-view>
				</div>
			`,
			data(){
				return {
					loginstate:true
				}
			},
			methods:{
			},
			mounted(){
				//利用路由守卫做当跳转首页时可直接跳转,跳转其他页面要等待两秒才可以跳转
				router.beforeEach((to,from,next)=>{
					console.log(to)
					if(to.path=='/nav/index'){
						next()
					}else{
						setTimeout(function(){
								next()
						},2000)
					}
				})
			}
			
		})
	</script>
</body>
</html>

四、vue-cli快速搭建vue项目

4.1、

在这里插入图片描述

在这里插入图片描述
执行命令

vue init webpack

在这里插入图片描述
yes回车
在这里插入图片描述
在当前目录初始化vue项目,直接回车
在这里插入图片描述
项目描述,直接回车
在这里插入图片描述
作者信息,直接回车
在这里插入图片描述
选择第一个,回车
在这里插入图片描述
安装路由器
在这里插入图片描述
一些语法校验,这里选择no,不安装(语法特别多,校验不对的话就无法运行,所以选择no)
在这里插入图片描述
no:
在这里插入图片描述
no:
在这里插入图片描述
选择第一项,回车
在这里插入图片描述

需要安装几分钟,直到出现下边就是安装结束
在这里插入图片描述
执行如下命令来启动项目

npm  run  dev

在这里插入图片描述
启动成功:
在这里插入图片描述
访问上边的http://localhost:8080
在这里插入图片描述

4.2、配置

配置端口
在这里插入图片描述
安装插件:
在这里插入图片描述
安装完插件后界面就美观了
在这里插入图片描述
该文件有以下三大部分:
在这里插入图片描述
部署:
部署时,先运行npm run build(将项目打包到dis里),然后将dis里的下边这俩文件放tomcat里即可
在这里插入图片描述

发布了46 篇原创文章 · 获赞 12 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_33417321/article/details/90311632