javascript - Adding externally handled elements in Vue.js? - Stack Overflow

I found lots of libraries that somehow marry an external library (and their DOM elements) with Vue.js.

I found lots of libraries that somehow marry an external library (and their DOM elements) with Vue.js. All of them though seem to only add child elements to the Vue.js-managed DOM node.

I wrote Vue-Stripe-Elements to make the use of the new Stripe V3 easier but struggled to mount Stripes elements to the Vue ponent.

The obvious way would be a .vue ponent like this:

<template>
</template>

<script>
export default {
  // could also be `mounted()`
  beforeMount () {
    const el = Stripe.elements.create('card')
    el.mount(this.$el)
  }
}
</script>

This would work if Stripe only adds children to the element it is mounted too but it looks like Stripe instead transcludes or replaces the given DOM node. Stripe of course also doesn't support any VNodes.

My current solution to the problem is to create a real DOM node and add it as a child:

<template>
</template>

<script>
export default {
  mounted () {
    const dom_node = document.createElement('div')
    const el = Stripe.elements.create('card')
    el.mount(dom_node)
    this.$el.appendChild(el)
  }
}
</script>

It works but it feels like I'm fighting against Vue.js here and I might create odd side effects here. Or am I just doing what other appending libraries do manually and it is the best way to go?

Is there an "official" way to do this?

Thanks in advance for any helpful ment about it.

I found lots of libraries that somehow marry an external library (and their DOM elements) with Vue.js. All of them though seem to only add child elements to the Vue.js-managed DOM node.

I wrote Vue-Stripe-Elements to make the use of the new Stripe V3 easier but struggled to mount Stripes elements to the Vue ponent.

The obvious way would be a .vue ponent like this:

<template>
</template>

<script>
export default {
  // could also be `mounted()`
  beforeMount () {
    const el = Stripe.elements.create('card')
    el.mount(this.$el)
  }
}
</script>

This would work if Stripe only adds children to the element it is mounted too but it looks like Stripe instead transcludes or replaces the given DOM node. Stripe of course also doesn't support any VNodes.

My current solution to the problem is to create a real DOM node and add it as a child:

<template>
</template>

<script>
export default {
  mounted () {
    const dom_node = document.createElement('div')
    const el = Stripe.elements.create('card')
    el.mount(dom_node)
    this.$el.appendChild(el)
  }
}
</script>

It works but it feels like I'm fighting against Vue.js here and I might create odd side effects here. Or am I just doing what other appending libraries do manually and it is the best way to go?

Is there an "official" way to do this?

Thanks in advance for any helpful ment about it.

Share Improve this question asked Feb 27, 2017 at 14:02 koehrkoehr 7791 gold badge10 silver badges21 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 5

Stripe Elements Vuejs 2

Use refs to get DOM elements in vuejs.

HTML

<div ref="cardElement"></div>

JS

mounted() {
    const stripe = Stripe('pk');
    const elements = stripe.elements();
    const card = elements.create('card');
    card.mount(this.$refs.cardElement);
}

I faced the same problem, so the method mounted is correct to add, but for the big applications where u call a specific vuejs i got the error "please make sure the element you are attempting to use is still mounted."

HTML Snippet :

 <div style="min-height:100px;">
                                            <div class="group">
                                                <h4><span class="label label-default"> Enter Card Details</span> </h4>
                                                <label class="cardlabel">
                                                    <span>Card number</span>
                                                    <div id="card-number-element" class="field"></div>
                                                    <span class="brand"><i class="pf pf-credit-card" id="brand-icon"></i></span>
                                                </label>
                                                <label class="cardlabel">
                                                    <span>Expiry date</span>
                                                    <div id="card-expiry-element" class="field"></div>
                                                </label>
                                                <label class="cardlabel">
                                                    <span>CVC</span>
                                                    <div id="card-cvc-element" class="field"></div>
                                                </label>
                                            </div>
                                        </div>

Vue.js

    (function () {

        let stripe = Stripe('keyhere');
        elements = stripe.elements(),
        cardNumberElementStripe = undefined;
        cardExpiryElementStripe = undefined;
        cardCvcElementStripe = undefined;
        var style = {
            base: {
                iconColor: '#666EE8',
                color: '#31325F',
                lineHeight: '40px',
                fontWeight: 300,
                fontFamily: 'Helvetica Neue',
                fontSize: '15px',

                '::placeholder': {
                    color: '#CFD7E0',
                },
            },
        };
            var purchase= new Vue({
                el: '#purchase',
                mounted() {

                    cardNumberElementStripe = elements.create('cardNumber', {
                        style: style
                    });

                    cardExpiryElementStripe = elements.create('cardExpiry', {
                        style: style
                    });
                    cardCvcElementStripe = elements.create('cardCvc', {
                        style: style
                    });
                    cardNumberElementStripe.mount('#card-number-element');
                    cardExpiryElementStripe.mount('#card-expiry-element');
                    cardCvcElementStripe.mount('#card-cvc-element');

                    cardNumberElementStripe.on('change', function (event) {
                        // Switch brand logo
                        if (event.brand) {
                            if (event.error) { setBrandIcon("unknown"); } else { setBrandIcon(event.brand); }
                        }

                        //setOute(event);
                    });
                    function setBrandIcon(brand) {
                        var brandIconElement = document.getElementById('brand-icon');
                        var pfClass = 'pf-credit-card';
                        if (brand in cardBrandToPfClass) {
                            pfClass = cardBrandToPfClass[brand];
                        }
                        for (var i = brandIconElement.classList.length - 1; i >= 0; i--) {
                            brandIconElement.classList.remove(brandIconElement.classList[i]);
                        }
                        brandIconElement.classList.add('pf');
                        brandIconElement.classList.add(pfClass);
                    }
                    var cardBrandToPfClass = {
                        'visa': 'pf-visa',
                        'mastercard': 'pf-mastercard',
                        'amex': 'pf-american-express',
                        'discover': 'pf-discover',
                        'diners': 'pf-diners',
                        'jcb': 'pf-jcb',
                        'unknown': 'pf-credit-card',
                    }



                },
            created() {
      //on the buttn click u are calling this using v-on:click.prevent="payment" 

  payment: function (e) {


                    stripe.createToken(cardNumberElementStripe).then(function (result) {
                        debugger;
                      if (result.token) {
                            cardId = result.token.id;
                           // $("#paymentform").get(0).submit();
                            } else if (result.error) {
                            errorElement.textContent = result.error.message;

                            return;
                        }
                    });
                }        
}

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

相关推荐

  • javascript - Adding externally handled elements in Vue.js? - Stack Overflow

    I found lots of libraries that somehow marry an external library (and their DOM elements) with Vue.js.

    3小时前
    20

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

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

关注微信