2、自定义vue指令
使用ref获焦点
可以通过 ref 获得 DOM ,然后操作 DOM 实现获取焦点
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>hello vue</title>
<!-- 引入Vue库 -->
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="root"></div>
</body>
<script>
const app = Vue.createApp({
mounted(){
this.$refs.input.focus();
},
template: `
<div>
<input ref="input" />
</div>
`
});
const vm = app.mount('#root');
</script>
</html>
复制代码
运行结果
使用ref也能实现,但无法复用!
自定义指令实现获取焦点
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>hello vue</title>
<!-- 引入Vue库 -->
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="root"></div>
</body>
<script>
const app = Vue.createApp({
// 使用 v-focus
template: `
<div>
<input v-focus />
</div>
`
});
// 自定义指令
app.directive("focus",{
// 时间:2021年06月15日 16时39分43秒
// 这里接收一个参数,参数就是 DOM 节点
mounted(el){
el.focus();
}
});
const vm = app.mount('#root');
</script>
</html>
复制代码
运行结果
局部自定义指令
类似组件、mixin,上面是全局自定义指令,我们来写一个局部自定义指令(写法有差异)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>hello vue</title>
<!-- 引入Vue库 -->
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="root"></div>
</body>
<script>
// 局部自定义指令
const directives = {
focus: {
mounted(el){
el.focus();
}
}
}
const app = Vue.createApp({
// 引入自定义指令
// 理论写法
// directives: directives,
// 解构写法(简化)
directives,
// 使用 v-focus
template: `
<div>
<input v-focus />
</div>
`
});
const vm = app.mount('#root');
</script>
</html>
复制代码
运行结果
说明
我们上面使用了生命周期函数 mounted ,实际上其他的生命周期函数也可以使用在自定义指令里面!
带属性值的自定义指令
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>hello vue</title>
<!-- 引入Vue库 -->
<script src="https://unpkg.com/vue@next"></script>
<!-- 样式 -->
<style>
.header{
position: absolute;
}
</style>
</head>
<body>
<div id="root"></div>
</body>
<script>
// 局部自定义指令
const directives = {
pos: {
mounted(el, binding){
el.style.top = binding.value + 'px';
}
}
}
const app = Vue.createApp({
// 引入自定义指令
directives,
// 使用 v-pos
template: `
<div v-pos='50' class="header">
<input />
</div>
`
});
const vm = app.mount('#root');
</script>
</html>
复制代码
运行结果
修改数据并使数据生效
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>hello vue</title>
<!-- 引入Vue库 -->
<script src="https://unpkg.com/vue@next"></script>
<!-- 样式 -->
<style>
.header{
position: absolute;
}
</style>
</head>
<body>
<div id="root"></div>
</body>
<script>
// 局部自定义指令
const directives = {
pos: {
// mounted只会执行一次,因此 data 里面的 top 改变不会反映到页面上
mounted(el, binding){
el.style.top = binding.value + 'px';
},
// 我们写一个 updated 生命周期函数
updated(el, binding){
el.style.top = binding.value + 'px';
}
}
}
const app = Vue.createApp({
// 引入自定义指令
directives,
// 使用数据代替 50
data(){
return {
top: 60
}
},
// 使用 v-pos
template: `
<div v-pos='top' class="header">
<input />
</div>
`
});
const vm = app.mount('#root');
</script>
</html>
复制代码
运行结果
简写
// 下面写法1等价于写法2,只要这两种等价,再加生命周期函数就不等价了
// 写法1
app.directive("focus", (el, binding) => {
el.style.top = binding.value + 'px';
});
// 写法2
app.directive("focus",{
mounted(el, binding){
el.style.top = binding.value + 'px';
},
updated(el, binding){
el.style.top = binding.value + 'px';
}
});
复制代码
自定义指令的属性
类似 v-ops:abc,abc即是属性,下面我们来看看如何获取这个abc
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>hello vue</title>
<!-- 引入Vue库 -->
<script src="https://unpkg.com/vue@next"></script>
<!-- 样式 -->
<style>
.header{
position: absolute;
}
</style>
</head>
<body>
<div id="root"></div>
</body>
<script>
// 局部自定义指令
const directives = {
pos: {
mounted(el, binding){
console.log(binding);
console.log(binding.arg);
el.style.top = binding.value + 'px';
},
}
}
const app = Vue.createApp({
// 引入自定义指令
directives,
// 使用数据代替 50
data(){
return {
top: 60
}
},
// 使用 v-pos
template: `
<div v-pos:abc='top' class="header">
<input />
</div>
`
});
const vm = app.mount('#root');
</script>
</html>
复制代码
运行结果
优化上面的距离设置
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>hello vue</title>
<!-- 引入Vue库 -->
<script src="https://unpkg.com/vue@next"></script>
<!-- 样式 -->
<style>
.header{
position: absolute;
}
</style>
</head>
<body>
<div id="root"></div>
</body>
<script>
// 局部自定义指令
const directives = {
pos: {
mounted(el, binding){
el.style[binding.arg] = binding.value + 'px';
},
}
}
const app = Vue.createApp({
// 引入自定义指令
directives,
// 使用数据代替 50
data(){
return {
top: 60
}
},
// 使用 v-pos
template: `
<div v-pos:left='top' class="header">
<input />
</div>
`
});
const vm = app.mount('#root');
</script>
</html>
复制代码
运行结果
我们把left改成right等,也能够实现同样的效果!
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END