Использование компонента vue в содержимом sweetalert2

У меня есть несколько простых модалов Sweetalert2 в проект Vue. Я хочу использовать пользовательский компонент в предупреждении. Например:

<template>
  <h1>Hello {{name}}</h1>
</template>
<script>
module.exorts: {
  props: ["name"]
}
</script>

my_template.vue

И в моем модальном режиме sweetalert:

swal({
  titleText: "Hi",
  html: '<my-template name="hello"></my-template>'
});

Я не уверен, возможно ли это вообще и как это сделать.


person angrykoala    schedule 08.02.2018    source источник


Ответы (3)


Технически это выглядит возможным:

Vue.component('my-component', {
  template: '<div>A custom component!</div>'
})

new Vue({
  el: '#modal',
  beforeCreate:  swal({
    titleText: "Hi",
    html: '<div id="modal"><my-component></my-component></div>'
  })
})

Но вы можете обернуть его функцией. Взгляните на мою скрипку:

JS Fiddle

Это просто идея, на мой взгляд, это не очень хорошо, но все еще работает. Также я должен упомянуть, что вы будете создавать новый экземпляр vue каждый раз, когда будете открывать диалог таким образом.

Вариант 2 из комментария к моему ответу:

Vue.component('my-component', {
    template: '<div>A custom component!</div>'
})    

swal({
    html: "<my-component></my-component>"
})
  
new Vue({
    el: swal.getHtmlContainer()
})  
 

Fiddle

person soeik    schedule 08.02.2018
comment
или, что еще лучше: html: '<my-component></my-component>', а затем new Vue({ el: swal.getContent() }) - person Limon Monte; 08.02.2018
comment
@LimonMonte спасибо за идею. Я добавил это к своему ответу, если вы не возражаете. - person soeik; 08.02.2018
comment
@KirillStepanov в реальной ситуации, наши приложения везде переполнены привязкой данных. Это решение касается создания нового объекта Vue и его рендеринга $ swal.html, но привязка данных не будет работать .... :( Кстати, Лимон Монте является владельцем sweetalert2. - person Justin Moh; 27.04.2018
comment
@JustinMoh Я согласен, но мы не знаем контекста вопроса. Я думаю, что передача свойств в экземпляре vue для визуализации компонента все еще возможна. Но я понятия не имею, почему бы не использовать только литерал шаблона. Не вижу никакой пользы в использовании для этого vue. - person soeik; 28.04.2018
comment
@KirillStepanov, что я сейчас использую html: '<div id="swalHtml"></div>', затем в onBeforeOpen: используйте let ComponentClass = Vue.extend(MyComponent); let instance = new ComponentClass({ propsData: { item: this.item } }), чтобы расширить компонент vue в контексте, затем смонтируйте его на dom instance.$mount(); document.getElementById('swalHtml').appendChild(instance.$el). - person Justin Moh; 29.04.2018
comment
Вторая скрипка будет работать, только если вы измените ее на swal.fire ({... - person J.Kirk.; 31.07.2019
comment
Я пытаюсь использовать опору для передачи переменной, но она не работает. - person Atef; 22.01.2020
comment
@Atef убедитесь, что вы используете propsData, а не реквизит - person Matt Wohler; 20.04.2020

Мне удалось заставить его работать следующим образом:

Я включаю всю логику шаблона между обратными кавычками: ''

вам также потребуется отредактировать файл vue.config.js и добавить внутри объекта configurewebpack следующее: 'vue $': 'vue / dist / vue.esm.js'

configureWebpack: {
resolve: {
  alias: {
    'src': resolveSrc('src'),
    'chart.js': 'chart.js/dist/Chart.js',

    // add this line for include components inside swal alert
    'vue$':'vue/dist/vue.esm.js'
  }
 }
}

Как только это будет сделано, вы должны перезапустить проект «npm run dev».

Это мой полный пример, протестированный и работающий

openSweet() {
  Vue.component('my-comp', {
      template: `
            <div class="card-content">
              <div class="span2">
                    <div class="col-sm-6 col-md-2 col-lg-3">
                        <div class="row">
                          <div style="margin-top: 6px;" >
                            <p-switch v-model="switchTrip.state" type="primary" 
on-text="ON" off-text="OFF" style="justify-content:center"></p-switch>
                            <h5 class="card-title" style="margin-left: 
25px;">Recorridos</h5>
                          </div>
                        </div>

                        <div class="row">
                          <div style="margin-top: 6px;" >
                            <p-switch v-model="switchVel.state" type="primary" 
on-text="ON" off-text="OFF" style="justify-content:center"></p-switch>
                            <h5 class="card-title" style="margin-left: 
25px;">Velocidad</h5>
                          </div>
                        </div>

                    </div>
              </div>
              <div class="span2">
                    <div class="col-sm-6 col-md-4 col-lg-3">
                        <div class="row">
                          <div >
                            <input type="search" class="form-control input-sm" 
placeholder="km / h" v-model="vmax">
                            <h5 class="card-title">Vel. Max</h5>
                          </div>
                        </div>

                        <div class="row">
                          <div>
                            <input type="search" class="form-control input-sm" 
placeholder="minutos" v-model="tol">
                            <h5 class="card-title">Tolerancia</h5>
                          </div>
                        </div>
                    </div>
              </div>
            </div>
      `,
    data () {
      return {
        switchVel: {
          state: false
        },
        switchEvent: {
          state: false
        },
        switchTrip: {
          state: false
        },
        search: '',
        vmax: '',
        tol: ''
      }
    },
    components: {
        [Button.name]: Button,
        Card,
        PSwitch
    }
  })
  new Vue({
    el: '#modal',
    beforeCreate:  () => {
      swal({
        titleText: "Descarga de Reportes",
        showCancelButton: true,
        cancelButtonText: 'Cancelar',
        confirmButtonText: 'Descargar',
        // confirmButtonAriaLabel: 'glyphicon glyphicon-ok-sign',
        // cancelButtonAriaLabel: 'glyphicon glyphicon-remove-sign',
        confirmButtonColor: '#3085d6',
        cancelButtonColor: '#d33',
        width: 800,
        html: '<div id="modal"><my-comp></my-comp></div>'
      })
    }
  })
}

Я надеюсь это поможет тебе

С Уважением

person Ale DC    schedule 08.10.2019

Вы можете отображать и скрывать контент внутри своего приложения:

<div id="swalHTML" style='display: none'>
  <my-template name="hello"></my-template>
</div>

Затем передайте в предупреждение innerHTML элемента:

let el = document.getElementById('swalHTML')
swal({
  html: el.innerHTML
});
person opowell    schedule 31.12.2020