<!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" content="ie=edge"> <title>Document</title> <script src="https://unpkg.com/vue/dist/vue.js"></script> <style> html,body { font: 13px/18px sans-serif; } select { min-width: 300px; } </style> </head> <body> <div id="el"></div> <!-- using string template here to work around HTML <option> placement restriction --> <script type="text/x-template" id="demo-template"> <div> <p>Selected: {{ selected }}</p> <select2 :options="options" v-model="selected"> <option disabled value="0">Select one</option> </select2> </div> </script> <script type="text/x-template" id="select2-template"> <select> <slot></slot> </select> </script> <script> Vue.component(‘select2‘,{ props: [‘options‘,‘value‘],template: ‘#select2-template‘,mounted: function () { var vm = this $(this.$el) // init select2 .select2({ data: this.options }) .val(this.value) .trigger(‘change‘) // emit event on change. .on(‘change‘,function () { vm.$emit(‘input‘,this.value) }) },watch: { value: function (value) { // update value $(this.$el) .val(value) .trigger(‘change‘) },options: function (options) { // update options $(this.$el).empty().select2({ data: options }) } },destroyed: function () { $(this.$el).off().select2(‘destroy‘) } }) var vm = new Vue({ el: ‘#el‘,template: ‘#demo-template‘,data: { selected: 2,options: [ { id: 1,text: ‘Hello‘ },{ id: 2,text: ‘World‘ } ] } }) </script> </body> </html>