[首页]
[文章]
[教程]
首页
Web开发
Windows开发
编程语言
数据库技术
移动平台
系统服务
微信
设计
布布扣
其他
数据分析
首页
>
其他
> 详细
vue自定义指令VNode详解(转)
时间:
2019-05-30 22:04:58
阅读:
199
评论:
0
收藏:
0
[点我收藏+]
1、自定义指令钩子函数 Vue.directive(‘my-directive‘, { bind: function () { // 做绑定的准备工作 // 比如添加事件监听器,或是其他只需要执行一次的复杂操作 }, inserted: function (newValue, oldValue) { // 被绑定元素插入父节点时调用 }, update: function (newValue, oldValue) { // 根据获得的新值执行对应的更新 // 对于初始值也会被调用一次 }, unbind: function () { // 做清理工作 // 比如移除在 bind() 中添加的事件监听器 } }) 指令定义函数提供了几个钩子函数(可选): bind: 只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个在绑定时执行一次的初始化动作。 inserted: 被绑定元素插入父节点时调用(父节点存在即可调用,不必存在于 document 中)。 update: 所在组件的 VNode 更新时调用,但是可能发生在其孩子的 VNode 更新之前。指令的值可能发生了改变也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。 componentUpdated: 所在组件的 VNode 及其孩子的 VNode 全部更新时调用。 unbind: 只调用一次, 指令与元素解绑时调用。 接下来我们来看一下钩子函数的参数 (包括 el,binding,vnode,oldVnode) 。 2、钩子函数参数 钩子函数被赋予了以下参数: el: 指令所绑定的元素,可以用来直接操作 DOM 。 binding: 一个对象,包含以下属性: name: 指令名,不包括 v- 前缀。 value: 指令的绑定值, 例如: v-my-directive=”1 + 1”, value 的值是 2。 oldValue: 指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。 expression: 绑定值的字符串形式。 例如 v-my-directive=”1 + 1” , expression 的值是 “1 + 1”。 arg: 传给指令的参数。例如 v-my-directive:foo, arg 的值是 “foo”。 modifiers: 一个包含修饰符的对象。 例如: v-my-directive.foo.bar, 修饰符对象 modifiers 的值是 { foo: true, bar: true }。 vnode: Vue 编译生成的虚拟节点 oldVnode: 上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。 3、VNode接口 export default class VNode { tag: string | void; data: VNodeData | void; children: ?Array
; text: string | void; elm: Node | void; ns: string | void; context: Component | void; // rendered in this component‘s scope functionalContext: Component | void; // only for functional component root nodes key: string | number | void; componentOptions: VNodeComponentOptions | void; componentInstance: Component | void; // component instance parent: VNode | void; // component placeholder node raw: boolean; // contains raw HTML? (server only) isStatic: boolean; // hoisted static node isRootInsert: boolean; // necessary for enter transition check isComment: boolean; // empty comment placeholder? isCloned: boolean; // is a cloned node? isOnce: boolean; // is a v-once node? asyncFactory: Function | void; // async component factory function asyncMeta: Object | void; isAsyncPlaceholder: boolean; ssrContext: Object | void; constructor ( tag?: string, data?: VNodeData, children?: ?Array
, text?: string, elm?: Node, context?: Component, componentOptions?: VNodeComponentOptions, asyncFactory?: Function ) { this.tag = tag this.data = data this.children = children this.text = text this.elm = elm this.ns = undefined this.context = context this.functionalContext = undefined this.key = data && data.key this.componentOptions = componentOptions this.componentInstance = undefined this.parent = undefined this.raw = false this.isStatic = false this.isRootInsert = true this.isComment = false this.isCloned = false this.isOnce = false this.asyncFactory = asyncFactory this.asyncMeta = undefined this.isAsyncPlaceholder = false } // DEPRECATED: alias for componentInstance for backwards compat. /* istanbul ignore next */ get child (): Component | void { return this.componentInstance } } export const createEmptyVNode = (text: string = ‘‘) => { const node = new VNode() node.text = text node.isComment = true return node } export function createTextVNode (val: string | number) { return new VNode(undefined, undefined, undefined, String(val)) } // optimized shallow clone // used for static nodes and slot nodes because they may be reused across // multiple renders, cloning them avoids errors when DOM manipulations rely // on their elm reference. export function cloneVNode (vnode: VNode, deep?: boolean): VNode { const cloned = new VNode( vnode.tag, vnode.data, vnode.children, vnode.text, vnode.elm, vnode.context, vnode.componentOptions, vnode.asyncFactory ) cloned.ns = vnode.ns cloned.isStatic = vnode.isStatic cloned.key = vnode.key cloned.isComment = vnode.isComment cloned.isCloned = true if (deep && vnode.children) { cloned.children = cloneVNodes(vnode.children) } return cloned } export function cloneVNodes (vnodes: Array
, deep?: boolean): Array
{ const len = vnodes.length const res = new Array(len) for (let i = 0; i < len; i++) { res[i] = cloneVNode(vnodes[i], deep) } return res } 4、VNode 不存在父节点: 存在父节点: v-IME自定义指令示例: import { log } from ‘SUtil‘ const install = Vue => { let isBind = true let IMEService = ‘‘ let $this = new Vue({ data () { return { outEl: null, outVnode: null } }, watch: { outVnode (value, oldValue) { if (oldValue) { oldValue.componentInstance.isFocus = false } } } }) async function openIme (e, option) { log.d(‘openIme‘, isBind, $this.$data.outVnode.componentInstance.percentValue) if ($this.$data.outEl && IMEService && isBind) { log.d(‘open‘) $this.$data.outEl.target.focus() let ret = await IMEService.open({ type: IMEService[option.type], track: Number.parseInt(option.track), w: Number.parseInt(option.w), h: Number.parseInt(option.h), x: Number.parseInt(option.x), y: Number.parseInt(option.y) }) if (ret.isSuccess) { console.log(‘输入法开启成功‘) } } } async function closeIme (e) { log.d(‘closeIme‘, isBind, $this.$data.outVnode.componentInstance.percentValue) if ($this.$data.outEl && IMEService && isBind) { log.d(‘close‘) $this.$data.outVnode.componentInstance.isFocus = false let ret = await IMEService.close() if (ret.isSuccess) { console.log(‘输入法关闭成功‘) } } } Vue.directive(‘IME‘, { bind: function (el, binding, vnode) { $this.$data.outVnode = vnode if (window.taf && window.taf.service.IMEService) { IMEService = window.taf.service.IMEService } else { log.e(‘IMEService 不存在‘) $this.$data.outVnode.componentInstance.$emit(‘error‘, ‘输入法故障‘) log.d(‘error‘, $this.$data.outVnode.componentInstance.percentValue) } }, inserted: function (el, binding, vnode) { const inputDom = vnode.componentInstance.$el.querySelector(‘input‘) if (inputDom) { inputDom.addEventListener(‘focus‘, async focusEvent => { log.d(‘focus‘) $this.$data.outEl = focusEvent $this.$data.outVnode = vnode vnode.componentInstance.ctrlBlur = true openIme(focusEvent, binding.value) }) inputDom.addEventListener(‘click‘, async focusEvent => { log.d(‘click‘) $this.$data.outEl = focusEvent $this.$data.outVnode = vnode vnode.componentInstance.ctrlBlur = true openIme(focusEvent, binding.value) }) inputDom.addEventListener(‘blur‘, async focusEvent => { log.d(‘blur‘) $this.$data.outEl = focusEvent $this.$data.outVnode = vnode vnode.componentInstance.ctrlBlur = false closeIme(focusEvent) }) } isBind = true }, async unbind (el, binding, vnode) { log.d(‘unbind‘) if (window.taf && window.taf.service.IMEService) { IMEService = window.taf.service.IMEService } else { log.e(‘IMEService 不存在‘) $this.$data.outVnode.componentInstance.$emit(‘error‘, ‘IMEService 不存在‘) log.d(‘error‘, $this.$data.outVnode.componentInstance.percentValue) } const inputDom = vnode.componentInstance.$el.querySelector(‘input‘) if (inputDom) { inputDom.removeEventListener(‘click‘, openIme) isBind = false await IMEService.close() } } }) } export default { install } --------------------- 原文:https://blog.csdn.net/qq_27626333/article/details/77743719
vue自定义指令VNode详解(转)
原文:https://www.cnblogs.com/q149072205/p/10951919.html
踩
(
0
)
赞
(
0
)
举报
评论
一句话评论(
0
)
登录后才能评论!
分享档案
更多>
2021年09月23日 (328)
2021年09月24日 (313)
2021年09月17日 (191)
2021年09月15日 (369)
2021年09月16日 (411)
2021年09月13日 (439)
2021年09月11日 (398)
2021年09月12日 (393)
2021年09月10日 (160)
2021年09月08日 (222)
最新文章
更多>
2021/09/28 scripts
2022-05-27
vue自定义全局指令v-emoji限制input输入表情和特殊字符
2022-05-27
9.26学习总结
2022-05-27
vim操作
2022-05-27
深入理解计算机基础 第三章
2022-05-27
C++ string 作为形参与引用传递(转)
2022-05-27
python 加解密
2022-05-27
JavaScript-对象数组里根据id获取name,对象可能有children属性
2022-05-27
SQL语句——保持现有内容在后面增加内容
2022-05-27
virsh命令文档
2022-05-27
教程昨日排行
更多>
1.
list.reverse()
2.
Django Admin 管理工具
3.
AppML 案例模型
4.
HTML 标签列表(功能排序)
5.
HTML 颜色名
6.
HTML 语言代码
7.
jQuery 事件
8.
jEasyUI 创建分割按钮
9.
jEasyUI 创建复杂布局
10.
jEasyUI 创建简单窗口
友情链接
汇智网
PHP教程
插件网
关于我们
-
联系我们
-
留言反馈
- 联系我们:wmxa8@hotmail.com
© 2014
bubuko.com
版权所有
打开技术之扣,分享程序人生!