Различное поведение, когда компонент создается через Vue.extend или через новый Vue(): данные и методы модели представления недоступны, если они созданы через новый Vue.

У меня есть простой компонент Hello:

<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
  </div>
</template>

<script>
export default {
  name: 'hello',
  props: {'myprop': String},
  data () {
    return {
      msg: 'Welcome ' + this.myprop
    }
  },
  methods: {
    mymethod: function () {
      return 'hi there'
    }
  }
}
</script>

Теперь, в зависимости от того, как создан компонент, будут доступны методы и данные. Проще всего проиллюстрировать это с помощью теста, пожалуйста, прочитайте комментарии к тесту:

import Vue from 'vue'
import Hello from '@/components/Hello'

describe('Hello.vue', () => {
  it('with Vue Extend', () => {
    const Constructor = Vue.extend(Hello)
    const vm = new Constructor({ propsData: { myprop: 'from test via propsdata' } }).$mount()
    // following 3 expections will all SUCCEED
    expect(vm.$el.querySelector('.hello h1').textContent)
      .to.equal('Welcome from test via propsdata')
    expect(vm.myprop).to.equal('from test via propsdata')
    expect(vm.mymethod()).to.equal('hi there')
  })

  it('with new Vue', () => {
    const vm = new Vue(
      {
        template: "<div><hello myprop='from template in test'></hello></div>",
        components: { 'hello': Hello }
      }).$mount()
    // following expectation SUCCEDS
    expect(vm.$el.querySelector('.hello h1').textContent)
      .to.equal('Welcome from template in test')
    // following TWO expections will FAIL
    expect(vm.mymethod()).to.equal('hi there')
    expect(vm.myprop).to.equal('from template in test')
  })
})

Как я могу заставить работать последние 2 ожидания?

Спасибо.


person paul van bladel    schedule 18.03.2017    source источник


Ответы (2)


Сначала вы должны зарегистрировать свой пользовательский компонент. Есть два способа сделать это:

  • С глобальной регистрацией:

    // register
    Vue.component('hello', {
        template: "<div><hello myprop='from template in test'></hello></div>",
        // ...
    });
    
    // create your root instance
    const vm = new Vue({
        el: '#root' // assume root eventually renders the 'hello' component
    });
    

    В документах Vue.js указано, что:

    После регистрации компонент можно использовать в шаблоне экземпляра в качестве пользовательского элемента. [] Убедитесь, что компонент зарегистрирован перед созданием экземпляра корневого экземпляра Vue.

  • Через местную регистрацию:

    // declare
    var hello = {
        template: "<div><hello myprop='from template in test'></hello></div>",
        // ...
    };
    
    // create your root instance, registering everything in 'components'
    const vm = new Vue({
        components: { 'hello': Hello }
    });
    

В вашем случае первое кажется более подходящим, так как вы хотите сохранить SOC в целости и просто проверить функциональность компонента.

person Eliran Malka    schedule 19.03.2017
comment
Извините, что такое СОК? - person paul van bladel; 20.03.2017
comment
Не могли бы вы предоставить полный код для теста 2 таким образом, чтобы последние 2 ожидания сработали. не вижу :( - person paul van bladel; 20.03.2017
comment
Следующие ожидания терпят неудачу в тесте 2: expect(vm.mymethod()).to.equal('привет!) - person paul van bladel; 20.03.2017
comment
Я хочу сказать, что в ТЕСТЕ 2 первое ожидание УСПЕШНО, поэтому я предполагаю, что компонент смонтирован правильно, не так ли? Только в тесте 2 ожидание 2 и 3 терпят неудачу по неочевидным причинам. - person paul van bladel; 20.03.2017
comment
я честно не знаю. вам придется отладить свой код и/или опубликовать некоторые ошибки, чтобы мы знали, что не работает. - person Eliran Malka; 21.03.2017

Хорошо, я нашел решение. Чтобы получить последние 2 ожидания в порядке:

expect(vm.$children[0].mymethod()).to.equal('hi there')
expect(vm.$children[0].myprop).to.equal('from template in test')

Оглядываясь назад, это вполне очевидно, так как мы добавляем компонент в div.

person paul van bladel    schedule 24.03.2017