Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

vue自定义指令 #8

Open
Wscats opened this issue Oct 9, 2016 · 3 comments
Open

vue自定义指令 #8

Wscats opened this issue Oct 9, 2016 · 3 comments

Comments

@Wscats
Copy link
Owner

Wscats commented Oct 9, 2016

全局定义

我们可以用Vue.directive来全局定义一个指令,定义完之后我们就可以在对应html结构前缀v-加上directive名字来激活这个指令

  • bind:只调用一次,在指令第一次绑定到元素上时调用。
  • update: 在 bind 之后立即以初始值为参数第一次调用,之后每当绑定值变化时调用,参数为新值与旧值。
  • unbind:只调用一次,在指令从元素上解绑时调用。
Vue.directive('cclick', {
	//bind就是先帮我们绑定,但不去执行这个test()函数,而updata则是绑定完后执行一次,后面每次更新都去执行一次
	bind: function(value) {
		var self = this;
		//指令的名字,不包含前缀 v-cclick:click="test()"中的cclick
		console.log(this.name)
		//指令的表达式,不包括参数和过滤器 v-cclick:click="test()"中的test()
		console.log(this.expression)
		//指令的参数 v-cclick:click="test()"中的click
		console.log(this.arg)
		this.el.addEventListener(this.arg, function(e) {
			self.expression.substring(0, self.expression.length - 2);
			//把test()转化为test,方便我们后面调用
			//console.log(self.expression.substring(0, self.expression.length - 2));
			//如果v-cclick:click="test",注意test没有加括号的时候我们就可以这样写
			//self.vm[self.expression]()
			self.vm[self.expression.substring(0, self.expression.length - 2)]()
		});
	},
})
var demo = new Vue({
	el: '#demo',
	data: {
		name: 'wsscat'
	},
	methods: {
		test: function() {
			console.log("test test")
		}
	},
})

视图如下

<body id="demo">
	<button v-cclick:click="test()">Ok</button>
</body>

注意这里我们该指令对应的标签受demo构造器控制,我们可以用this.expression获取函数的名字,然后用this.vm来拿到构造器里面的数据进而触发我们想要触发的方法

在这里要注意的是如果把逻辑放在了update里面定义的话test()会首先先自执行一次
当然其实我们直接这样写<button v-cclick:click="test">Ok</button>_test_没有了两个大括号,我们获取这个函数名再去执行就更加方便了,我们就可以直接这样来执行函数了self.vm[self.expression]()

局部定义

我们还可以在构造起里面定义指令,这样就不会担心影响到其他构造器的指令了,只要在加上属性directives就可以对它进行定义了

var demo = new Vue({
	el: '#demo',
	data: {
		msg: 'hello!',
		name: 'wsscat'
	},
	directives: {
		wsscat: {
			bind: function() {
				console.log("wsscat")
			},
			update: function(newValue, oldValue) {
				console.log('new:' + newValue);
				console.log('old:' + oldValue);
				this.el.style.color = 'blue';
				if(newValue == 'red') {
					this.el.style.color = 'red';
				} else if(newValue == 'yellow') {
					this.el.style.color = 'yellow';
				} else {
					this.el.style.color = 'green';
				}
			}
		}
	}
})

视图如下

<input v-model="name" />
<p v-wsscat="name">{{name}}</p>

上面的代码我们把逻辑写在update里面,因为我们这里的name值会一直变化,第一次进来先触发一次update里面的逻辑,后面每一次name的变化都会触发update里面的逻辑,我们这里在输入框对应输入red,yellow都会有颜色的变化,所以这里update符合需求

@Wscats
Copy link
Owner Author

Wscats commented Oct 9, 2016

获取指令所在的标签其他属性值

添加属性params,并接收一个带属性的数组,我们就可以在里面用this.params获取对应的值

directives: {
	wsscat: {
		params: ['a', 'b'],
		bind: function() {
			console.log("wsscat")
		},
		console.log(this.params)
	}
}

视图

<p v-wsscat="name" a="1" b="arr">{{name}}</p>

@Wscats
Copy link
Owner Author

Wscats commented Oct 11, 2016

自定义Touch指令

new Vue({
	el: '#demo',
	data: {
		name: 'wsscat'
	},
	methods: {

	},
	//私有的指令
	directives: {
		touch: {
			params: ['a', 'b'],
			bind: function(value) {
				console.log(this.params)

				function direction() {
					if(Math.abs(xStart - xEnd) >= Math.abs(yStart - yEnd)) {
						if(xStart >= xEnd) {
							console.log("left")
						} else {
							console.log("right")
						}
					} else {
						if(yStart >= yEnd) {
							console.log("up")
						} else {
							console.log("down")
						}
					}
				}
				var xStart, xEnd, yStart, yEnd;
				this.el.addEventListener('touchstart', function(e) {
					//console.log("start:")
					//console.log(e)
					xStart = e.targetTouches[0].pageX;
					yStart = e.targetTouches[0].pageY;
				});
				this.el.addEventListener('touchend', function(e) {
					//console.log("end")
					//console.log(e)
					xEnd = e.changedTouches[0].pageX;
					yEnd = e.changedTouches[0].pageY
					direction(xStart, xEnd, yStart, yEnd)
				})
			}
		}
	}
})

视图

<div id="demo">
        <p class="A1" v-touch='name' :a="name" b="abc">{{name}}</p>
</div>

@jackwanggui
Copy link

123

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants