简体   繁体   English

在Vue.js中添加外部处理的元素?

[英]Adding externally handled elements in Vue.js?

I found lots of libraries that somehow marry an external library (and their DOM elements) with Vue.js. 我发现很多库以某种方式将外部库(及其DOM元素)与Vue.js结合在一起。 All of them though seem to only add child elements to the Vue.js-managed DOM node. 所有这些似乎只是将子元素添加到Vue.js管理的DOM节点。

I wrote Vue-Stripe-Elements to make the use of the new Stripe V3 easier but struggled to mount Stripes elements to the Vue component. 我编写了Vue-Stripe-Elements以便更容易地使用新的Stripe V3,但很难将Stripes元素安装到Vue组件。

The obvious way would be a .vue component like this: 显而易见的方法是像这样的.vue组件:

<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只将子元素添加到它所安装的元素中,那么这将起作用,但它看起来像Stripe而是转换或替换给定的DOM节点。 Stripe of course also doesn't support any VNode s. Stripe当然也不支持任何VNode

My current solution to the problem is to create a real DOM node and add it as a child: 我目前解决这个问题的方法是创建一个真正的DOM节点并将其添加为子节点:

<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. 它有效,但感觉我在这里与Vue.js作战,我可能会在这里产生奇怪的副作用。 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 comment about it. 在此先感谢任何有用的评论。

Stripe Elements Vuejs 2 条纹元素Vuejs 2

Use refs to get DOM elements in vuejs. 使用refs在vuejs中获取DOM元素。

HTML HTML

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

JS 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." 我遇到了同样的问题,所以安装的方法是正确的添加,但对于你调用特定vuejs的大型应用程序,我得到错误“请确保你正在尝试使用的元素仍然被挂载。”

HTML Snippet : HTML代码段:

 <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 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); }
                        }

                        //setOutcome(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;
                        }
                    });
                }        
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM