Vue.js ( w Avoriaz) 从子组件抛出时如何捕获父组件中的错误
Vue.js ( w Avoriaz) How to catch error in parent component when thrown from child component
用空输入值测试子组件,抛出错误,但没有在父组件中捕获
错误:未捕获错误:没有文本的新项目
我怎样才能抓住它?在哪里?
感谢反馈
父组件
ShoppingListComponent.vue
<template>
<div>
<h2>{{ title }}</h2>
<add-item-component :id='id' @add="addItem"></add-item-component>
<items-component :items="items" :id="id"></items-component>
</div>
</template>
<script>
import AddItemComponent from './AddItemComponent'
import ItemsComponent from './ItemsComponent'
export default {
components: {
AddItemComponent,
ItemsComponent
},
props: ['id', 'title', 'items'],
methods: {
addItem (text) {
console.log('SHOPLIST addItem:', text)
if (text.length > 0) {
this.items.push({
text: text,
checked: false
})
}
}
}
}
</script>
子组件
AddItemComponent.vue
<template>
<div class="input-group">
<input type="text" @keyup.enter="addItem" v-model="newItem" placeholder="add shopping list item" class="form-control">
<span class="input-group-btn">
<button @click="addItem" class="btn btn-default" type="button">Add!</button>
</span>
</div>
</template>
<script>
export default {
props: ['id'],
data () {
return {
newItem: ''
}
},
methods: {
addItem () {. // see @keyup.enter in this template
var text
text = this.newItem.trim()
if (text.length > 0) {
this.$emit('add', this.newItem). // see @add in parent template
this.newItem = ''
this.$store.dispatch('updateList', this.id)
} else {
console.log('ERROR EMPTY TEXT'). // debugging
throw new Error('New Item without a text')
}
}
}
}
</script>
单元测试
AddItemComponent.spec.js
import Vue from 'vue'
import AddItemComponent from '@/components/AddItemComponent'
import Vuex from 'vuex'
import sinon from 'sinon'
import { mount } from 'avoriaz'
Vue.use(Vuex)
describe('AddItemComponent.vue', () => {
let actions
let store
let wrapper
describe('add New Item', () => {
beforeEach(() => {
actions = {
actionClick: sinon.stub(),
addItem: sinon.stub()
}
store = new Vuex.Store({
state: {},
actions
})
wrapper = mount(AddItemComponent, { store })
sinon.stub(wrapper.vm, '$emit')
sinon.stub(store, 'dispatch')
})
it('should throw an error when input value is null and an input event is fired', () => {
const input = wrapper.find('input')[0]
wrapper.setProps({ id: 'niceId' })
wrapper.setData({ newItem: '' })
wrapper.setProps({ items: [] })
input.trigger('keyup.enter')
expect(() => {
wrapper.vm.addItem()
}).to.throw('New Item without a text')
})
})
})
主机单元测试
LOG LOG: 'ERROR EMPTY TEXT'
AddItemComponent.vue
add New Item
✗ should throw an error when input value is null and an input event is fired
Error: Uncaught Error: New Item without a text (webpack:///src/components/AddItemComponent.vue:33:0 <- index.js:26197)
at Wrapper.trigger (webpack:///~/avoriaz/dist/avoriaz.js:597:0 <- index.js:16436:16)
at Context.<anonymous> (webpack:///test/unit/specs/components/AddItemComponent.spec.js:46:12 <- index.js:25368:13)
Vue 提供了一种在其配置中定义全局错误处理程序的方法:
Vue.config.errorHandler = function (err, vm, info) {
// Do stuff with error
}
您可以在此处查看实际效果:https://jsfiddle.net/ydx7q4m3/
用空输入值测试子组件,抛出错误,但没有在父组件中捕获 错误:未捕获错误:没有文本的新项目
我怎样才能抓住它?在哪里? 感谢反馈
父组件 ShoppingListComponent.vue
<template>
<div>
<h2>{{ title }}</h2>
<add-item-component :id='id' @add="addItem"></add-item-component>
<items-component :items="items" :id="id"></items-component>
</div>
</template>
<script>
import AddItemComponent from './AddItemComponent'
import ItemsComponent from './ItemsComponent'
export default {
components: {
AddItemComponent,
ItemsComponent
},
props: ['id', 'title', 'items'],
methods: {
addItem (text) {
console.log('SHOPLIST addItem:', text)
if (text.length > 0) {
this.items.push({
text: text,
checked: false
})
}
}
}
}
</script>
子组件 AddItemComponent.vue
<template>
<div class="input-group">
<input type="text" @keyup.enter="addItem" v-model="newItem" placeholder="add shopping list item" class="form-control">
<span class="input-group-btn">
<button @click="addItem" class="btn btn-default" type="button">Add!</button>
</span>
</div>
</template>
<script>
export default {
props: ['id'],
data () {
return {
newItem: ''
}
},
methods: {
addItem () {. // see @keyup.enter in this template
var text
text = this.newItem.trim()
if (text.length > 0) {
this.$emit('add', this.newItem). // see @add in parent template
this.newItem = ''
this.$store.dispatch('updateList', this.id)
} else {
console.log('ERROR EMPTY TEXT'). // debugging
throw new Error('New Item without a text')
}
}
}
}
</script>
单元测试 AddItemComponent.spec.js
import Vue from 'vue'
import AddItemComponent from '@/components/AddItemComponent'
import Vuex from 'vuex'
import sinon from 'sinon'
import { mount } from 'avoriaz'
Vue.use(Vuex)
describe('AddItemComponent.vue', () => {
let actions
let store
let wrapper
describe('add New Item', () => {
beforeEach(() => {
actions = {
actionClick: sinon.stub(),
addItem: sinon.stub()
}
store = new Vuex.Store({
state: {},
actions
})
wrapper = mount(AddItemComponent, { store })
sinon.stub(wrapper.vm, '$emit')
sinon.stub(store, 'dispatch')
})
it('should throw an error when input value is null and an input event is fired', () => {
const input = wrapper.find('input')[0]
wrapper.setProps({ id: 'niceId' })
wrapper.setData({ newItem: '' })
wrapper.setProps({ items: [] })
input.trigger('keyup.enter')
expect(() => {
wrapper.vm.addItem()
}).to.throw('New Item without a text')
})
})
})
主机单元测试
LOG LOG: 'ERROR EMPTY TEXT'
AddItemComponent.vue
add New Item
✗ should throw an error when input value is null and an input event is fired
Error: Uncaught Error: New Item without a text (webpack:///src/components/AddItemComponent.vue:33:0 <- index.js:26197)
at Wrapper.trigger (webpack:///~/avoriaz/dist/avoriaz.js:597:0 <- index.js:16436:16)
at Context.<anonymous> (webpack:///test/unit/specs/components/AddItemComponent.spec.js:46:12 <- index.js:25368:13)
Vue 提供了一种在其配置中定义全局错误处理程序的方法:
Vue.config.errorHandler = function (err, vm, info) {
// Do stuff with error
}
您可以在此处查看实际效果:https://jsfiddle.net/ydx7q4m3/