Vue的基础用法(二)

Vue 语法(二)

一、插槽分发

1、slot 插槽

1)子组件插槽

在子组件模板中使用标签定义插槽位置,标签中可以填写内容,当父组件不传
入内容时显示此内容。

<template id="child-template"> 
    <div> 
        <div>我是子组件</div> 
        <div>{{msg}}</div> 
        <!-- 定义 slot 插槽进行占位 --> 
        <slot>我是默认内容,父组件不传入时我显示</slot> 
    </div> 
</template> 
Vue.component('child', { 
    template:'#child-template', 
    props:['msg'] 
}); 

2)父组件分发

在引用<child>子组件时,标签中的内容会放在子组件的<solt>插槽中。 


<div id="app"> 
    <!-- 传入数据 --> 
    <child :msg="msgText"> 
        <!-- 传入模板,混合子模板 --> 
        <h4>父组件模板</h4> 
        <h5>模板混入....</h5> 
    </child> 
</div> 
 
<template id="child-template"> 
    <div> 
        <div>我是子组件</div> 
        <div>{{msg}}</div> 
        <!-- 定义 slot 插槽进行占位 --> 
        <slot>我是默认内容,父组件不传入时我显示</slot> 
    </div> 
</template>
<script> 
    Vue.component('child', { 
        template:'#child-template', 
        props:['msg'] 
    }); 
    var app = new Vue({ 
        el:'#app', 
        data:{ 
            msgText:'父组件数据' 
        } 
    }); 
</script>
2、具名插槽
具名插槽slot, 就是给插槽起个名字。
	在子组件定时可以定定义多个<slot>插槽,同时通过name属性指定一个名字,如:<slot name='header'>,父组件引用时使用< slot='header'>进行插槽选择。


	
	<html>
	<head>
		<meta charset="UTF-8">
		<title>slot插槽</title>
		<script type="text/javascript" src="../js/vue.js" ></script>
	</head>

	<body>
  <div id="app">
		<!--<my-hello></my-hello>-->
		<my-hello>
			<h3 slot="header">你好</h3>
			<p slot="footer">这是p元素</p>
		</my-hello>
	</div>
	
	<!--使用template标签-->
	<template id="tpl1">
		<div>
			<slot name="header">如果没有传递数据,默认显示这段文本</slot>
			<div>--------------------</div>
			<!--插槽,占位-->
			<slot name="footer">如果没有传递数据,默认显示这段文本</slot>
		</div>
	</template>
	
</body>

<script type="text/javascript">
	
	// 自定义组件
	Vue.component("my-hello",{
		template:"#tpl1",
	});
	var app = new Vue({
		el:"#app"
		
	});
</script>
</html>
	
3、slot-scope

作用域插槽 slot-scope, 父组件通过插槽混入父组件的内容, 子组件也可以通过 slot 作用域向插槽 slot 内部传入数据,使用方式:,父组件通过进行引用。



 <body>
    <div id="app">
			<!--<my-hello></my-hello>-->
			<my-hello>
				<template slot-scope="props">
					<h3>你好----{{props.msg}}----{{props.txt}}</h3>
				</template>
			</my-hello>
		</div>
		
		<!--使用template标签-->
		<template id="tpl1">
			<div>
				<div>--------------------</div>
				<!--插槽,占位-->
				<slot msg="你好啊" txt="Hello">如果没有传递数据,默认显示这段文本</slot>
			</div>
		</template>
		
	</body>
	
	<script type="text/javascript">
		
		// 自定义组件
		Vue.component("my-hello",{
			template:"#tpl1",
		});
		
		
		var app = new Vue({
			el:"#app"
			
		});
		
	</script>
	<body>
	<div id="app">
		<!--<my-hello></my-hello>-->
		<my-hello>
			<h3 slot-scope="{msg,txt}">你好----{{msg}}----{{txt}}</h3>
		</my-hello>
	</div>
	
	<!--使用template标签-->
	<template id="tpl1">
		<div>
			<div>--------------------</div>
			<!--插槽,占位-->
			<slot msg="你好啊" txt="Hello">如果没有传递数据,默认显示这段文本</slot>
		</div>
	</template>
	
</body>

<script type="text/javascript">
	
	// 自定义组件
	Vue.component("my-hello",{
		template:"#tpl1",
	});	
var app = new Vue({
		el:"#app"
		
	});
	
</script>

4.动态组件

使用标签的is属性,动态绑定多个组件到一个挂载点,通过改变is绑定值,切换组件。

<body>
<div id="app">
			<!--3、指定导航-->
			/ <a href='#' @click.prevent="page='index'">首页</a>
			/ <a href='#' @click.prevent="page='news'">新闻</a>
			/ <a href='#' @click.prevent="page='login'">登陆</a>
			
			<!--2、使用component引用-->
			<component :is="page"> </component>
		</div>
	</body>
	
	<script type="text/javascript">
		// 1、定义组件
		Vue.component('index', {
		    template:'<h5>首页</h5>'
		});
		Vue.component('news', {
		    template:'<h5>新闻页</h5>'
		});
		Vue.component('login', {
		    template:'<h5>登陆页</h5>'
		});
		
		new Vue({
			el:"#app",
			data:{
	            page:'index'
	        }
		});
	</script>
keep-alive

​ 如果把切换出去的组件保留在内存中,可以保留它的状态或避免重新渲染。为此可以添加一个 keep-alive 指令。

<div id="app">
			<!--3、指定导航-->
			/ <a href='#' @click.prevent="page='index'">首页</a>
			/ <a href='#' @click.prevent="page='news'">新闻</a>
			/ <a href='#' @click.prevent="page='login'">登陆</a>
			
			<!--2、使用component引用-->
			<keep-alive>
		        <component :is="page"></component>
		    </keep-alive>
		</div>
	</body>
	
	<script type="text/javascript">
		// 1、定义组件
		Vue.component('index', {
		    template:'<h5>首页</h5>',
		    // 当组件挂载时,触发(钩子函数)
		    mounted: function () {
		        console.log('挂载...首页');
		    }
		});
		Vue.component('news', {
		    template:'<h5>新闻页</h5>',
		    mounted: function () {
		        console.log('挂载...新闻页');
		    }
		});
		Vue.component('login', {
		    template:'<h5>登陆页</h5>',
		    mounted: function () {
		        console.log('挂载...登陆页');
		    }
		});
		
		new Vue({
			el:"#app",
			data:{
	            page:'index'
	        }
		});
	</script>
refs属性

​ 使用ref 给每个组件起一个固定的名字,方便后续直接引用操作,在父组件中使用$refs访问子组件。

<div id="app">
			<index ref="ind"></index>
		</div>
	</body>
	
	<script type="text/javascript">
		// 1、定义组件
		Vue.component('index', {
		    template:'<div>{{count}}</div>',
		   	data:function(){
		   		return {count:0};
		   	}
		});
		
		
		var app = new Vue({
			el:"#app",
		});
		
		// 通过refs属性得到指定的自定义组件,修改对应的组件中的值
		app.$refs.ind.count=10;
	</script>

二、数据处理

1、watch 属性

在 Vue 组件中,使用 watch 属性来监听数据的变化,同时可以指定监听那个属性。

<body>
		<div id="app">
			{{name}}
		</div>
	</body>
	<script type="text/javascript">
		var app = new Vue({
			el:"#app",
			data:{
				name:"Tony"
			},
			// 监听数据的变化
			watch:{
				name:function(v1,v2) {
					console.log(v1,v2)
				}
			}
		});
	</script>
2. $watch

除了在组件内部使用 watch 也可以使用内部命令$watch 进行属性监听

第一个参数是需要监听的属性,第二个是回调函数用法和watch一样。

需要取消监听只需拿到监听对象的引用,这个引用是返回一个函数对象,执行该对象就可以取消监听。
同时监听多个属性,可以不指定属性

<html>
	<head>
		<meta charset="UTF-8">
		<title>watch属性</title>
		<script type="text/javascript" src="../js/vue.js" ></script>
	</head>
	<body>
		<div id="app">
			{{firstName}} {{lastName}}
		</div>
	</body>
		<script type="text/javascript">
		var app = new Vue({
			el:"#app",
			data:{
				firstName:"Hello",
				lastName:"Kitty"
			}
		});
		// 监听指定属性
		/*app.$watch("firstName",function(newVal,oldVal){
			console.log(newVal,oldVal);
		});*/
		
		// 监听所有属性
		app.$watch(function(){
        	return this.firstName + " " + this.lastName;
    	},function(newVal,oldVal){
			console.log(newVal,oldVal);
		});
	</script>
</html>

3 . computed属性

computed 计算属性用于定义比较复杂的属性计算,比如上边计算 fullName 的时候,
需要使用 watch 两个属性:firstName 和 lastName,比较繁琐,但是使用 computed
就很简单。

<html>
	<head>
		<meta charset="UTF-8">
		<title>computed属性</title>
		<script type="text/javascript" src="../js/vue.js" ></script>
	</head>
	<body>
		<div id="app">
			<p>
		        firstName: 
		        <input type="text" v-model="firstName">
		    </p>
		    <p>
		        lastName: 
		        <input type="text" v-model="lastName"  >
		    </p>
		    <h4>{{fullName}}</h4>
		</div>
	</body>
	<script type="text/javascript">
		var app = new Vue({
			el:"#app",
			data:{
				firstName:"Hello",
				lastName:"Kitty"
			},
			computed:{
				fullName:function(){
					return this.firstName + " " +this.lastName;
				}
			}
		});
		
	</script>
	

computed和methods区别:
计算属性使用computed定义, 方法使用methods定义
计算属性使用时不加括号执行符
计算属性是基于它们的依赖进行缓存的,计算属性只有在它的相关依赖发生改变时才会重新求值。否则返回之前计算好的值,性能更高!

<script type="text/javascript">
		var app = new Vue({
			el:"#app",
			data:{
				firstName:"Hello",
				lastName:"Kitty"
			},
			computed:{
				fullName:function(){
					return this.firstName + " " +this.lastName;
				}
			}
		});
		
	</script>
	<script type="text/javascript">
		var app = new Vue({
			el:"#app",
			data:{
				firstName:"Hello",
				lastName:"Kitty"
			},
			computed:{
				fullName:{
					// getter 得到fullName的值
					get:function(){
						return this.firstName + " " + this.lastName;
					},
					set:function(val){
						var arr = val.split(" ");
						this.firstName = arr[0];
						this.lastName = arr[1];
					}
				}
			}
		});
		
	</script>
4. getter和setter
<script>
var vm = new Vue({
    el:'#root',
    data:{
        name:'Tim'
    },
    created: function () {
        console.log('实例创建...');
    },
    mounted:function () {
        console.log('实例挂载...');
    },
    beforeUpdate:function () {
        console.log('实例将要更新...');
    },
    updated:function () {
        console.log('实例已更新...');
    },
    destroyed:function(){
        console.log('实例卸载...');
    }
});
//改变name
// vm.name = 'Cat';
// vm.$destroy();//卸载
</script>

自定义指令

全局指令
局部指令

使用directive定义,第一个参数为指令名,使用时加上v-前缀才能生效。
inserted属性指当绑定元素插入到DOM时调用。 
<title>自定义指令</title>
	<script type="text/javascript" src="../js/vue.js" ></script>
</head>
<body>
	<div id="root">
		<input type="text" v-focus />
		<input type="text" v-focus2 />
	</div>
</body>
<script>
	
	//自定义全局指令v-focus
	Vue.directive('focus',{
	    //当绑定元素插入到DOM调用
	    inserted: function (el) {
	        //元素获取焦点
	        el.focus();
	    }
	});
		
    var vm = new Vue({
        el:'#root',
	    directives:{
	        focus2:{
	            inserted: function (el) {
	                //元素获取焦点
	                el.focus();
	            }
	        }
	    }
    });
   
</script>

钩子函数的参数有三个:

1)el:当前指令绑定元素
2)binding:当前指令绑定的所有信息对象,有以下属性:

​ name:指令名,不包括 v- 前缀。
​ value:指令的绑定值,例如:v-my-directive=“1 + 1”, value 的值是 2。
​ oldValue:指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。
​ expression:绑定值的字符串形式。例如 v-my-directive=“1 + 1” ,expression 的值是 “1 + 1”。
​ arg:传给指令的参数。例如 v-my-directive:foo,arg 的值是 “foo”。
​ modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar, 修饰符对象 modifiers 的值是 { foo: true, bar: true }。
3)vnode:Vue 编译生成的虚拟节点
4)oldVnode:上一个虚拟节点,仅在 update 和 componentUpdated
​ 钩子中可用。

<html>
	<head>
		<meta charset="UTF-8">
		<title>自定义指令</title>
		<script type="text/javascript" src="../js/vue.js" ></script>
		<style>
		    .item, .item img{
		        width: 200px;
		        height: 120px;
		        float: left;
		    }
		</style>
	</head>
	<body>
		<div id="root">
			<div class="item" v-for="img in imgs" v-img="img.url"></div>
		</div>
	</body>
	
	
	<script>
		
		//定义全局自定义指令v-img
		Vue.directive('img',{
		    bind: function (el,binding) {
		        //生成随机颜色
		        var color = parseInt(Math.random()*0xFFFFFF).toString(16);
		        //设置当前元素的背景,提前进行占位等待图片加载
		        el.style.background = '#'+color;
		        //setTimeout模拟图片加载的延时情况
		        setTimeout(function () {
		            //创建图片对象
		            var img = new Image();
		            //通过binding对象获取真实的图片url
		            img.src = binding.value;
		            //将图片元素插入DOM结构
		            el.appendChild(img);
		            //随机延时
		        },Math.random()*3000+500);
		    }
		});
	
		
	    var vm = new Vue({
	        el:'#root',
	        data:{
		        //定义模拟数据
		        imgs:[
		            {url:'../img/01.jpg'},
		            {url:'../img/02.jpg'},
		            {url:'../img/03.jpg'},
		            {url:'../img/04.jpg'}
		        ]
		    }
	    });
   
</script>
过滤器

​ Vue允许自定义过滤器,可被用作一些常见的文本格式化。
​ 过滤器可以用在两个地方:mustache 插值和 v-bind 表达式 (后者从 2.1.0+ 开始支持)。
​ 过滤器应该被添加在 JavaScript 表达式的尾部,由“管道”符指示。

<div id="app">
{{msg | uppercase | length}}
		<br />
		{{msg | test("<--","--<")}}

	</div>
</body>
<script type="text/javascript">	
// 全局过滤器
	Vue.filter("uppercase",function(val){
		return val.toUpperCase();
	});
var app = new Vue({
		el:"#app",
		data:{
			msg:"hello"
		},
		// 定义局部过滤器
		filters:{
			length:function(val){
				return val + " " + val.length;
			},
			test:function(val,a,b){
				return a + val + b;
			}
		}
	});
	
</script>
	

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值