通过Vue.extend或通过" new Vue()"创建组件时的不同行为:如果通过新Vue创建,则无法访问视图模型的数据和方法

时间:2017-03-18 15:27:53

标签: vue.js vuejs2 vue-component

我有一个简单的组件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 个答案:

答案 0 :(得分:1)

您必须先注册自定义组件。有两种方法可以做到:

  • 通过全球注册:

    // 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文档state that

      

    注册后,组件可以作为自定义元素在实例的模板中使用[...]确保在实例化根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完整,并且只测试组件的功能。

答案 1 :(得分:0)

好的,我找到了解决方案。 为了获得最后2个期望:

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

回想起来,非常明显,因为我们在div中添加了组件。