vue自定义函数虚拟真实dom问题

vue 自定义指令 为什么可以拿到真实dom参数啊 他不是还在虚拟dom吗

在 Vue 中,自定义指令的 bindinsertedupdatecomponentUpdated 四个钩子函数中,第一个参数 el 表示指令所绑定的元素,它是真实的 DOM 元素,而不是虚拟 DOM。当 Vue 编译模板时,会将模板转换为虚拟 DOM,然后通过虚拟 DOM 更新真实 DOM,这个过程中会执行自定义指令的钩子函数。

在自定义指令的钩子函数中,可以通过 el 参数访问到真实的 DOM 元素,因为 Vue 在执行钩子函数时已经将虚拟 DOM 转换为真实 DOM 并插入到页面中。所以,自定义指令可以拿到真实 DOM 参数。

在 Vue 中,虚拟 DOM 是用来描述真实 DOM 的一种数据结构,每个虚拟 DOM 节点都有对应的真实 DOM 节点,而且在渲染过程中,Vue 会将虚拟 DOM 转换成真实 DOM 并插入到页面中
在自定义指令中,通过钩子函数 bind、inserted、update、componentUpdated、unbind 可以访问到真实 DOM,这是因为在这些钩子函数执行时,Vue 已经将虚拟 DOM 转换成了真实 DOM 并插入到页面中
在 bind 钩子函数中,可以通过参数 el 获取到真实 DOM 元素,而在 update 钩子函数中,可以通过参数 el 和 vnode 获取到更新后的真实 DOM 元素和虚拟 DOM 节点
总结来说自定义指令中的钩子函数是在虚拟 DOM 中执行的,但是在执行过程中,Vue 已经将虚拟 DOM 转换成了真实 DOM 并插入到页面中,因此可以访问到真实 DOM 参数

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 你可以看下这个问题的回答https://ask.csdn.net/questions/7430677
  • 这篇博客你也可以参考下:vue 如果需要在DOM加载完成后获取DOM的动态属性,应该怎么做
  • 除此之外, 这篇博客: vue源码系列4之虚拟dom和真实dom中的 vue源码系列4之虚拟dom和真实dom 部分也许能够解决你的问题, 你可以仔细阅读以下内容或者直接跳转源博客中阅读:
    • 流程:
    // 判断用户是否 传入了render , 没传入时,可能传入了template。template没有传入时候,就拿最外面的 <div id="#app"></div>作为模板
    // 将我们的html -> 词法解析 (开始标签 , 结束标签,属性,文本)
    // ast语法树 用来描述html语法的 stack = []
    // codegen <div>hello</div> -> _c('div',{},'hello') -> 让字符串解析  _c创建元素
    // 方式:
    // 使用方式 01:模板引擎 new Function + with 来实现 -> render函数 
    	  // + 02:字符串解析转化为代码后 eval 好性能 会有作用域问题 -> 不使用
    // 之后生成虚拟dom
    
  • 您还可以看一下 卜算子老师的Vue实战:如何开发一个Vue插件课程中的 vue插件开发封装小节, 巩固相关知识点
  • 以下回答来自chatgpt:

    对于自定义指令来说,可以通过钩子函数来获取到真实的DOM参数。在自定义指令定义时,可以用bind、inserted、update、componentUpdated和unbind这几个钩子函数来完成相应的操作。其中, bind:只会执行一次,在指令第一次绑定到元素上时执行,该钩子函数可以接收到el、binding参数。 inserted:只会执行一次,在被绑定元素插入父节点时执行,该钩子函数可以接收到el、binding、vnode、oldVnode参数。 update:在指令所在元素上发生任何更新时执行,但是可能发生在子组件的更新之前。该钩子函数可以接收到el、binding、vnode、oldVnode参数。 componentUpdated:在指令所在元素及其子元素全部更新后执行。该钩子函数可以接收到el、binding、vnode、oldVnode参数。 unbind:只会执行一次,在指令解绑时执行,该钩子函数可以接收到el、binding参数。 在这些钩子函数中,除了bind之外,其他函数中的el参数都代表指令所在的DOM元素,可以通过该参数获取到真实的DOM参数。可以使用vue提供的$refs属性或getElementById、getElementsByClassName、getElementsByTagName等方法来获取指定的DOM元素,然后在钩子函数中进行操作。示例代码如下:

    Vue.directive('myDirective', {
      bind: function(el, binding) {
        // el代表指令所在的DOM元素,通过该参数可以获取到真实的DOM元素
        console.log(el.tagName); // 获取元素标签名
        console.log(el.getAttribute('id')); // 获取元素id属性
    
        // 可以使用vue提供的$refs属性或getElementById、getElementsByClassName、getElementsByTagName等方法来获取指定的DOM元素
        console.log(this.$refs.myElement); // 获取ref为myElement的元素
    
        // binding包含了指令和绑定的值
        console.log(binding.name);    // 获取指令名称
        console.log(binding.value);   // 获取绑定的值
      },
      inserted: function(el) {
        // el代表指令所在的DOM元素,通过该参数可以获取到真实的DOM元素
        console.log(el.tagName); // 获取元素标签名
    
        // 可以使用vue提供的$refs属性或getElementById、getElementsByClassName、getElementsByTagName等方法来获取指定的DOM元素
        console.log(this.$refs.myElement); // 获取ref为myElement的元素
      },
      update: function(el) {
        // el代表指令所在的DOM元素,通过该参数可以获取到真实的DOM元素
        console.log(el.tagName); // 获取元素标签名
    
        // 可以使用vue提供的$refs属性或getElementById、getElementsByClassName、getElementsByTagName等方法来获取指定的DOM元素
        console.log(this.$refs.myElement); // 获取ref为myElement的元素
      },
      componentUpdated: function(el) {
        // el代表指令所在的DOM元素,通过该参数可以获取到真实的DOM元素
        console.log(el.tagName); // 获取元素标签名
    
        // 可以使用vue提供的$refs属性或getElementById、getElementsByClassName、getElementsByTagName等方法来获取指定的DOM元素
        console.log(this.$refs.myElement); // 获取ref为myElement的元素
      },
      unbind: function(el) {
        // el代表指令所在的DOM元素,通过该参数可以获取到真实的DOM元素
        console.log(el.tagName); // 获取元素标签名
    
        // 可以使用vue提供的$refs属性或getElementById、getElementsByClassName、getElementsByTagName等方法来获取指定的DOM元素
        console.log(this.$refs.myElement); // 获取ref为myElement的元素
      }
    });
    

如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^