Vue从入门到实战:指令实例

来自CloudWiki
跳转至: 导航搜索

通过指令实现下拉菜单

菜单是导航链接的另一种呈现形式,通常用<a>元素来定义。

在页面编写菜单时,一种方法是将所有的菜单和子菜单项硬编码来实现

另一种方式是把菜单和子菜单按照层级关系定义为一个大的Javascript对象,然后通过脚本动态呈现。

后者定义的对象稍显复杂,但扩展和维护很方便。

数据的定义

data: {
		      menus: [
		      	{
		      		name: '我的淘宝', url: '#', show: false, subMenus: [
		      				{name: '已买到的宝贝', url: '#'},
		      				{name: '已卖出的宝贝', url: '#'}
		      			]
		      	},
		      	{
		      		name: '收藏夹', url: '#', show: false, subMenus: [
		      				{name: '收藏的宝贝', url: '#'},
		      				{name: '收藏的店铺', url: '#'}
		      			]
		      	}
		      ]
		    }

我们为每一个顶级菜单对象定义了一个show属性,初始值为false,该属性主要用于控制其下的子菜单是否显示。

循环输出菜单

接下来使用v-for指令循环输出菜单,采用v-for指令来进行渲染。

如果有多级菜单,可以嵌套使用v-for指令。

<div id = "app" v-cloak>
			<li v-for="menu in menus" @mouseover="menu.show = !menu.show" @mouseout="menu.show = !menu.show">
				<a :href="menu.url" >
					{{menu.name}}
				</a>
				<ul v-show="menu.show">
					<li v-for="subMenu in menu.subMenus">
						<a :href="subMenu.url">{{subMenu.name}}</a>
					</li>
				</ul>
			</li>
		</div>

注意:

  • 在div元素中使用了v-cloak指令来避免页面加载时的闪烁问题,当然,这需要和CSS样式规则[v-cloak]{display:none}一起使用
  • 绑定mouseover和mouseout事件时采用了v-on指令的简写语法
  • 子菜单放在一个
      元素内部,在该元素上使用v-show指令根据表达式menu.show的值来动态控制子菜单的隐藏和显示。

    完整代码

    <!DOCTYPE html>
    <html>
    	<head>
    		<meta charset="UTF-8">
    		<title></title>
    		<style>
    			body {
    				width: 600px;
    			}
    			a {
    				text-decoration: none;
    				display: block;
    				color: #fff;
    				width: 120px;
    				height: 40px;
    				line-height: 40px;
    				border: 1px solid #fff;
    				border-width: 1px 1px 0 0;
    				background: #255f9e;
    			}
    			li {
    				list-style-type: none;
    			}
    			#app > li {
    				list-style-type: none;
    				float: left;
    				text-align: center;
    				position: relative;
    			}
    			#app li a:hover {
    				color: #fff;
    				background: #ffb100;
    			}
    			#app li ul {
    				position: absolute;
    				left: -40px;
    				top: 40px;
    				margin-top: 1px;
    				font-size: 12px;
    			}
    			[v-cloak] {
    				display: none;
    				}
    		</style>
    	</head>
    	<body>
    		<div id = "app" v-cloak>
    			<li v-for="menu in menus" @mouseover="menu.show = !menu.show" @mouseout="menu.show = !menu.show">
    				<a :href="menu.url" >
    					{{menu.name}}
    				</a>
    				<ul v-show="menu.show">
    					<li v-for="subMenu in menu.subMenus">
    						<a :href="subMenu.url">{{subMenu.name}}</a>
    					</li>
    				</ul>
    			</li>
    		</div>
    	
    		<script src="vue.js"></script>
    		<script>
    			var vm = new Vue({
    		    el: '#app',
    		    data: {
    		      menus: [
    		      	{
    		      		name: '我的淘宝', url: '#', show: false, subMenus: [
    		      				{name: '已买到的宝贝', url: '#'},
    		      				{name: '已卖出的宝贝', url: '#'}
    		      			]
    		      	},
    		      	{
    		      		name: '收藏夹', url: '#', show: false, subMenus: [
    		      				{name: '收藏的宝贝', url: '#'},
    		      				{name: '收藏的店铺', url: '#'}
    		      			]
    		      	}
    		      ]
    		    }
    		  });
    		  
    		</script>
    	</body>
    </html>
    

    Vue21020801.png

    使用自定义指令实现随机背景色

    有时候会使用一幅图片作为网页中某个元素的背景图,当网络情况不好时,或者图片本身较大时,图片的加载会比较慢,这种情况下,可以先在该元素的区域用随机的背景色填充,等图片加载完成后,再把元素的背景替换为图片。

    使用自定义指令,可以很方便地实现上述功能。

    <!DOCTYPE html>
    <html>
    	<head>
    		<meta charset="UTF-8">
    		<title></title>
    		
    		<style>
    			div{
    				width: 567px; 
    				height: 567px;
    			}
    		</style>
    	</head>
    	<body>
    		<div id="app">
    			<div v-img="'images/bg.jpg'"></div>
    		</div>
    	
    		<script src="vue.js"></script>
    		
    		<script>
    			Vue.directive('img', {
    				inserted: function(el, binding){
    					let color = Math.floor(Math.random() * 1000000);
    					el.style.backgroundColor = '#' + color;
    					let img = new Image();
    					img.src = binding.value;
    					img.onload = function(){
    						el.style.backgroundImage = 'url(' + img.src  + ')';
    					}
    				}
    			})
    		
    			var vm = new Vue({
    				el: '#app',
    			})
    		</script>
    	</body>
    </html>
    
    注意:自定义指令只应该用于封装对DOM的操作,不要将其作别的用途。