Vue05-自定义指令+生命周期
Vue05-自定义指令+生命周期
1.自定义指令-自定义v-big和v-find指令
<body>
<div id="app">
<!--
1 定义v-big指令,功能和v-text指令类似,但是会将绑定的数字放大10倍。
-->
<p>n值 <span v-text="n"></span></p>
<p>放大10倍的n值 <span v-big="n"></span></p>
<button @click="n++">n++</button>
<!--
1 v-big没有绑定name值,但是name被修改了,big函数也被调用。
2 name被修改,模板被重新解析,big函数也会被调用。
-->
<p>{{name}}</p>
<button @click="name = 'alice'">修改name</button>
<!-- 2 定义v-fbind指令,功能和v-bind类型,但是会使元素获取焦点。 -->
<input type="text" v-fbind01="n">
<input type="text" v-fbind02="n">
</div>
<script>
const vm = new Vue({
el: '#app',
data: {
n: 1,
name: 'tom'
},
// directives用于自定义指令。
directives: {
// 1 自定义的big指令可以是一个函数,函数有两个参数。
// 1 element,element是绑定v-big指令的真实DOM元素。
// 2 binding,binding为绑定指令的信息。
// 2 big函数调用的时机。
// 1 指令和元素绑定成功时调用。
// 2 指令所在模板被重新解析时调用。
big(element, binding) {
console.log(element); // <span></span>
console.dir(element);
console.log(element instanceof HTMLElement); // true
console.log(binding); // {name: 'big', rawName: 'v-big', value: 1, expression: 'n', modifiers: {…}, …}
// binding.value获取指令绑定的值。
element.innerHTML = binding.value * 10;
},
fbind01(element, binding) {
element.value = binding.value;
// fbind01在指令和元素绑定成功时执行,但是此时元素并没有被加载到DOM中,
// 所以给元素设置焦点是无效的。
element.focus();
},
// 自定义指令的第二种写法,自定义指令可以是一个对象。
// 当指令被定义为对象时,对象中可以定义三个方法,这三个方法vue会在指定的时间调用。
fbind02: {
// 指令和元素绑定成功时调用。
bind(element, binding) {
element.value = binding.value;
},
// 指令所在元素被插入页面时调用。
inserted(element, binding) {
// 此时元素已经被插入页面,所以给元素设置焦点是有效的。
element.focus();
},
// 指令所在模板被重新解析时调用。
update(element, binding) {
element.value = binding.value;
}
}
}
});
</script>
</body>
2.自定义指令-获取焦点执行时间的问题
<body>
<button id="btn01">创建输入框</button>
<button id="btn02">创建输入框</button>
<script>
// 当获取焦点的代码在元素未放入DOM中是无效的。
document.getElementById('btn01').onclick = function () {
const input = document.createElement('input');
// 让创建的输入框获取焦点。
input.focus();
// 设置元素value的代码在放入DOM前后都是有效果的。
input.value = 'tom';
document.body.appendChild(input);
};
// 获取焦点的代码在元素放入DOM之后,获取焦点有效果。
document.getElementById('btn02').onclick = function () {
const input = document.createElement('input');
document.body.appendChild(input);
input.value = 'alice';
input.focus();
};
</script>
</body>
3.自定义实例-自定义全局指令和自定义指令总结
<body>
<div id="app">
<!--
自定义指令总结。
1 定义语法。
局部指令。new Vue({directives: {}})
全局指令。Vue.directive(指令名, 配置对象) 或者 Vue.directive(指令名, 回调函数)。
2 当指令为对象时,对象中常用的三个回调。
bind,指令和元素成功绑定时调用。
inserted,指令所在元素被插入页面时调用。
update,指令所在模板结构被重新解析时调用。
3 指令在定义时不需要加v-,但是在使用时需要加v-。
4 指令名如果是多个单词,则需要使用a-b的形式,而不能使用驼峰命名aB的形式。
-->
<!-- 1 当指令的为多个单词时的写法。 -->
<span v-big-number="n"></span>
<!-- 2 所有指令中的this都是window,不管指令是函数形式还是对象形式,自定义指令中的this都是window。 -->
<span v-big="n"></span>
<input type="text" v-fbind="n">
<!-- 3 自定义全局指令。 -->
<p>自定义全局指令</p>
<span v-big01="n"></span>
<input type="text" v-fbind01="n">
</div>
<script>
// 1 定义全局的指令,函数式。
Vue.directive('big01', function (element, binding) {
element.innerHTML = binding.value * 20;
});
// 定义全局的指令,对象式。
Vue.directive('fbind01', {
bind(element, binding) {
console.log('bind', this); // window
element.value = binding.value * 30;
},
inserted(element, binding) {
console.log('inserted', this); // window
element.focus();
},
update(element, binding) {
console.log('update', this); // window
element.value = binding.value;
}
});
const vm = new Vue({
el: '#app',
data: {
n: 1
},
// vue实例中定义的都是局部指令
directives: {
// 当自定义指令为多个单词时,需要使用下划线_连接,所以属性的key要使用原始写法。
'big-number': function (element, binding) {
let n = binding.value;
element.innerHTML = n * 100;
},
big(element, binding) {
console.log('big', this); // window
let n = binding.value;
element.innerHTML = n * 100;
},
fbind: {
bind(element, binding) {
console.log('bind', this); // window
element.value = binding.value;
},
inserted(element, binding) {
console.log('inserted', this); // window
element.focus();
},
update(element, binding) {
console.log('update', this); // window
element.value = binding.value;
}
}
}
})
</script>
</body>
4.生命周期-引出生命周期
<body>
<div id="app">
<!--
1 生命周期又称为生命周期回调函数、生命周期函数、生命周期钩子函数。
2 Vue的生命周期是指Vue在关键时刻调用一些特殊名称的函数。
3 生命周期函数的名称不可更改,但是生命周期函数的内容可以由程序员定义。
4 生命周期函数中的this指向vm或者组件实例对象。
-->
<span :style="{opacity: opacity}">学习vue</span>
<span :style="{opacity: n}">学习vue</span>
</div>
<script>
const vm = new Vue({
el: '#app',
data: {
opacity: 1,
n: 1
},
// Vue完成模板解析并把初始的真实DOM放入页面后调用mounted。
mounted() {
console.log("Vue完成模板解析");
console.log(this); // mounted中的this是Vue实例vm
// 2 vue中定义定时器的方式二,初始化时调用,并且只调用一次。
setInterval(() => {
this.n -= 0.1;
if (this.n <= 0) {
this.n = 1;
}
}, 1000);
}
});
// 1 vue中定义定时器的方式一,在vue实例外部定位,不推荐使用。
setInterval(() => {
vm.opacity -= 0.1;
if (vm.opacity <= 0) {
vm.opacity = 1;
}
}, 1000);
</script>
</body>
5.声明周期-分析生命周期
<body>
<div id="app">
<span>n的当前值{{n}}</span>
<br>
<button @click="add">n+1</button>
<button @click="destroy">销毁</button>
</div>
<div id="root01">
</div>
<script>
const vm = new Vue({
el: '#app',
data: {
n: 1
},
methods: {
add() {
console.log('add');
this.n++;
},
destroy() {
this.$destroy();
}
},
// 初始化流程。
beforeCreate() {
console.log('beforeCreate');
// debugger; // 执行到当前后暂停。
},
created() {
console.log('created');
},
// 挂载流程。
beforeMount() {
console.log('beforeMount');
},
mounted() {
console.log('mounted');
// vm.$el此时是真实的DOM,
console.log(this.$el);
console.log(this.$el instanceof HTMLElement); // true
},
// 更新流程。
beforeUpdate() {
console.log('beforeUpdate');
},
updated() {
console.log('updated');
},
// 销毁流程。
// 销毁会撤销watch中对属性的监视。
beforeDestroy() {
console.log('beforeDestroy');
// beforeDestroy()依然可以进行方法的调用,
// 但是所调用的方法如果会修改页面数据的值,则不会在进行页面数据的更新。
this.add();
},
destroyed() {
console.log('destroyed');
}
});
const vm01 = new Vue({
el: '#root01',
data: {
n: 1
},
// 可以将模板代码定义在template中。
// template中的代码会替换<div id="root01"></div>和其内部的所有代码。
// template中的代码要求只有一个根节点。
// template在组件中使用。
template: `<div>
<span>n的当前值{{n}}</span>
<br>
<button @click="n++">n+1</button>
</div>`
})
</script>
</body>
6.声明周期-总结生命周期
<body>
<div id="app">
<!--
1 Vue声明周期函数。
beforeCreate、created、beforeMount、mounted、
beforeUpdate、updated、beforeDestroy、destroyed。
2 常见的声明周期函数。
1 mounted,可以发送ajax请求、开启定时器、绑定自定义事件、订阅消息。
2 beforeDestroy,可以消除定时器、解绑自定义事件、取消消息订阅。
3 关于销毁Vue实例。
1 销毁后借助Vue开发工具看不到任何信息。
2 销毁后自定义事件会失效,但是原生DOM定义的事件依然有效(通过@click绑定的事件)。
3 一般不会在beforeDestroy中操作数据,因为即使操作了数据,也不会触发数据更新的流程。
-->
<span :style="{opacity: opacity}">学习vue</span>
<button @click="stop">stop</button>
</div>
<script>
const vm = new Vue({
el: '#app',
data: {
opacity: 1,
},
methods: {
stop() {
this.$destroy();
}
},
mounted() {
// 将开启定时器返回的id保存到Vue实例中,方便清除定时器时使用。
this.timer = setInterval(() => {
this.opacity -= 0.1;
if (this.opacity <= 0) {
this.opacity = 1;
}
}, 100);
},
beforeDestroy() {
console.log('销毁之前');
clearInterval(this.timer);
}
});
</script>
</body>
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现