Vue.js property undefined? - javascript

I've use this in my main component:
<contacts :corporation="corporation"></contacts>
contacts component:
export default {
props: {
corporation: {
default: () => []
}
},
data () {
return {
contacts: []
}
},
created() {
this.fetchContacts();
},
methods: {
fetchContacts() {
console.log(this.corporation.slug); // undefined!
CorporationService.users(this.corporation.slug)
.then(({data}) => {
this.contacts = data.contacts;
});
}
}
}
I'm trying to fetch contacts in the contacts component. The problem is that if I console.log(this.corporation.slug);in the method fetchContacts(); the corporation.slug is undefined!
But when I look into vue devtools the corporation prop is being set properly!
What could be going on? Already tried to change:
created() {
this.fetchContacts();
}
to
mounted() {
this.fetchContacts();
}
But that's not working.

Can you use a watch?
Something like this.
watch: {
'corporation.slug': function(slug) {
if(slug){
this.fetchContacts();
}
}
}
Now if parent component changes corporation.slug your child component will fetch contacts automatically.

Your prop default value is whether a value, or a function. But if it is a function, it HAS TO return something:
props: {
corporation: {
default () {
return []
}
}
},

Related

Vue check if "v-model.number" (Modifier) is being used

There is a way to know when it is being used v-model.number?
<component v-model.number="value" />
component.vue
...
onMounted(() => {
if (props.modelValue.isUsingModifierNumber()){
console.log('Yes')
}
})
...
In Vue 3, v-model modifiers are passed as a modelModifiers prop - see the docs
define a prop on your component
props: {
modelValue: Number,
modelModifiers: {
type: Object,
default: () => ({})
}
}
Test
created() {
if(this.modelModifiers.number)
{
// ....
}
}

Vue 3 Render Function how to set up v-model and onClicks

Does anybody here have experience with Vue 3 Render Function? I don't know how to set up the v-model and on clicks, the documentation on Vue 3 somewhat kinda useless and lacks practical usage examples.
Maybe someone has a sample code?
If you want to emulate the v-model directive in the render function try something like :
h('input', {
value: this.test,
onInput:(e)=> {
this.test = e.target.value
}
})
which is equivalent to <input v-model="test" />
const {
createApp,
h
} = Vue;
const App = {
data() {
return {
test: "Test"
}
},
render() {
return h('div', {}, [h('input', {
value: this.test,
onInput:(e)=> {
this.test = e.target.value
}
}),h("h4",this.test)])
}
}
const app = createApp(App)
app.mount('#app')
<script src="https://unpkg.com/vue#3.0.0-rc.11/dist/vue.global.prod.js"></script>
<div id="app">
</div>
#Boussadjra Brahim
render() {
self = this; // Added this
return h('div', {}, h('input', {
value: this.test,
onInput(e) {
self.test = e.target.value // Change this.test to self.test
}
}))
}
Thank you for this, I don't know why onKeyUp didn't work but onInput did.

Enzyme shallow() and addEventListener

I have this component, which works fine in the application:
class TheComponent extends Component {
componentDidMount() {
this.watchForClicks();
}
watchForClicks() {
this.elementRef.addEventListener('click', () => {
console.log('there went one!');
});
}
render() {
return (
<div
ref={theElement => {
this.elementRef = theElement;
}}
>
...
</div>
);
}
}
export default TheComponent;
And this test:
describe('<TheComponent />', () => {
context('do a test:', function() {
it.only('fails!', () => {
wrapper = shallow(<TheElement />)
})
});
});
Why do I get this error?
undefined is not an object (evaluating 'this.elementRef.addEventListener')
As you can see in the docs, the ShallowWrapper API doesn't have a ref() method, but you can use mount() instead, which does have the ref() method.

Vue binding parent and child components

How to binding parent's model to child in Vue.js?
These codes below is works fine. if i fill the input manually, then child's model return it's value to the parent's model.
But the issue is, if the data set from AJAX request in a parent, the input doesn't automatically filled.
Can anyone help me on this?
Form.vue
<template>
<form-input v-model="o.name" :fieldModel="o.name" #listenChanges="o.name = $event"/>
<form-input v-model="o.address" :fieldModel="o.address" #listenChanges="o.address = $event"/>
</template>
<script>
import FormInput from '../share/FormInput.vue'
export default {
data () {
return {
o: {
name: '',
address: ''
}
}
},
components: { 'form-input': FormInput },
created: function() {
axios.get('http://api.example.com')
.then(response => {
this.o.name = response.data.name
this.o.address = response.data.address
})
.catch(e => { console.log(e) })
}
}
</script>
FormInput.vue
<template>
<input type="text" v-model='fieldModelValue' #input="forceUpper($event, fieldModel)">
</template>
<script>
export default {
props: ['fieldModel'],
data() {
return {
fieldModelValue: ''
}
},
mounted: function() {
this.fieldModelValue = this.fieldModel;
},
methods: {
forceUpper(e, m) {
const start = e.target.selectionStart;
e.target.value = e.target.value.toUpperCase();
this.fieldModelValue = e.target.value.toUpperCase();
this.$emit('listenChanges', this.fieldModelValue)
}
}
}
</script>
Things are more straightforward if you take advantage of v-model in components.
If you put v-model on a component, the component should take a prop named value, and should emit input events to trigger it to update.
I like to make a computed to hide the event emitting, and allow me to just v-model the computed inside my component.
new Vue({
el: '#app',
data: {
o: {
name: '',
address: ''
}
},
components: {
'form-input': {
template: '#form-input',
props: ['value'],
computed: {
fieldModelValue: {
get() {
return this.value;
},
set(newValue) {
this.$emit('input', newValue.toUpperCase());
}
}
}
}
},
// Simulate axios call
created: function() {
setTimeout(() => {
this.o.name = 'the name';
this.o.address = 'and address';
}, 500);
}
});
<script src="//unpkg.com/vue#latest/dist/vue.js"></script>
<div id="app">
Name ({{o.name}})
<form-input v-model="o.name"></form-input>
Address ({{o.address}})
<form-input v-model="o.address"></form-input>
</div>
<template id="form-input">
<input type="text" v-model='fieldModelValue'>
</template>
The mounted() hook is blocking subsequent updates from the parent.
Remove mounted and change v-model to 'fieldModel'
<template>
<input type="text" :value='fieldModel' #input="forceUpper($event, fieldModel)">
</template>
<script>
export default {
props: ['fieldModel'],
data() {
return {
fieldModelValue: ''
}
},
// mounted: function() {
// this.fieldModelValue = this.fieldModel;
// },
methods: {
forceUpper(e, m) {
const start = e.target.selectionStart;
e.target.value = e.target.value.toUpperCase();
this.fieldModelValue = e.target.value.toUpperCase();
this.$emit('listenChanges', this.fieldModelValue)
}
}
}
</script>
Demo CodeSandbox

2 way-binding with a nested property inside object. (VueJS + VueX)

I'm currently doing the below:
<script>
export default {
computed: {
editingItem: {
get() {
return this.$store.getters['editing/editingItem'];
},
set(newValue) {
this.$store.commit('editing/UPDATE_EDITING', newValue);
}
},
editingItemName: {
get() {
return this.editingItem.name;
},
set(newValue) {
this.editingItem.name = newValue;
this.editingItem = this.editingItem;
}
}
},
}
</script>
Am I over complicating it? The second line on the editingItemName set(), is a workaround to make the editingItem set() function trigger.
Check this article. it's about forms, but it shows the way to achieve to 2-way binding with vuex.
regarding your special case, see the code. telephone is a nested property inside an object.
myModule.js
const myModule = {
state: {
customerInfo: {
name: '',
telephone: ''
}
},
getters: {
getTelephone(state) {
return state.customerInfo.telephone
}
},
mutations: {
setTelephone(state, payload) {
state.customerInfo.telephone += payload
},
}
}
export default myModule;
form.vue
<template>
<div>
<input v-model="telephone"></input>
</div>
</template>
<script>
export default {
computed: {
telephone: {
get() {
return this.$store.getters['getTelephone']
},
set(value) {
this.$store.commit('setTelephone', value)
}
},
}
}
</script>

Categories

Resources