Custom instruction
Introduction to the
In addition to the default built-in directives (such as V-model and V-show), Vue also allows you to register custom directives.
For example, when the page loads, the input element gets focus.
By registering global directives
<body>
<div id="app">
<input type="text" v-focus />
</div>
<script src="https://unpkg.com/vue@next"></script>
<script>
const { createApp, directive } = Vue;
const Root = {};
const app = createApp(Root);
// Register the global directive
app.directive("focus", {
mounted(el) {
// executes when the bound element is mounted into the DOM
// el represents the element to which the directive is boundel.focus(); }}); app.mount("#app");
</script>
</body>
Copy the code
This is done by registering local directives
<body>
<div id="app">
<! -- v-focus is a local directive, can only be used in my-Component components, otherwise error -->
<! -- <input type="text" v-focus /> -->
<my-component></my-component>
</div>
<script src="https://unpkg.com/vue@next"></script>
<script>
const { createApp, directive } = Vue;
const Root = {};
const app = createApp(Root);
app.component("my-component", {
template: `<div><input type="text" v-focus /></div>`.directives: {
focus: {
mounted(el){ el.focus(); }},}}); app.mount("#app");
</script>
</body>
Copy the code
Hook function
Hook function | Execution time |
---|---|
created | Called before the attribute or event listener of the bound element is applied. |
beforeMount | Called before the element of the bound directive is mounted into the DOM |
mounted | Called after the element of the bound directive is mounted into the DOM |
beforeUpdate | Called before the component in which the element of the bound directive is updated |
updated | Called after the component of the element to which the directive is bound is updated |
beforeUnmount | Called before the component in which the element of the bound directive is unloaded |
unmounted | Called after the component in which the element of the bound directive is unloaded |
<body>
<div id="app">
<my-component v-if="isShow"></my-component>
<button @click="rootClick">switch</button>
</div>
<script src="https://unpkg.com/vue@next"></script>
<script>
const { createApp, directive, ref } = Vue;
const Root = {
setup() {
const isShow = ref(true);
const rootClick = function () { isShow.value = ! isShow.value }return{ isShow, rootClick }; }};const app = createApp(Root);
app.directive("test", {
created() {
console.log("created...");
},
beforeMount() {
console.log("beforeMount...");
},
mounted() {
console.log("mounted...");
},
beforeUpdate() {
console.log("beforeUpdate...");
},
updated() {
console.log("updated...");
},
beforeUnmount() {
console.log("beforeUnmount...");
},
unmounted() {
console.log("unmounted"); }}); app.component("my-component", {
name: "my-component".template: `
my-component
{{ count }}
`.setup() {
const count = ref("100");
const myClick = function () {
count.value++;
};
return{ count, myClick, }; }}); app.mount("#app");
</script>
</body>
Copy the code
Dynamic instruction parameter
The parameters and binding values of instructions can be dynamic.
<body>
<div id="app">
<div
style="width: 50px; height: 50px; background: pink"
v-padding:[direction] ="distance"
></div>
<div>
<button @click="rootClick">{{ direction }}</button>
</div>
<div>
<input type="range" min="0" max="50" v-model="distance" />{{ distance }}
</div>
</div>
<script src="https://unpkg.com/vue@next"></script>
<script>
const { createApp, directive, ref } = Vue;
const Root = {
setup() {
const direction = ref("Start");
const distance = ref("0");
const arr = [
"border-top"."border-right"."border-bottom"."border-left",];let index = 0;
const rootClick = function () {
index > 3 ? (index = 0) : "";
direction.value = arr[index++];
};
return{ direction, distance, rootClick, }; }};const app = createApp(Root);
app.directive("padding", {
updated(el, binding) {
el.style.border = "unset";
el.style[binding.arg] = binding.value + "px" + " solid orange"; }}); app.mount("#app");
</script>
</body>
Copy the code
Function shorthand
If you want to trigger the same behavior when Mounted and updated, regardless of the other hook functions. You can pass in a function at the second argument.
<body>
<div id="app">
<input type="text" v-focus />
{{counter }}
<button @click="myClick">update</button>
</div>
<script src="https://unpkg.com/vue@next"></script>
<script>
const { createApp, directive, ref } = Vue;
const Root = {
setup() {
const counter = ref('0')
const myClick = function () {
counter.value++
}
return {
counter,
myClick
}
},
};
const app = createApp(Root);
app.directive("focus".(el, binding) = > {
console.log("Executed...");
});
app.mount("#app");
</script>
</body>
Copy the code
Object literals
If an instruction requires more than one value, you can pass in a JS object literal.
<body>
<div id="app">
<input type="text" v-user="{ name: 'cezlz', age: 18 }" />
</div>
<script src="https://unpkg.com/vue@next"></script>
<script>
const { createApp, directive, ref } = Vue;
const Root = {};
const app = createApp(Root);
app.directive("user".(el, binding) = > {
console.log(binding.value);
});
app.mount("#app");
</script>
</body>
Copy the code
Used in components
When used in a component, custom directives are always applied to the root node of the component.
<body>
<div id="app">
<my-component v-test></my-component>
</div>
<script src="https://unpkg.com/vue@next"></script>
<script>
const { createApp, directive } = Vue;
const Root = {};
const app = createApp(Root);
app.directive("test".(el, binding) = > {
console.log(el.id)
});
app.component("my-component", {
name: "my-component".template: `
my-component
`}); app.mount("#app");
</script>
</body>
Copy the code
The result is box1 printed, indicating that the custom directive is applied to the root node.
If the component has more than one root node, the custom directive is ignored and a warning is thrown.
<body>
<div id="app">
<my-component v-test></my-component>
</div>
<script src="https://unpkg.com/vue@next"></script>
<script>
const { createApp, directive } = Vue;
const Root = {};
const app = createApp(Root);
app.directive("test".(el, binding) = > {
console.log(el.id)
});
app.component("my-component", {
name: "my-component".template: `
my-component
my-component
`}); app.mount("#app");
</script>
</body>
Copy the code
Box1 is now not printed, indicating that the custom instruction has been ignored.