vuejs自定义指令(Vue 内置指令以及自定义指令)
1. 内置指令
v-show :
说明:根据条件展示元素,true展示元素 ,false隐藏元素 <template> <div> <button v-show="isShow"></button> </div> </template> <script> export default { name: HomeView, data() { return { isShow: false }; } }; </script>注意:v-show 不支持写在 template 元素标签上 ,也不支持同时写在 v-else 标签中
v-show 是采用切换css属性display:block,display:none来控制显示或隐藏dom ,所以初始页面render时 ,此dom就会渲染至页面中 ,只不过是隐藏状态 。
v-if:
说明:根据条件展示元素,true在dom树中渲染元素 ,false从dom树中移除元素 <template> <div> <button v-if="isShow"></button> </div> </template> <script> export default { name: HomeView, data() { return { isShow: false }; } }; </script>v-if可以作用于template中 ,如果表达式为true ,那么template标签块中的代码都会渲染 ,反之都不渲染
v-if也是惰性的:如果在初始渲染时条件为假 ,则什么也不做——直到条件第一次变为真时 ,才会开始渲染条件块
v-else
说明:表示 v-if 的“else 块 ” <template> <div> <button v-if="isShow">按钮1</button> <button v-else>按钮2</button> </div> </template> <script> export default { name: HomeView, data() { return { isShow: false }; } }; </script>v-else元素必须紧跟在带v-if或者v-else-if的元素的后面 ,否则它将不会被识别
v-else-if
说明:表示 v-if 的“else 块 ” <template> <div> <button v-if="type === a">按钮a</button> <button v-else-if="type === b">按钮b</button> <button v-else-if="type === c">按钮c</button> <button v-else="type === d">按钮d</button> </div> </template> <script> export default { name: HomeView, data() { return { type: a }; } }; </script>类似于 v-else,v-else-if 也必须紧跟在带 v-if 或者 v-else-if 的元素之后 。
v-bind
说明:动态地绑定一个或多个 attribute ,或一个组件 prop 到表达式 缩写::a. 绑定一个 attribute
<template> <div> <img v-bind:src="https://www.cnblogs.com/jwyblogs/p/imgSrc" /> <img :src="https://www.cnblogs.com/jwyblogs/p/imgSrc" /> </div> </template> <script> export default { name: HomeView, data() { return { imgSrc: https://picsum.photos/200/300/?random }; } }; </script>b. class 绑定
<template> <div> <div :class="{ red: isRed }"></div> <div :class="[classA, classB]"></div> <div :class="[classA, { classB: isB, classC: isC }]"></div> </div> </template> <script> export default { name: HomeView, data() { return { isRed: true, classA: classA, classB: classB, isB: true, isC: true }; } }; </script>c. style 绑定
<template> <div> <div :style="{ fontSize: size + px }"></div> <div :style="[styleObjectA, styleObjectB]"></div> </div> </template> <script> export default { name: HomeView, data() { return { size: 20, styleObjectA: { color: red, fontSize: 20px }, styleObjectB: { color: blue, fontSize: 30px } }; } }; </script>d. 组件传值
<template> <div> <child-component :title="text" /> </div> </template> <script> export default { name: HomeView, components: { child-component: { props: { title: String }, template: <div>{{ title }}</div> } }, data() { return { text: test }; } }; </script>e. 传递当前所有 props
<template> <div> <child-component v-bind="$props" /> </div> </template> <script> export default { name: HomeView, components: { child-component: { props: { title: String }, template: <div>{{ title }}</div> } }, props: { propsValue: String }, data() { return { text: test }; } }; </script>v-text
说明:更新元素的 textContent <template> <div> <span v-text="text"></span> <!-- 和下面的一样 --> <span>{{ text }}</span> </div> </template> <script> export default { name: HomeView, data() { return { text: test }; } }; </script>v-html
说明:更新元素的 innerHTML 版本:vue2,vue3 <template> <div> <p v-html="innerHTML"></p> </div> </template> <script> export default { name: HomeView, data() { return { innerHTML: <button>click</button> }; } }; </script>页面展示:
v-for
说明:遍历数据 <template> <div class="container"> <ul> <li v-for="(item, index) in list" :key="item.name">{{ item.name }}{{ index }}</li> </ul> <ol> <li v-for="(item, index) of list" :key="item.version">{{ item.version }}{{ index }}</li> </ol> </div> </template> <script> export default { name: HomeView, data() { return { list: [ { name: vue, version: 2 }, { name: react, version: 17 } ] }; } }; </script>注意:请不要将 v-for 与 v-if 一起使用 ,当和 v-if 一起使用时,v-for 的优先级比 v-if 更高 ,v-for 可以与 v-show 一起使用 ,如果需要带条件渲染 ,请考虑使用 computed 属性
最佳建议 ,在使用 v-for 时 ,使用 key 属性 ,来保证内部 diff 算法更新 dom 时最佳优化 ,不推荐使用 index 属性页面展示:
v-model
说明:在表单控件或者组件上创建双向绑定 <template> <div class="container"> <p> <span>input-</span> <span>v-model:</span> <span>{{ inputVal }}</span> <input type="text" v-model="inputVal" /> </p> <p> <span>textarea-</span> <span>v-model:</span> <span>{{ textareaVal }}</span> <textarea type="text" v-model="textareaVal"></textarea> </p> </div> </template> <script> export default { name: HomeView, data() { return { inputVal: , textareaVal: }; } }; </script>页面展示:
2. 自定义指令
注册全局指令 import Vue from vue; Vue.directive(directiveName, { bind(el, binding, vnode, oldVnode) {}, inserted(el, binding, vnode, oldVnode) {}, update(el, binding, vnode, oldVnode) {}, componentUpdated(el, binding, vnode, oldVnode) {}, unbind(el, binding, vnode, oldVnode) {} }); <template> <div class="container" v-directiveName></div> </template> 局部注册指令 <template> <input class="container" v-focus /> </template> <script> export default { name: HomeView, directives: { focus: { bind(el, binding, vnode, oldVnode) {}, inserted(el, binding, vnode, oldVnode) {}, update(el, binding, vnode, oldVnode) {}, componentUpdated(el, binding, vnode, oldVnode) {}, unbind(el, binding, vnode, oldVnode) {} } } }; </script>钩子函数
bind : 只调用一次 ,指令第一次绑定到元素时调用 。在这里可以进行一次性的初始化设置 。 inserted : 被绑定元素插入父节点时调用 (仅保证父节点存在 ,但不一定已被插入文档中) 。 update : 所在组件的 VNode 更新时调用 ,但是可能发生在其子 VNode 更新之前 。指令的值可能发生了改变 ,也可能没有 componentUpdated : 指令所在组件的 VNode 及其子 VNode 全部更新后调用 。 unbind : 只调用一次 ,指令与元素解绑时调用 。钩子函数参数
el : 指令所绑定的元素,可以用来直接操作 DOM 。 binding : 一个对象 ,包含以下 property 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 编译生成的虚拟节点 oldVnode : 上一个虚拟节点 ,仅在 update 和 componentUpdated 钩子中可用 。指令完整参数写法
<template> <input v-focus:mount.foo.bar="1 + 1" /> </template> <script> export default { name: HomeView, directives: { focus: { bind(el, binding, vnode, oldVnode) { console.log(binding); }, inserted(el, binding, vnode, oldVnode) {}, update(el, binding, vnode, oldVnode) {}, componentUpdated(el, binding, vnode, oldVnode) {}, unbind(el, binding, vnode, oldVnode) {} } } }; // [object Object] { "name": "focus", "rawName": "v-focus:mount.foo.bar", "value": 2, "expression": "1 + 1", "arg": "mount", "modifiers": { "foo": true, "bar": true }, "def": {} } </script> 动态参数 <template> <input v-focus:[dynamic].foo.bar="1 + 1" /> </template> <script> export default { name: HomeView, data() { return { dynamic: [1, 2, 3, 4, 5] }; }, directives: { focus: { bind(el, binding, vnode, oldVnode) { console.log(binding); }, inserted(el, binding, vnode, oldVnode) {}, update(el, binding, vnode, oldVnode) {}, componentUpdated(el, binding, vnode, oldVnode) {}, unbind(el, binding, vnode, oldVnode) {} } } }; </script> // [object Object] { "name": "focus", "rawName": "v-focus:[dynamic].foo.bar", "value": 2, "expression": "1 + 1", "arg": [ 1, 2, 3, 4, 5 ], "modifiers": { "foo": true, "bar": true }, "def": {} } 自定义指令示例 v-drag <template> <div class="container" v-drag></div> </template> <script> export default { name: HomeView, data() { return { dynamic: [1, 2, 3, 4, 5] }; }, directives: { drag: { bind(el, binding, vnode, oldVnode) { el.onmousedown = e => { const disX = e.clientX - el.offsetLeft; const disY = e.clientY - el.offsetTop; document.onmousemove = e => { el.style.left = e.clientX - disX + px; el.style.top = e.clientY - disY + px; }; document.onmouseup = () => { document.onmousemove = null; document.onmouseup = null; }; }; }, inserted(el, binding, vnode, oldVnode) {}, update(el, binding, vnode, oldVnode) {}, componentUpdated(el, binding, vnode, oldVnode) {}, unbind(el, binding, vnode, oldVnode) {} } } }; </script> <style scoped> .container { width: 500px; height: 300px; border: 1px solid red; position: fixed; left: 0; top: 0; } .container:hover { cursor: pointer; } </style>创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!