Vue(day02-05~14: 自定义指令、钩子函数、计算属性和侦听器、过滤器、生命周期)

自定义指令

除了核心功能默认内置的指令 (v-model 和 v-show),Vue 也允许注册自定义指令。
有的情况下,你仍然需要对普通 DOM 元素进行底层操作,这时候就会用到自定义指令。举个聚焦输入框的例子,如下:

// 注册一个全局自定义指令 `v-focus`
Vue.directive('focus', {
  // 当被绑定的元素插入到 DOM 中时……
  inserted: function (el) {
    // 聚焦元素
    el.focus()
  }
})

如果想注册局部指令,组件中也接受一个 directives 的选项:

directives: {
  focus: {
    // 指令的定义
    inserted: function (el) {
      el.focus()
    }
  }
}

然后你可以在模板中任何元素上使用新的 v-focus 属性,如下:

<input v-focus>

练习代码:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
	</head>
	<body>
		<div id="app">
			<!--自定义指令用法-->
			<input type="text" v-focus/>
			<input type="text" v-color='msg'/>
		</div>
		<script type="text/javascript" src="js/vue.min.js" ></script>
		<script type="text/javascript">
			/*
			 * 自定义指令
			 */
			//全局指令:使用范围
			//inserted钩子函数
			Vue.directive('focus',{
				inserted: function(el){
					//获取元素焦点
					el.focus();
				}
			});
//			Vue.directive('color',{
//				bind: function(el,binding){
//					//根据指令的参数设置背景色 
//					//console.log(binding.value.color);
//					el.style.backgroundColor = binding.value.color;
//				}
//			});
			var vm = new Vue({
				el: '#app',
				data: {
					msg: {
						color: 'red'
					}
				},
				methods:{
					
				},
				//局部指令:只能在本组件使用
				directives: {
					color: {
						bind: function(el,binding){
					       el.style.backgroundColor = binding.value.color;
				        }
					}
				}
			});
		</script>
	</body>
</html>

钩子函数

参考Vue官网链接
一个指令定义对象可以提供如下几个钩子函数 (均为可选):

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 编译生成的虚拟节点。移步 VNode API 来了解更多详情。
oldVnode:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。

注意:除了 el 之外,其它参数都应该是只读的,切勿进行修改。如果需要在钩子之间共享数据,建议通过元素的 dataset 来进行。

参考资料Vue官网:计算属性和侦听器

计算属性

computed:{}

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
	</head>
	<body>
		<div id="app">
			<!--表达式的计算逻辑可能会比较复杂,使用计算属性可以是模板内容更加简洁-->
			<div>{{msg}}</div>
			<div>{{reverseString}}</div>
		</div>
		<script type="text/javascript" src="js/vue.min.js" ></script>
		<script type="text/javascript">
			var vm = new Vue({
				el: '#app',
				data: {
					msg: 'Hello'
				},
				//计算属性与方法的区别:计算属性是基于它们的依赖(依赖于data里面的值)进行缓存的;方法不存在缓存
				//计算属性
				computed: {
					reverseString: function(){
						return this.msg.split('').reverse().join('');
					}
				}
			})
		</script>
	</body>
</html>

侦听器

watch:{}

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
	</head>
	<body>
		<div id="app">
			<div>
				<span>名:</span>
				<span>
					<input type="text" v-model="firstName" />
				</span>
			</div>
			<div>
				<span>姓:</span>
				<span>
					<input type="text" v-model="lastName" />
				</span>
			</div>
			<div>{{fullName}}</div>
		</div>
		
		<script type="text/javascript" src="js/vue.min.js" ></script>
		<script type="text/javascript">
			var vm = new Vue({
				el: '#app',
				data: {
					firstName: 'Jim',
					lastName: 'Green',
					fullName: 'Jim Green'
				},
				//侦听器:数据变化时执行异步或开销较大的操作
				watch: {
					firstName: function(val){
						this.fullName = val + ' ' +this.lastName; 
					},
					lastName: function(val){
						this.fullName = this.firstName + ' ' + val; 
					}
				},
				//31,34-41去掉
//				computed: {
//					fullName: function(){
//						return this.firstName + " " + this.lastName;
//					}
//				}
			})
		</script>
	</body>
</html>

侦听器应用:验证用户名是否可用

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
	</head>
	<body>
		<!--验证用户名是否可用-->
		<div id="app">
			<div>
				<span>用户名:</span>
				<span>
					<input type="text" v-model.lazy="uname"/>
				</span>
				<span>{{tip}}</span>
			</div>
		</div>
		
		<script type="text/javascript" src="js/vue.min.js" ></script>
		<script type="text/javascript">
			/*
			 * 1.采用侦听器监听用户名变化
			 * 2.调用后台接口进行验证
			 * 3.根据验证的结果调整提示信息
			 */
			var vm = new Vue({
				el: '#app',
				data: {
					uname: '',
					tip: ''
				},
				methods: {
					checkName: function(uname){
						var that = this;
						//调用接口,但是可以使用定时任务的方式模拟接口调用
						setTimeout(function(){
							//模拟接口调用
							if(uname == 'admit'){
								that.tip = '用户名已经存在,请更换一个';
							}else{
								that.tip = '用户名可以使用';
							}
						},2000)
					}
				},
				watch: {
					uname: function(val){
						//调用后台接口验证用户名的合法性
						this.checkName(val);
						//修改提示信息
						this.tip = '正在验证...';
					}
				}
			})
		</script>
	</body>
</html>

Vue官网:过滤器

过滤器

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
	</head>
	<body>
		<!--过滤器:格式化数据-->
		<div id="app">
			<input type="text" v-model="msg"/>
			<div>{{msg | upper}}</div>
			<div>{{msg | upper | lower}}</div>
			<div :asd='msg | upper'>测试</div>
		</div>
		
		<script type="text/javascript" src="js/vue.min.js" ></script>
		<script type="text/javascript">
			/*
			 * 过滤器
			 */
//			Vue.filter('upper',function(val){
//				return val.charAt(0).toUpperCase() + val.slice(1);
//			});
			Vue.filter('lower',function(val){
				return val.charAt(0).toLowerCase() + val.slice(1);
			});
			var vm = new Vue({
				el: '#app',
				data: {
					msg: ''
				},
				//局部绑定
				filters: {
					upper: function(val){
						return val.charAt(0).toUpperCase() + val.slice(1);
					}
				}
			});
		</script>
	</body>
</html>

过滤器应用:格式化日期

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
	</head>
	<body>
		<div id="app">
			<div>{{date | format('yyyy-MM-dd')}}</div>
		</div>
		
		<script type="text/javascript" src="js/vue.min.js" ></script>
		<script type="text/javascript">
			/*
			 * 过滤器格式化日期
			 */
			//filter参数
			Vue.filter('format',function(value,arg){
				//console.log(value);
				//console.log(arg);
				if(arg == 'yyyy-MM-dd'){
					//13视频有补充
					var ret = '';
					ret += value. getFullYear() + '-' +(value.getMonth()+1) + '-' + value.getDate();
					return ret;
				}
				return value;
			});
			var vm = new Vue({
				el: '#app',
				data: {
					date: new Date()
				},
				methods: {
					
				}
			});
		</script>
	</body>
</html>

生命周期

生命周期
测试代码(关注:mounted)

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
	</head>
	<body>
		<div id="app">
			<div>{{msg}}</div>
			<button @click="change">更新</button>
			<button @click="destory">销毁</button>
		</div>
		
		<script type="text/javascript" src="js/vue.min.js" ></script>
		<script type="text/javascript">
			/*
			 * 生命周期钩子
			 * 挂载(mounted)、更新、销毁
			 */
			var vm = new Vue({
				el: '#app',
				data: {
					msg: '生命周期'
				},
				methods: {
					change: function(){
						this.msg = '123456'
					},
					destory: function(){
						this.$destroy();
					}
				},
				beforeCreate: function(){
					console.log('beforeCreate');
				},
				created: function(){
					console.log('created');
				},
				beforeMount: function(){
					console.log('beforeMount');
				},
				mounted: function(){
					console.log('mounted');
				},
				beforeUpdate: function(){
					console.log('beforeUpdate');
				},
				updated: function(){
					console.log('updated');
				},
				beforeDestroy: function(){
					console.log('beforeDestroy');
				},
				destroyed: function(){
					console.log('destroyed');
				}
			});
		</script>
	</body>
</html>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值