通过 Vue.extend 或“new Vue()”创建组件时的不同行为:如果通过 new Vue 创建,则无法访问视图模型的数据和方法
Posted
技术标签:
【中文标题】通过 Vue.extend 或“new Vue()”创建组件时的不同行为:如果通过 new Vue 创建,则无法访问视图模型的数据和方法【英文标题】:Different behavior when component is created via Vue.extend or via "new Vue()": view-model's data and methods not accessible if created via new Vue 【发布时间】:2017-08-10 02:44:03 【问题描述】:我有一个简单的组件你好:
<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>
现在,根据组件的创建方式,可以访问方法和数据。最简单的说明方法是通过测试,请阅读测试中的 cmets:
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 个期望起作用?
谢谢。
【问题讨论】:
【参考方案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 完整,并且只测试组件的功能。
【讨论】:
对不起,SOC是什么? 您能否以这样的方式提供测试 2 的完整代码,以使最后 2 个期望成功。我没看到:( 以下预期在测试 2 中失败:expect(vm.mymethod()).to.equal('hi there') expect(vm.myprop).to.equal('from template in test' ) 我的意思是,在 TEST 2 中,第一个期望成功,所以我假设组件安装正确,不是吗?仅在测试 2 中,期望 2 和 3 因不明原因而失败。 我真的不知道。您将不得不调试您的代码和/或发布一些错误,以便我们知道什么不起作用。【参考方案2】:好的,我找到了解决方案。 要确定最后 2 个期望:
expect(vm.$children[0].mymethod()).to.equal('hi there')
expect(vm.$children[0].myprop).to.equal('from template in test')
回想起来,很明显,因为我们在 div 中添加了组件。
【讨论】:
以上是关于通过 Vue.extend 或“new Vue()”创建组件时的不同行为:如果通过 new Vue 创建,则无法访问视图模型的数据和方法的主要内容,如果未能解决你的问题,请参考以下文章
new Vue/Vue.Component/Vue.extend的区别