Vue 组件中 移动 this.$el 的注意事项

比如,

mounted () {    document.body.appendChild(this.$el);    // insertAdjacentElement // insertBefore},

这几行代码会导致 dom 元素位置  与 VNode 期望的位置不一致

比如:

---------------------------------------

父组件:

div(id=‘p‘) h1 第1个 button(@click="add")  新增 p(v-for="(item,index) in list", :key="index")         | 第 {{item}} 个元素 ccc
---js部分
methods: {    add () {        this.list.push(1);    }

}

---------------------------------------

子组件 ccc:

div | 我是document.body.append的元素
---js部分
mounted () {    document.body.appendChild(this.$el);    // insertAdjacentElement // insertBefore}

---------------------------------------

本来 ccc 在VNode 中的位置其父 parent 是  id 为 p 的div 元素, 然后由于在 mounted 中,$el的位置发生了移动,导致其实际的位置发生了改变,父节点变为 body 元素。

这将导致  父组件中的 v-for  p 元素,渲染失败

 

原因:

在点击 父组件 按钮是,会触发 组件的update, 这将会导致新的元素会  insert 到dom树中,这段代码在 vue 源码,patch.js 中

function insert (parent, elm, ref$$1) {  if (isDef(parent)) {    if (isDef(ref$$1)) {      if (ref$$1.parentNode === parent) {        nodeOps.insertBefore(parent, elm, ref$$1);      }    } else {      nodeOps.appendChild(parent, elm);    }  }}

在插入新的 p 元素时, 会执行这段代码, 三个参数 分别为: div(id=‘p‘),  p 元素自身, ref$$1 为 ccc 的$el

ref$$1.parentNode === parent

由于 ccc 的$el 的parent 发生了变化,导致这行判断失效, 渲染失败。

原文地址:https://www.cnblogs.com/btgyoyo/p/9305148.html

时间: 2024-10-02 02:16:26

Vue 组件中 移动 this.$el 的注意事项的相关文章

vue组件中使用iframe元素

需要在本页面中展示vue组件中的超链接,地址栏不改变的方法: <template> <div class="accept-container"> <div class="go-back" v-show="goBackState" @click="goBack">GoBack</div> <ul> <li v-for="item in webAddres

vue组件中的样式属性:scoped,解决在父组件中无法修改子组件样式问题

Scoped CSS规范是Web组件产生不污染其他组件,也不被其他组件污染的CSS规范. vue组件中的style标签标有scoped属性时表明style里的css样式只适用于当前组件元素,它是通过使用PostCSS来改变以下内容实现的: <style scoped> .example { color: red; } </style> <template> <div class="example">hi</div> </

Vue组件中的父子传值

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" con

vue组件中的通信

一.组件间的关系 1.父子关系 2.兄弟关系 3.隔代关系 二.组件间的通信方式 1.props 2.$emit/$on 3.VUEX 4.$parent/$children 5.$attrs/$listeners 6.provide/inject 三.通信方式举例 新建了一个过程,采用webpack来管理项目.  方法一:props / $emit 1.props---父组件向子组件传值 子组件:sub1.vue 父组件:app.vue 父组件通过props向下传递给子组件.注:组件中的数据共

深入理解--VUE组件中数据的存放以及为什么组件中的data必需是函数

1.组件中数据的存放 ***(重点)组件是一个单独模块的封装:这个模块有自己的HTML模板,也有data属性. 只是这个data属性必需是一个函数,而这个函数返回一个对象,这个对象里面存放着组件的数据. <template id="MyCpn"> <div> <h2>组件数据的存放 </h2> <p>{{title}}</p> </div> </template> <script>

vue组件中的style scoped中遇到的问题

在uve组件中我们我们经常需要给style添加scoped来使得当前样式只作用于当前组件的节点.添加scoped之后,实际上vue在背后做的工作是将当前组件的节点添加一个像data-v-1233这样唯一属性的标识,当然也会给当前style的所有样式添加[data-v-1233]这样的话,就可以使得当前样式只作用于当前组件的节点.但是我们需要注意的是如果我们添加了子组件,同样的,如果子组件也用scoped标识了,那么在父组件中是不能设置子组件中的节点的.若父组件有scoped,子组件没有设置,同样

vue组件中click事件失效

最近使用vue学习开发移动端的项目,使用了bette-scroll插件做滚动.在引入better-scroll的组件中使用@click事件的时候,点击事件失效,v-on:click.v-bind:click.@click.native都不行,试了一下@touchstart是却是可以的,发现better-scroll的配置中没有设置click:true,设置过之后click事件成功. 后来在使用vuex的时候一直报"[vuex] unknown mutation type: changeCity&

nuxtjs在vue组件中使用window对象编译报错的解决方法

我们知道nuxtjs是做服务端渲染的,他有很多声明周期是运行在服务端的,以及正常的vue声明周期mounted之前均是在服务端运行的,那么服务端是没有比如window对象的location.navagitor等,以及H5的FormData()方法,所以当你在created之前使用这些时,会报错,那么如何处理呢? 1.自己的写的函数里包含window等 因为nuxt为SSR框架,所以其编译打包时会区分服务端渲染还是客户端渲染(即浏览器),在vue文件中使用window对象报错的原因是,webpac

vue组件中 IS 用法

//html <link rel="stylesheet" href="http://www.jq22.com/demo/animate-141106223642/animate.min.css" /> <script src="//cdn.bootcss.com/vue/1.0.24/vue.min.js"></script> <div id="app"> <span c