Vue教程

Vue安装与使用

1.使用cdn

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

2.官网下载
进入英文官网
在这里插入图片描述

  • 第一个为开发版本,包含完整的警告和调试模式
  • 第二个为生产版本,压缩了代码,删除了警告

根据自己的需求下载合适的版本,需要注意的是中文的官网点击下载出现的是源码
在html文件中用script标签直接引入Vue就可使用

Vue起步

Vue基本结构

每个 Vue 应用都需要通过实例化 Vue 来实现

var vm = new Vue()

Vue构造器基本的参数

参数 含义
el 表示当前new的这个vue的实例,即要控制哪个区域
data 用于定义属性,当属性改变时,html的内容也发生改变,不需要手动操作DOM元素
methods 用于定义函数

html代码

<div id="app">
	<p>{{msg}}</p>
	<p>{{show()}}</p>
</div>

js代码

var vm=new Vue({
	el:"#app",
	data:{
		msg:'Hello'
	},
	methods:{
		show:function(){
			return 'World'
		}
	}	
})

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

扫描二维码关注公众号,回复: 8535722 查看本文章

Vue基本指令

{{ }}和v-cloak

{{ }}插值表达式的作用:用于输出对象属性和函数返回值
v-cloak作用:解决插值表达式闪烁的问题,即在为了防止出现Vue的变量名,在DOM染完成后才显示
用法:
html:
html <p v-cloak>{{msg}}</p>
css
css [v-cloak]{ display: none; }

v-text 和 v-html

默认的v-text是没有闪烁的,和插值表达式的不同是v-text会覆盖元素中原本的内容,但是插值表达式只会替换自己的占位符,而不会把整个元素的内容清空

	<p v-text="msg">haha</p>

输出结果:Hello
使用 v-html 指令用于输出 html 代码

v-bind 和 v-on

v-bind用于绑定属性,简写 :
v-on用于绑定方法,简写 @
代码示例

  <div id="app">
  		<input type="text" v-bind:value="val"/>
  		<br/>
  		<span v-on:mouseover="show()">鼠标移到这</span>
  	</div>
  <script>
  	var vm = new Vue({
  		el: "#app",
  		data: {
  			val:"这里绑定了输入框的值"
  		},
  		methods: {
  			show: function() {
  				alert("移到这了!")
  			}
  		}
  	})
  </script>

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

v-model

v-model 指令用来在 input、select、textarea、checkbox、radio 等表单控件元素上创建双向数据绑定,根据表单上的值,自动更新绑定的元素的值。

<div id="app">
  	<p>{{msg}}</p>
  	<input v-model="msg">
</div>
<script>
  	var vm = new Vue({
  		el: "#app",
  		data: {
  			msg: "绑定"
  		}
  	})
  </script>

查看更多示例

Vue绑定样式

例:

.color{
	color: #ffffff;
}
.bkcolor{
	background-color: #ff0000;

.size{
	font-size: 20px;
}

:class为v-bind:class的简写
1.使用数组绑定

<div id="app">
	<h1 :class="['color','bkcolor','size']">这是一个用Vue绑定样式的标题</h1>
</div>
<script>
	var vm = new Vue({
		el: "#app",
		//也可将数组的内容写在data域里
	})
</script>

结果:
在这里插入图片描述
2.数组中使用三元表达式或者镶嵌对象

<div id="app">
	<h1 :class="[flag?'color':'','bkcolor','size']">这是一个用Vue绑定样式的标题1</h1>
	<h1 :class="['color','bkcolor',{'size':flag}]">这是一个用Vue绑定样式的标题2</h1>
</div>
<script>
	var vm = new Vue({
		el: "#app",
		data:{
			flag:false
			//也可将数组内容写在data区域
		}
	})
</script>

在这里插入图片描述
3.使用对象

<div id="app">
	<h1 :class="h_class">这是一个用Vue绑定样式的标题</h1>
</div>
<script>
	var vm = new Vue({
		el: "#app",
		data:{
			h_class:{
				color:true,
				bkcolor:true,
				size:false
			}
		}
	})
</script>

在这里插入图片描述
4.使用:style(v-bind:style)内联样式

Vue循环指令

循环使用 v-for 指令
1.迭代数组

<div id="app">
	<span v-for="item in arr">{{item}}</span>
</div>
<script>
	var vm = new Vue({
		el: "#app",
		data:{
			arr:[1,2,3,4,5]
		}
	})
</script>

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

<div id="app">
	<span v-for="item,i in arr">{{i}}=>{{item}}&nbsp;</span>
</div>
<script>
	var vm = new Vue({
		el: "#app",
		data:{
			arr:[1,2,3,4,5]
		}
	})
</script>

结果:
在这里插入图片描述
2.迭代对象中的属性

<div id="app">
	<span v-for="item in arr">{{item.id}}=>{{item.name}}&nbsp;</span>
</div>
<script>
	var vm = new Vue({
		el: "#app",
		data:{
			arr:[
				{id:1,name:'ls1'},
				{id:2,name:'ls2'},
				{id:2,name:'ls3'}
			]
		}
	})
</script>

在这里插入图片描述

<div id="app">
	<span v-for="item,i in arr">{{i}}=>{{item.id}}=>{{item.name}}&nbsp;</span>
</div>
<script>
	var vm = new Vue({
		el: "#app",
		data:{
			arr:[
				{id:1,name:'ls1'},
				{id:2,name:'ls2'},
				{id:2,name:'ls3'}
			]
		}
	})
</script>

在这里插入图片描述

<div id="app">
	<span v-for="val,key in obj">{{key}}=>{{val}}&nbsp;</span>
	<!--可以有第三个值,索引-->
</div>
<script>
	var vm = new Vue({
		el: "#app",
		data:{
			obj:{
				id:123456,
				name:"zs",
				sex:"M"
			}
		}
	})
</script>

在这里插入图片描述
3.迭代数字

迭代数字从1开始

<div id="app">
	<span v-for="count in 5">{{count}}</span>
</div>
<script>
	var vm = new Vue({
		el: "#app",
		data:{}
	})
</script>

在这里插入图片描述

Vue条件语句

v-if:每次都会重新创建或者删除元素
v-show:不会重新进行对DOM删除或者创建,只是切换了元素的display:none的属性
v-if有更高的切换消耗v-show有更高的初始渲染消耗,因此如果需要频繁切换v-show较好,如果运行条件不大可能改变v-if更好

<div id="app">
	<span v-if="hasinfor">您已登陆</span>
	<!--v-else-if用于多重判断-->
	<span v-else="hasinfor">请登录登陆</span>
	<span v-show="hasinfor">您已登陆</span>
	<span v-show="!hasinfor">请登录登陆</span>
</div>
<script>
	var vm = new Vue({
		el: "#app",
		data:{
			hasinfor:false
		}
	})
</script>

在这里插入图片描述

Vue过滤器

可被用作一些常见文本格式化,可在mustachc插值和v-bind表达式
过滤器调用格式

{{name|过滤器名称}}

全局过滤器的使用

Vue.filter('过滤器名称',function(){})

私有过滤器的使用

filters:{
	过滤器名称:function(){}
}

例子:

<div id="app">
	<p>{{msg|msgFormat}}</p>
</div>
<script>
	Vue.filter('msgFormat',function(msg){
		return msg.replace('邪恶','单纯')
	})
	var vm = new Vue({
		el: "#app",
		data:{
			msg:"他是一个邪恶的男孩"
		}
	})
</script>
/*****私有过滤器的使用方法
var vm = new Vue({
	el: "#app",
	data:{
		msg:"他是一个邪恶的男孩"
	},
	filters:{
		msgFormat:function(msg){
			return msg.replace('邪恶','单纯')
		}
	}
})
*****/

输出:他是一个单纯的男孩

Vue按键修饰符

Vue 允许为 v-on 在监听键盘事件时添加按键修饰符

<!--在输入框绑定回车事件submit-->
<input v-on:keyup.enter="submit">

Vue 提供了绝大多数常用的按键码的别名

  • enter
  • tab
  • delete (捕获“删除”和“退格”键)
  • esc
  • space
  • up
  • down
  • left
  • right

可以通过全局 config.keyCodes 对象自定义按键修饰符别名

// 可以使用v-on:keyup.f1,112为f1的键码
Vue.config.keyCodes.f1 = 112

Vue自定义指令

对普通 DOM 元素进行底层操作,这时候就会用到自定义指令

自定义指令使用方法:

v-指令名称

全局自定义指令的注册

Vue.directive('指令名称',{
	//第二个参数为一个对象,包括不同的钩子函数,常用bind,inserted,update
	bind:function(){},
	inserted:function(){},
	update:function(){}
})

局部自定义指令的注册

directives:{
	指令名称:{
		bind:function(){},
		inserted:function(){},
		update:function(){}
	}	
}

例子:

<div id="app">
	<p v-color>测试文字</p>
</div>
<script>
	Vue.directive('color',{
	bind:function(el){
		el.style.color="red";//el是直接对dom元素进行操作
		}
	})
</script>
/*****私有指令的使用方法
var vm = new Vue({
	el: "#app",	
	data:{},
	directives:{
		color:{
			bind:function(el){
				el.style.color="red";
			}
		}
	}
})
*****/

钩子函数

函数名称 作用
bind 只调用一次,指令第一次绑定到元素时调用
inserted 被绑定元素插入父节点时调用
update 所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前
componentUpdated 指令所在组件的 VNode 及其子 VNode 全部更新后调用
unbind 只调用一次,指令与元素解绑时调用

钩子函数参数- el:指令所绑定的元素,可以用来直接操作 DOM 。

  • binding:一个对象,包含以下属性:
    • name:指令名,不包括 v- 前缀。
    • value:指令的绑定值,例如:v-my-directive=“1 + 1” 中,绑定值为 2。
    • oldValue:指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。
    • expression:字符串形式的指令表达式。例如 v-my-directive=“1 + 1” 中,表达式为 “1 + 1”。
    • arg:传给指令的参数,可选。例如 v-my-directive:foo 中,参数为 “foo”。
    • modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar 中,修饰符对象为 { foo: true, bar: true }。
  • vnode:Vue 编译生成的虚拟节点。
  • oldVnode:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。
<div id="app" v-demo:foo.a.b="message"></div>
<script>
	Vue.directive('demo', {
		bind: function(el, binding){
			el.innerHTML =
				'name: ' + binding.name + '<br>' +
				'value: ' + binding.value + '<br>' +
				'expression: ' + binding.expression + '<br>' +
				'argument: ' + binding.arg + '<br>' +
				'modifiers: ' + JSON.stringify(binding.modifiers) + '<br>' 
			}
	})
	var vm = new Vue({
		el: "#app",
		data: {
			message:"hello"
		},
	})
</script>

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

Vue监听属性

可以通过 watch 来响应数据的变化
格式:

watch:{
		监听的属性:function (newvalue,oldvalue) {}		
}

例子:

<div id="app">
	请输入姓:<input type="text" v-model="fistname" /><br />
	请输入名:<input type="text" v-model="lastname" /><br />
	姓名:<span>{{fullname}}</span>
	<p>{{log}}</p>
</div>
<script>
	var vue = new Vue({
		el: '#app',
		data:{
			fistname:'',
			lastname:'',
			fullname:'',
			log:''
		},
		watch:{
			'fistname':function () {
				this.fullname=this.fistname+this.lastname;
			},
			'lastname':function () {
				this.fullname=this.fistname+this.lastname;
			},
			'fullname':function (newname,oldname) {
				this.log='您的姓名由'+oldname+'改成'+newname;
			},
		}
	})
</script>	

Vue计算属性

计算属性关键词: computed
计算属性的本质就是一个方法,只不过,在使用这些计算属性的时候,是把他们的名称直接当作属性使用,并不会当作方法
可以使用 methods 来替代 computed,但是 computed 是基于它的依赖缓存,只有相关依赖发生改变时才会重新取值。而使用 methods ,在重新渲染的时候,函数总会重新调用执行。使用 computed 性能会更好,但不希望缓存,可以使用 methods 属性

var vue = new Vue({
	el: '#app',
	computed:{
	}
})

Vue生命周期

生命周期钩子=生命周期函数=生命周期事件

图示:

在这里插入图片描述

钩子函数

生命周期钩子 详情 应用
beforeCreate 在实例初始化之后,数据观测(data observer) 和 event/watcher 事件配置之前被调用,不能访问到data以及methods等 初始化非响应式变量
created 实例已经创建完成之后被调用。可访问data以及methods等,未挂载DOM,不能访问$el 简单的ajax请求以及页面的初始化
beforeMount 在挂载开始之前被调用,可访问到$el
mounted 挂载到实例上去之后调用该钩子 常用于获取VNode信息和操作,ajax请求
beforeUpdate 数据更新时调用,发生在虚拟 DOM 重新渲染和打补丁之前 更新之前访问现有的DOM,手动移除已添加的事件监听器
updated 虚拟 DOM 重新渲染和打补丁之后调用 避免在这个钩子函数中操作数据,可能陷入死循环
beforeDestroy 实例销毁之前调用。在这一步,实例仍然完全可用。 常用于销毁定时器、解绑全局事件、销毁插件对象等操作
destroyed Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。

Vue ajax

Vue.js 2.0 版本推荐使用 axios 来完成 ajax 请求
Axios 是一个基于 Promise 的 HTTP 库,可以用在浏览器和 node.js 中

安装方法

1.使用cdn

<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

2.使用npm

$ npm install axios

get方法

示例:

<div id="app"></div>
<script>
	var vue = new Vue({
		el: '#app',
		mounted() {
			axios
				.get(url)//url地址
				.then(function(response){
					console.log(response.data);
				})//.then为请求数据成功后的函数
				.catch(function(error) {
					console.log(error);
				});//.catch为请求数据失败后的函数
		}
	})
</script>	

get传参

1.在url上拼接参数
axios
	.get(url+'?key1=value1&key2=value2')
2.使用params传参
axios
	.get(url,{
		params:{
			key1:value1,
			key2:value2
		}
	})

post方法

<div id="app"></div>
<script>
	var vue = new Vue({
		el: '#app',
		mounted() {
			axios
				.post(url)//url地址
				.then(function(response){
					console.log(response.data);
				})//.then为请求数据成功后的函数
				.catch(function(error) {
					console.log(error);
				});//.catch为请求数据失败后的函数
		}
	})
</script>	

post传参

axios
	.post(url,{
		key1:value1,//第一个参数
		key2:value2//第二个参数
	})

axios API

可以通过向 axios 传递相关配置来创建请求

<script>
	var vue = new Vue({
		el: '#app',
		mounted() {
			axios({
					method: 'get',
					url:url,
					params:{
						key:value
					}
				})//config配置,具体见下文
				.then(function(response){
					console.log(response.data);
				})//.then为请求数据成功后的函数
				.catch(function(error) {
					console.log(error);
				});//.catch为请求数据失败后的函数
		}
	})
</script>	

请求方法别名
在使用别名方法时, url、method、data 这些属性都不必在配置中指定。

axios.request(config)
axios.get(url[, config])
axios.delete(url[, config])
axios.head(url[, config])
axios.post(url[, data[, config]])
axios.put(url[, data[, config]])
axios.patch(url[, data[, config]])

例如:

<div id="app"></div>
<script>
	var vue = new Vue({
		el: '#app',
		mounted() {
			axios
				.get(url,{
					//此处对config里的参数进行配置
					//与请求一起发送的 URL 参数
					params:{
						key=value
					},
					//指定请求超时的毫秒数
					timeout:1000,
				})//url地址
				.then(function(response){
					console.log(response.data);
				})//.then为请求数据成功后的函数
				.catch(function(error) {
					console.log(error);
				});//.catch为请求数据失败后的函数
		}
	})
</script>	

axios响应结构

{
  // `data` 由服务器提供的响应
  data: {},

  // `status`  HTTP 状态码
  status: 200,

  // `statusText` 来自服务器响应的 HTTP 状态信息
  statusText: "OK",

  // `headers` 服务器响应的头
  headers: {},

  // `config` 是为请求提供的配置信息
  config: {}
}

默认配置
1.默认全局配置

axios.defaults.baseURL = 主目录url;

2.自定义的实例默认设置

var instance = axios.create({
		baseURL: 主目录url,
		timeout:1000
	});
	instance
		.get('/下一级目录')
		
//修改
instance.defaults.baseURL = url;

config配置

点击此处

Vue动画

语法格式

<transtion>
	<!--变化的DOM-->
</transtion>

过渡的类名

即用相应类名的css控制变化前后以及变化的时长
在这里插入图片描述

类名 作用
v-enter 定义进入过渡的开始状态。在元素被插入之前生效,在元素被插入之后的下一帧移除
v-enter-active 定义进入过渡生效时的状态。在整个进入过渡的阶段中应用,在元素被插入之前生效,在过渡/动画完成之后移除。这个类可以被用来定义进入过渡的过程时间,延迟和曲线函数
v-enter-to 2.1.8版及以上 定义进入过渡的结束状态。在元素被插入之后下一帧生效 (与此同时 v-enter 被移除),在过渡/动画完成之后移除
v-leave 定义离开过渡的开始状态。在离开过渡被触发时立刻生效,下一帧被移除
v-leave-active 定义离开过渡生效时的状态。在整个离开过渡的阶段中应用,在离开过渡被触发时立刻生效,在过渡/动画完成之后移除。这个类可以被用来定义离开过渡的过程时间,延迟和曲线函数。
v-leave-to 2.1.8版及以上 定义离开过渡的结束状态。在离开过渡被触发之后下一帧生效 (与此同时 v-leave 被删除),在过渡/动画完成之后移除

***如果transition没有指定name属性的值,默认类名为上表的类名,即v-(如v-enter),如果指定了name的值,则类名为:name的值-(如name=“fade”,类名为fade-enter)
例子:
css

/*默认的transition*/
.v-enter,.v-leave-to{
	opacity: 0;
	transform: translateX(100px);
}
.v-enter-active,.v-leave-active{
	transition: all 0.8s linear;
}
/*指定name属性的transition*/
.fade-enter,.fade-leave-to{
	opacity: 0;
	transform: translateY(100px);
}
.fade-enter-active,.fade-leave-active{
	transition: all 1s linear;
}

html

<div id="app">
	<div>
		<input type="button" value="h1变化" @click="flag1=!flag1"/>
		<transition>
			<h1 v-if="flag1">这是一个可以变化的h1</h1>
		</transtion>
	</div>
	<div>
		<input type="button" value="h2变化" @click="flag2=!flag2"/>
		<transition name="fade">
		<h2 v-if="flag2">这是一个可以变化的h2</h2>
		</transition>
	</div>
</div>
<script>
	var vue = new Vue({
		el: '#app',
		data:{
			flag1:false,
			flag2:false
		}
	})
</script>

自定义过渡类名

自定义过渡的类名优先级高于普通的类名,这样就能很好的与第三方(如:animate.css)的动画库结合使用

  • enter-class
  • enter-active-class
  • enter-to-class (2.1.8+)
  • leave-class
  • leave-active-class
  • leave-to-class (2.1.8+)

:duration用于设置过渡动画时间

<transition :duration="800">...</transition>
<transition :duration="{ enter: 600, leave: 1000 }">...</transition>

例如:

<!--前面引入Animate.css动画库-->
<div id="app">
	<input type="button" value="h1变化" @click="show=!show"/>
	<transition 
	enter-active-class="bounceIn"
	leave-active-class="bounceOut"
	:duration="1000"
	>
		<h1 v-if="show">这是一个使用自定义动画的h1</h1>
	</transtion>
</div>
<script>
	var vue = new Vue({
		el: '#app',
		data:{
			show:false,
		}
	})
</script>	

JavaScript 钩子

html

<transition
  v-on:before-enter="beforeEnter"
  v-on:enter="enter"
  v-on:after-enter="afterEnter"
  v-on:enter-cancelled="enterCancelled"
 
  v-on:before-leave="beforeLeave"
  v-on:leave="leave"
  v-on:after-leave="afterLeave"
  v-on:leave-cancelled="leaveCancelled"
>
</transition>
函数 作用
beforeEnter(el) el,表示要执行动画的DOM元素,是个原生的js对象,动画入场之前
function(el, done) 动画开始之后的样子,在这可以设置结束状态,done的起始就是afterEnter,done为afterEnter的引用
afterEnter(el) 动画完成之后调用

**leave函数类似
***在 enter 和 leave 中必须使用 done 进行回调。否则,它们将被同步调用,过渡会立即完成。
***推荐对于仅使用 JavaScript 过渡的元素添加 v-bind:css=“false”,Vue 会跳过 CSS 的检测。这也可以避免过渡过程中 CSS 的影响

小球移动例子:

<div id="app">
	<input type="button" value="jump" @click="show=!show"/>
	<transition 
	@before-enter="beforeEnter"
	@enter="enter"
	@after-enter="afterEnter"
	>
		<div v-if="show" style="width: 20px;height: 20px;border-radius: 50%;background: red;"></div>
	</transtion>
</div>
<script>
	var vue = new Vue({
		el: '#app',
		data:{
			show:false,
		},
		methods:{
			beforeEnter:function(el){
				el.style.transform="translate(0,0)";
			},
			enter:function(el,done){
				el.offsetWidth;
				//可以认为el.offsetWidth会强制动画刷新,不加没动画
				el.style.transform="translate(150px,450px)";
				el.style.transition="all 1s ease";
				done();
			},
			afterEnter:function(el){
				this.show=!this.show;
			}
		}
	})
</script>

列表过渡

1.在实现列表过渡的时候,如果需要过渡的元素是通过v-for循环渲染出来的,则使用transition-group包裹
2.不同于 transition,transition-group会以一个真实元素呈现,默认为span,可以通过 tag 特性更换为其他元素
3.内部元素总是需要提供唯一的 key 属性值

例子:随机在数组位置中插入一个数字以及随机减少一个数字
css

.num{
	margin-right: 10px;
	display: inline-block;
}
.num-enter, .num-leave-to{
	opacity: 0;
	transform: translateY(20px);
}
.num-enter-active, .num-leave-active {
	transition: all 1s linear;
}

html

<div id="app">
	<input type="button" value="Add" @click="add"/>
	<input type="button" value="remove" @click="remove"/>
	<transition-group name="num" tag="div">
		<span class="num" v-for="item in arr" v-bind:key="item">{{item}}</span>
	</transition-group>
</div>
<script>
	var vue = new Vue({
		el: '#app',
		data:{
			arr:[1,2,3,4,5,6,7,8,9],
			nextnum:10//为了使key唯一,让增加的数字每次都不同,在9之后
		},
		methods:{
			add:function(){
				var index=Math.floor(Math.random() * this.arr.length);
				return this.arr.splice(index,0,this.nextnum++);
			},
			remove:function(){
				var index=Math.floor(Math.random() * this.arr.length);
				return this.arr.splice(index,1);
			}
		}
	})
</script>	

上述例子中,添加和移除元素的时候,周围的元素会瞬间移动到他们的新布局的位置,而不是平滑的过渡,为了解决这个问题,则添加下面代码

/*这两个类需要配合使用,才能让其他元素有动画*/
.num-move{
	transition: all 1s linear;
}
.num-leave-active{
	position: absolute;
}

过渡模式

transition的默认行为是进入和离开同时发生,可以通过vue提供的过渡模式让进入和离开分别进行
格式:

<transitio mode="out-in">
</transition>
模式 方式
in-out 新元素先进行过渡,完成之后当前元素过渡离开
out-in 当前元素先进行过渡,完成之后新元素过渡进入

组件过渡

了解组件知识点击此处直接跳转

Vue组件

组件可以扩展 HTML 元素,封装可重用的代码。组件化是从UI的角度进行划分,前端的组件化,方便UI组件的重用

全局组件注册

格式:

Vue.component(tagName, options)

调用组件的方式

<tagName></tagName>

如果为驼峰命名,则采用将大写改小写,两个单词用-分离
例:

<div id="app">
	<com></com>
	<my-com></my-com>
</div>
<script>
	Vue.component('com',{
		template:"<h1>这是由vue创建的第一个全局组件</h1>",
		//通过template属性指定要展示的HTML结构
	})
	Vue.component('myCom',{
		template:"<h1>这是由vue创建的第二个全局组件</h1>",
		//调用采用my-com的标签
	})
	var vue = new Vue({
		el: '#app',
		data:{}
	})
</script>

**需要注意的是,template属性指向的模板内容必须有且只有唯一的根元素

局部组件注册

格式:

components:{
	tagName: options
}

例子

<div id="app">
	<my-com2></my-com2>
</div>
<script>
	var vue = new Vue({
		el: '#app',
		data:{},
		components:{
			myCom2:{
				template:"<h1>这是由vue创建的私有组件</h1>"
			}
		}
	})
</script>	

外部定义

通过template标签可在外面定义的组件结构后调用

<template id="t_com">
	<h1>这是通过template元素在外面定义的组件结构</h1>
</template>
<div id="app">
	<t-com></t-com>
</div>
<script>
	Vue.component('tCom',{
		template:'#t_com'
	})
	var vue = new Vue({
		el: '#app',
		data:{}
	})
</script>	

组件的数据和方法

1.组件可以有自己的数据,但是组件中的数据必须为一个方法
2.在方法的内部,必须返回一个对象
3.调用方式和实例中的data一样
例子:计数器

<template id="counter">
	<div>
		<input type="button" value="+" @click="add"/>
		<p>{{count}}</p>
	</div>
</template>
<div id="app">
	<counter></counter>
</div>
<script>
	Vue.component('counter',{
		template:'#counter',
		data:function(){
			return {
				count:0
			}
		},
		methods:{
			add:function(){
				this.count++
			}
		}
	})
	var vue = new Vue({
		el: '#app',
		data:{},
	})
</script>	

父组件向子组件传值

使用v-bind 动态绑定 props的值到父组件的数据中。每当父组件的数据变化时,该变化也会传导给子组件,props值为只读

<div id="app">
	<com v-bind:parentmsg="msg"></com>
	<!--parentmsg通过props传递到父组件中被调用,传递的值为msg-->
</div>
<script>
	Vue.component('com',{
		template:"<h1>这是子组件and{{parentmsg}}</h1>",
		props:['parentmsg'],
		//只有通过props数组,子组件才可以调用传递过来的值
	})
	var vue = new Vue({
		el: '#app',
		data:{
			msg:"这是父组件的数据"
		}
	})
</script>

子组件向父组件传值

使用 v-on 绑定自定义事件,使用 $emit(eventName) 触发事件

<template id="com">
	<input type="button" value="点击子组件向父组件传值" @click="myclick"/>
</template>
<div id="app">
	<!--通过v-on绑定子组件中触发的函数func,交给父组件中的show方法来处理,参数为子组件传递的参数-->
	<com v-on:func="show"></com>
</div>
<script>
	//添加子组件的点击事件为myclick,通过myclick触发函数,后面跟要传递的值
	Vue.component('com',{
		template:"#com",
		data(){
			return{
				childmsg:"这是子组件的值"
			}
		},
		methods:{
			myclick:function(){
				this.$emit('func',this.childmsg)
			}
		}
	})
	var vue = new Vue({
		el: '#app',
		methods:{
			show:function(data){
				console.log(data)
			}
		}
	})
</script>

组件切换

1.使用v-if/v-else进行显示和隐藏

<div id="app">
	<a href="" @click.prevent="flag=true">登陆</a>
	<a href="" @click.prevent="flag=false">注册</a>
	<!--click.prevent阻止默认事件-->
	<login v-if="flag"></login>
	<register v-else></register>
</div>
<script>
	Vue.component('login',{
		template:"<h3>登陆组件</h3>"
	})
	Vue.component('register',{
		template:"<h3>注册组件</h3>"
	})
	var vue = new Vue({
		el: '#app',
		data:{
			flag:true
		},
	})
</script>

2.使用component来展示对应名称的组件,:is属性可以用来指定展示的组件名称,类型为字符串,所以用’ ’

<div id="app">
	<a href="" @click.prevent="cname='login'">登陆</a>
	<a href="" @click.prevent="cname='register'">注册</a>
	<!--click.prevent阻止默认事件-->
	<component :is="cname"></component>
</div>
<script>
	Vue.component('login',{
		template:"<h3>登陆组件</h3>"
	})
	Vue.component('register',{
		template:"<h3>注册组件</h3>"
	})
	var vue = new Vue({
		el: '#app',
		data:{
			cname:'login'
		},
	})
</script>

组件过渡

多个组件过渡不需要使用key属性
例子:
css

.v-enter,.v-leave-to{
	transform: translateY(20px);
	opacity: 0;
}
.v-enter-active,.v-leave-active{
	transition: all 0.5s linear;
}

html

<div id="app">
	<a href="" @click.prevent="cname='login'">登陆</a>
	<a href="" @click.prevent="cname='register'">注册</a>
	<!--click.prevent阻止默认事件-->
	<transition mode="out-in">
		<component :is="cname"></component>
	</transition>
</div>
<script>
	Vue.component('login',{
		template:"<h3>登陆组件</h3>"
	})
	Vue.component('register',{
		template:"<h3>注册组件</h3>"
	})
	var vue = new Vue({
		el: '#app',
		data:{
			cname:'login'
		},
	})
</script>

Vue路由

前端路由:主要通过URL中的hash(#号)来实现不同页面之间的切换,同时hash有个特点,http请求不包含hash相关的内容。这种通过hash改变来切换页面的方式称为前端路由

安装方法

1.使用cdn

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

2.使用npm

npm install vue-router

基本使用

1.创建一个路由对象,VueRouter

var routerobj=new VueRouter()

2.在路由对象里配置路由规则,routes,每个规则都是一个对象。里面包含两个必须属性
1)path,表示监听哪个路由地址。
2)component,表示路由是前面所匹配到的path,则component对应哪个组件,component必须是一个模板对象,不能是组件引用的名称。

var routerobj=new VueRouter({
	routes:[
		{path:路由地址,component:组件模板对象}
	]
})

3.将路由规则对象注册到vm实例上,用来监听URL地址的变化,然后展示对应组件的变化

var vue = new Vue({
		el: '#app',
		router:routerobj
	})

4.router-view将路由规则匹配到的组件展示到页面

<router-view></router-view>

5.切换方式
1)a标签

<a href="#/路由地址"></a>

注意有#进行hash

2)router-link

<router-link to="/路由地址"></router-link>

例子

<div id="app">
	<router-link to="/login">登陆</router-link>
	<router-link to="/register">注册</router-link>
	<router-view></router-view>
</div>
<script>
	var login={
		template:'<h1>登陆组件</h1>'
	}
	var register={
		template:'<h1>注册组件</h1>'
	}
	//创建一个路由对象
	var routerobj=new VueRouter({
		//配置路由规则
		routes:[
			//component必须是一个模板对象
			{path:'/',redirect:'/login'},//重定向,默认path为/login
			{path:'/login',component:login},
			{path:'/register',component:register}
		]
	})
	var vue = new Vue({
		el: '#app',
		router:routerobj
	})
</script>

点击默认URL和点击登陆时
在这里插入图片描述
点击注册时
在这里插入图片描述
注:可用redirect进行重定向,使默认的URL展示的指定路由地址

router-link设置

1.router-link默认渲染成a标签,如需要渲染成其他标签,则在标签内添加tag属性,指向设置的标签

<router-link to="/路由地址" tag="li"></router-link>

2.设置选中样式
1)默认选中路由标签的类名为router-link-active,只需修改这个类的样式,即可设置选中样式
2)在路由对象中添加linkActiveClass属性,设置对应的类

var routerobj=new VueRouter({
	routes:[],
	linkActiveClass:'myClass'
})

路由传参

1.query方式
不需要修改path属性,传参的格式为在连接地址后加?key=value,调用$router.query.key
2.params方式
在path属性后添加/:key,传参的格式为在连接地址后加/value,调用$router.params.key

<div id="app">
	<router-link to="/login?id=11&name=hhh">登陆</router-link>
	<router-link to="/register/11/hh">注册</router-link>
	<router-view></router-view>
</div>
<script>
	var login={
		template:'<h1>登陆组件<br/>id:{{$route.query.id}}<br/>name:{{$route.query.name}}</h1>'
	}
	var register={
		template:'<h1>注册组件<br/>id:{{$route.params.id}}<br/>name:{{$route.params.name}}</h1>'
	}
	var routerobj=new VueRouter({
		routes:[
			{path:'/login',component:login},
			{path:'/register/:id/:name',component:register}
		]
	})
	var vue = new Vue({
		el: '#app',
		router:routerobj
	})
</script>

路由的嵌套

在路由匹配规则中用children属性即可实现组件的嵌套

<!-- 用户组件acc里面包含登陆注册组件以及相应的显示 -->
<template id="acc">
	<div>
		<h1>这里是用户界面</h1>
		<!-- 包含父组件路径 -->
		<router-link to="/acc/login">登陆</router-link>
		<router-link to="/acc/register">注册</router-link>
		<router-view></router-view>
	</div>
</template>
<div id="app">
	<router-link to="/acc">用户界面</router-link>
	<router-view></router-view>
</div>
<script>
	var login={
		template:'<h1>登陆组件</h1>'
	}
	var register={
		template:'<h1>注册组件</h1>'
	}
	var acc={
		template:'#acc'
	}
	var routerobj=new VueRouter({
		routes:[
			{
				path:'/acc',
				component:acc,
				//不需要/,否则将以根目录开头
				children:[
					{path:'login',component:login},
					{path:'register',component:register}
				]
			}
		]
	})
	var vue = new Vue({
		el: '#app',
		router:routerobj
	})
</script>

在这里插入图片描述

命名视图

为了同级展示多个视图,则使用命名视图,在路由配置中,使用components配置多个路由视图,name属性对应 router-view的name属性对应components配置对象的名字,如果 router-view 没有设置名字,那么默认为 default

<div id="app">
	<router-view></router-view>
	<router-view name='a'></router-view>
	<router-view name='b'></router-view>
</div>
<script>
	var com1={
		template:'<h1>组件1</h1>'
	}
	var com2={
		template:'<h1>组件2</h1>'
	}
	var com3={
		template:'<h1>组件3</h1>'
	}
	var routerobj=new VueRouter({
		routes:[
			{
				path:'/',
				components:{
					default:com1,
					a:com2,
					b:com3
				}
			}
		]
	})
	var vue = new Vue({
		el: '#app',
		router:routerobj
	})
</script>	
发布了20 篇原创文章 · 获赞 25 · 访问量 7461

猜你喜欢

转载自blog.csdn.net/qq_41866776/article/details/98476042