Difference in behavior between inline templates and SFC templates


#1

I am trying to use the vue-phone-number-input component in my f7-vue app. It works fine when using in f7 app that is inlined with templates and script all in the html file. And it also works fine in a regular Vue app without f7. But when I try to use this component in an f7-vue app built by webpack with SFC and es6 modules, then an infinite render loop error occurs:

vue.runtime.esm.js?2b0e:619 [Vue warn]: You may have an infinite update loop in a component render function.

found in

---> <CountrySelector> at CountrySelector.vue
       <VuePhoneNumberInput> at index.vue
         <F7PageContent>
           <F7Page>
             <PhonePage> at src/components/PhonePage.vue
               <F7View>
                 <F7App>
                   <App> at src/App.vue
                     <Root>

The inline and module-based apps seem to be basically the same, yet the component behaves differently. I distilled a repro as simply as I could. The source code is at: https://github.com/jacobg/f7-phone-input

Demos of the repro are here:

  1. webpack version with error - https://jacobg.github.io/f7-phone-input
  2. inline version that works fine - https://jacobg.github.io/f7-phone-input/inline.html

What could be the problem? Am I missing something?

Thanks.


#2

In the webpack version, if the <phone-page /> component is declared directly in App.vue without making a route for it, then it works fine. The problem occurs when it’s a routable component. What would cause that issue?


#3

It also works if I programatically create the VuePhoneNumberInput in the PhonePage’s pageAfterIn event handler:

    pageAfterIn () {
      const vuePhoneNumberInput = new VuePhoneNumberInputClass({
        parent: this,
        propsData: {
          value: this.phoneNumber
        }
      })
      vuePhoneNumberInput.$on('input', value => { this.phoneNumber = value })
      vuePhoneNumberInput.$mount()
      this.$el.querySelector('.container').appendChild(vuePhoneNumberInput.$el)
    }

Why is the component sensitive to being rendered when mounting vs pageAfterIn? There seems to be a similar issue here:


#4

Another thought: This is the first time I’ve used a non-f7 input component in an f7 app. Is there a quirk to that? Do f7 components comply in some way to how f7 apps render, such that non f7 components (maybe input or other components with bindings) might have issues?


#5

Ideally you should never use inline templates with Vue, especially on production. There shouldn’t be any behavior difference, but inline templates are limited.

I checked the repo and can say that issue somewhere is on plugin side, there is something wrong with it producing infinite loop.


#6

I’m not using inline templates. It was just to try to debug the problem.

The infinite loop has something to do with focus and the use of the v-click-outside directive. What’s throwing me off is that it works fine in 3 scenarios, and breaks in 1 scenario. The 3 scenarios it works fine in are: (1) vue without f7; (2) f7-vue using inline templates; and (3) f7-vue and programatically adding the component in the mounted event of the parent.

That’s why I was just wondering if there’s any rendering or focusing magic you’re aware of in the f7 routed pages?


#7

Well, there is no really any rendering magic, at least from what i see nothing should break the rendering logic.

There is still something wrong with plugin for sure, if i register it globally, issue will gone:

import VuePhoneNumberInput from 'vue-phone-number-input'
Vue.component('vue-phone-number-input', VuePhoneNumberInput)

#8

Thanks @nolimits4web. I also tried global registration, and it works fine. It’s so strange. Why would it make a difference?


#9

This better to ask to that plugin developer :slight_smile: