javascript - How to Add or Remove Vue.js component dynamically (programmatically or on the fly) - Stack Overflow

Here is my code, this is just a example code, if the below works then this will help me to build someth

Here is my code, this is just a example code, if the below works then this will help me to build something else that I am working on.

<template>
  <div id="wrapper">
    <div id="divOne">
      <!-- Add or remove ponent here dynamically -->
    </div>
    <div id="divTwo">
      <!-- Add or remove ponent here dynamically -->
    </div>

    <!-- There will be more divs like #divOne #divTwo above -->

    <div>
      <input type="radio" id="one" value="divOne" v-model="pickedDiv">
      <label for="one">One</label>
    </div>
    <div>
      <input type="radio" id="two" value="divTwo" v-model="pickedDiv">
      <label for="two">Two</label>
    </div>

    <button @click="addComponent">Add Component</button>
  </div>
</template>

<script>
import SomeComponent from './SomeComponent'

export default {
  data() {
    return {
      pickedDiv: '',
      pickedDivPreviously: ''
      propItems: ['item1', 'item2']
    }
  }
  methods: {
    addComponent () {
      //-- This is not working code but I need something like this --//
      this.pickedDivPreviously = this.pickedDiv // event not sure how to get previously selected div

      const divThatIsPicked = document.getElementById(this.pickedDiv)
      const divThatWasPickedPreviously = document.getElementById(this.pickedDivPreviously)

      // code here to remove/empty/destroy old ponent from 'divThatWasPickedPreviously'
      divThatWasPickedPreviously.innerHTML = "" 

      // code here to add new ponent in 'divThatIsPicked'
      divThatIsPicked.appendChild('<some-ponent :someProp="propItems" @someEvent="someFn">')
    }
  }
}
</script>

I don't want to distract you from answering actual question but If you are curious about what I am working then check this :) Here I am trying to add new child DIV at the end of the row when any row item is clicked.

I will be more than happy if this is converted to vue than the actual question asked above, as said please don't get distracted from actual question if you find it hard :)

Here is my code, this is just a example code, if the below works then this will help me to build something else that I am working on.

<template>
  <div id="wrapper">
    <div id="divOne">
      <!-- Add or remove ponent here dynamically -->
    </div>
    <div id="divTwo">
      <!-- Add or remove ponent here dynamically -->
    </div>

    <!-- There will be more divs like #divOne #divTwo above -->

    <div>
      <input type="radio" id="one" value="divOne" v-model="pickedDiv">
      <label for="one">One</label>
    </div>
    <div>
      <input type="radio" id="two" value="divTwo" v-model="pickedDiv">
      <label for="two">Two</label>
    </div>

    <button @click="addComponent">Add Component</button>
  </div>
</template>

<script>
import SomeComponent from './SomeComponent'

export default {
  data() {
    return {
      pickedDiv: '',
      pickedDivPreviously: ''
      propItems: ['item1', 'item2']
    }
  }
  methods: {
    addComponent () {
      //-- This is not working code but I need something like this --//
      this.pickedDivPreviously = this.pickedDiv // event not sure how to get previously selected div

      const divThatIsPicked = document.getElementById(this.pickedDiv)
      const divThatWasPickedPreviously = document.getElementById(this.pickedDivPreviously)

      // code here to remove/empty/destroy old ponent from 'divThatWasPickedPreviously'
      divThatWasPickedPreviously.innerHTML = "" 

      // code here to add new ponent in 'divThatIsPicked'
      divThatIsPicked.appendChild('<some-ponent :someProp="propItems" @someEvent="someFn">')
    }
  }
}
</script>

I don't want to distract you from answering actual question but If you are curious about what I am working then check this :) Here I am trying to add new child DIV at the end of the row when any row item is clicked.

I will be more than happy if this is converted to vue than the actual question asked above, as said please don't get distracted from actual question if you find it hard :)

Share Improve this question edited Dec 5, 2018 at 7:57 Syed asked Apr 14, 2018 at 2:37 SyedSyed 16.6k15 gold badges127 silver badges157 bronze badges 1
  • its possible. check this article : css-tricks./… – dagalti Commented Apr 5, 2019 at 3:21
Add a ment  | 

2 Answers 2

Reset to default 5

I got help from JamesThomson in forum.vuejs, though the solution did not fix my issue but I got to understand the limitation or possibilities of using Vue.js.

JamesThomson says:

Yeah, your example code definitely won’t work. When working with Vue you need to think in a data oriented way, not DOM oriented (like jQuery)

Taken from your SO post:

Here I am trying to add new child DIV at the end of the row when any row item is clicked.

I assume this is your end goal for this topic. A simple example of this can be achieved like so: https://codepen.io/getreworked/pen/XZOgbm?editors=1010

let Wele = {
  template: `
    <p @click="toggleMsg()">Wele {{ msg }}!</p>
  `,
  
  data () {
    return {
      msg: 'home'
    }
  },
  
  methods: {
    toggleMsg () {
      return this.msg = this.msg === 'home' ? 'back' : 'home'; 
    }
  }
}

const App = new Vue({
  el: '#app',
  
  data: {
    children: [
      Wele
    ]
  },
  
  methods: {
    add () {
      this.children.push(Wele);
    },
  }
});
<link rel="stylesheet" href="//cdn.rawgit./milligram/milligram/master/dist/milligram.min.css">
<script src="https://cdnjs.cloudflare./ajax/libs/vue/2.5.13/vue.js"></script>

<div id="app">
  <template v-for="(child, index) in children">
      <ponent :is="child" :key="child.name"></ponent>
  </template>
  
  <button @click="add()">Add Another</button>
</div>

or you can use a render function for more flexibility https://jsfiddle/jamesbrndwgn/ku7m1dp0/9/

const Reusable = {
  template: '<div>{{ name }} {{ bar }}</div>',
  
  props: {
    name: {
      type: String
    }
  },
  
  data () {
    return {
      bar: 'Bar'
    }
  }
}

const App = new Vue({
  el: '#app',
  
  data: {
    items: []
  },
  
  methods: {
    addComponent () {
      const renderComponent = {
        render (h) {         
          return h(Reusable, {
            class: ['foo'],
            
            props: { 
              name: 'Foo'
            }
          })
        }
      }
      
      this.items.push(renderComponent)      
    }
  }
});
<script src="https://cdnjs.cloudflare./ajax/libs/vue/2.5.13/vue.js"></script>
<link rel="stylesheet" href="//cdn.rawgit./milligram/milligram/master/dist/milligram.min.css">

<div id="app">
  <ponent v-for="item in items" ref="itemRefs" :is="item" :key="item.name"></ponent>
  
  <button @click="addComponent">Add Component</button>
</div>

I found one of the other ways that does kinda same as above but work only with old vue.js-1 not with vue.js-2:

var createNewBox = function() {
	var MyPartial = Vue.extend({});
  window.partial = new MyPartial({
    template: '#partial',
    data: function() {
      return {
        txt: 'This is partial'
      }
    },
    methods: {
    	print: function() {
        console.log('this.txt : ' + this.txt)
        console.log('main.txt : ' + main.txt)
      },
    },
  })
  window.partial.$mount().$appendTo('body')
}

window.main = new Vue({
  el: '#main',
  data: function() {
  	return {
    	txt: 'This is main'
    }
  },
  methods: {
  	show: function() {
    	createNewBox()
    }
  },
})
<script src="https://cdn.bootcss./vue/1.0.17/vue.min.js"></script>

<div @click="show" style="width:200px;height:200px;background:#000" id="main">
  <template id="partial">
    <div style="width:100px;height:100px;background:#ff0" @click.stop="print"></div>
  </template>
</div>

this converted to Vue.

https://codepen.io/jacobgoh101/pen/Kojpve

<div id="app">
  <div class="parent">
    <div class="child" @click="handleChildClick" data-new-child-id="1">1234</div>

    <div class="child" @click="handleChildClick" data-new-child-id="2">12341234 </div>

    <div class="child" @click="handleChildClick" data-new-child-id="3">123412341234</div>

    <div class="child" @click="handleChildClick" data-new-child-id="4">1234</div>

    <div class="new-child" v-if="[1,2,3,4].indexOf(showNewChild) > -1">boom</div>

    <div class="child" @click="handleChildClick" data-new-child-id="5">12341234</div>

    <div class="child" @click="handleChildClick" data-new-child-id="6">123412341234</div>

    <div class="child" @click="handleChildClick" data-new-child-id="7">1234</div>

    <div class="child" @click="handleChildClick" data-new-child-id="8">12341234</div>

    <div class="new-child" v-if="[5,6,7,8].indexOf(showNewChild) > -1">boom</div>

    <div class="child" @click="handleChildClick" data-new-child-id="9">123412341234</div>

    <div class="new-child" v-if="[9].indexOf(showNewChild) > -1">boom</div>
  </div>
</div>

Javascript

new Vue({
  el: '#app',
  data: {
    showNewChild:null
  },
  methods: {
    handleChildClick(e) {
      let id = e.target.dataset.newChildId;
      id = Number(id);
      this.showNewChild = id;
    }
  }
})

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1743904928a4527313.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信