I think im not understanding something properly or is an obvious oversight but I cant access values returned from my data() function in my Vue component's computed properties. From my below code i am trying to return a computed property newmessage but it is saying that message is undefined and so is everything else in data if i try. Appreciate any help :)
<script>
export default {
props:['alertdata'],
data () {
return {
message: 'hello',
expanded: [],
singleExpand: false,
alertHeaders: [
{
text: 'Rule Number',
align: 'start',
sortable: false,
value: 'RuleNumber',
},
{ text: 'Date', value: 'DateCreated' },
{ text: 'Amount', value: 'Amount' },
],
alerts: this.alertdata,
transactions : this.alertdata.detail,
}
},
computed: {
newmessage : function() {
return message.reverse()
}
}
}
</script>
Typically, inside methods, or computed properties or lifecycle handlers in Vue, you will use this to refer the component to which the method/computed/handler is attached. this refers to the context in which the function is currently executing.
in your case you need to add this before message
computed: {
newmessage : function() {
return this.message.reverse()
}
You need to refer to property defined in data with this keyword:
newmessage : function() {
return this.message.reverse()
}
Related
This question already has an answer here:
VueJS | Method "watch" has type "object" in the component definition
(1 answer)
Closed 1 year ago.
I'm building a Dropdown Component, and Vue is throwing me the following error:
Method "watch" has type "object" in the component definition. Did you reference the function correctly?
watch: {
selected: function (val) {
console.log("value changed", val);
},
}
I've done some research but I can't figure out how to correctly resolve this error, as it appears correct to me, let me know if I should attach some more relevant code. I'll attach my full methods below:
methods: {
updateSelectedValue: function (newValue) {
this.selected = newValue;
},
addParam() {
this.addFormFields(['params'], {
slug: '',
name: '',
isRequired: true,
description: '',
typeSlug: '',
});
},
deleteParam(idx){
this.removeFormFields(['params', idx]);
},
restoreParam(idx){
this.restoreFormFields(['params', idx])
},
$newObject() {
return {
slug: '',
name: '',
isAbstract: false,
requester: '',
description: '',
status: 'inactive',
params: [],
selected: '',
};
},
$extraPrams() {
return {
parentId: this.parentId,
};
},
watch: {
selected: function (val) {
console.log("value changed", val);
},
}
},
};
it seems that you put watch in methods. it should be out of methods
I have a Request Form Component, and within this request form Component I have a Dropdown Menu Component, which I will link both below. All values in my table are pushed into an object upon hitting the Submit Button. However my dropdown selection is only being picked up by my console.log and not being pushed into the Object.
I'm not so familiar with Vue, so I'm not sure what direction to go in for fixing this. I'll attach the relevant (?) pieces of code below.
Parent Component:
<SelectComponent :selected="this.selected" #change="updateSelectedValue" />
export default {
fullScreen: true,
name: 'CcRequestForm',
mixins: [BaseForm],
name: "App",
components: {
SelectComponent,
},
data() {
return {
selected: "A",
};
},
props: {
modelName: {
default: 'CcRequest',
},
parentId: {
type: Number,
default: null,
},
},
mounted() {
this.formFields.requester.value = this.currentRequesterSlug;
},
destroyed() {
if (!this.modelId) return;
let request = this.currentCcRequest;
request.params = request.params.filter(p => p.id)
},
computed: {
...mapGetters(['ccTypesForRequests', 'currentRequesterSlug', 'currentCcRequest']),
ccTypesCollection() {
return this.ccTypesForRequests.map((x)=>[x.slug, this.t(`cc_types.${x.slug}`)]);
}
},
methods: {
addParam() {
this.addFormFields(['params'], {
slug: '',
name: '',
isRequired: true,
description: '',
typeSlug: '',
selected: ''
});
},
deleteParam(idx){
this.removeFormFields(['params', idx]);
},
restoreParam(idx){
this.restoreFormFields(['params', idx])
},
$newObject() {
return {
slug: '',
name: '',
isAbstract: false,
requester: '',
description: '',
status: 'inactive',
params: [],
selected: ''
};
},
$extraPrams() {
return {
parentId: this.parentId,
};
},
updateSelectedValue: function (newValue) {
this.selected = newValue;
},
},
watch: {
selected: function (val) {
console.log("value changed", val);
},
},
};
Child Component:
<script>
export default {
name: "SelectComponent",
props: {
selected: String,
},
computed: {
mutableItem: {
get: function () {
return this.selected;
},
set: function (newValue) {
this.$emit("change", newValue);
},
},
},
};
You have to define the emit property in the parent component, or else it won't know what to expect. That would look like:
<SelectComponent :selected="this.selected" #update-selected-value="updateSelectedValue" />
Check out this tutorial for more information: https://www.telerik.com/blogs/how-to-emit-data-in-vue-beyond-the-vuejs-documentation
To update selected property inside the object, in this constellation, you need to update object property manually upon receiving an event, inside of updateSelectedValue method. Other way could be creating a computed property, since it's reactive, wrapping "selected" property.
computed: {
selectedValue () {
return this.selected
}
}
And inside of object, use selectedValue instead of selected:
return {
...
selected: selectedValue
}
I am having a weird issue with Vuetify data table. I have two files that are relevant:
The parent:
<!-- DataTable component with articles and headers passed as props -->
<ArticleTable :propData="articles" :headers="headers"></ArticleTable>
<script>
//Add data
data() {
return {
//For the article list from the server
articles: null,
//Headers for Datatable
headers: [
{ text: "Article #", value: "articleID" },
{ text: "Title", value: "articleTitle" },
{ text: "Content", value: "articleContent" },
{ text: "Click to Like", value: "liked", sortable: false },
{ text: "Likes", value: "articleLikes" }
]
};
},
//When the component is first created, call method
created() {
this.getArticles();
},
//Methods
methods: {
getArticles() {
this.error = null;
//Sets parameters from external file
let url = serverDetails.url;
let params = { ...serverDetails.params };
//GET request for all articles
axios
.get(`${url}articles`, {
params
})
//On success save response in articles variable
.then(response => {
this.articles = response.data;
console.log("Articles found: ", response.data);
})
//Catch and display any errors
.catch(error => {
this.error = error.toString();
console.log("Error on retriving articles: " + error);
});
}
}
};
Which makes a request to my server and pulls back a list of articles. This is then passed to the child component:
<template>
<div>
<!-- Vuetify data table -->
<v-data-table
:items="propData"
:headers="headers"
:search="search"
:custom-filter="filter"
:key="renderKey"
>
</v-data-table>
<script>
"use strict";
export default {
name: "ArticleTable",
//Add props
props: {
propData: {
type: Array
},
headers: {
//Expects compulsory Array
type: Array,
required: true
}
},
//Add data
data() {
return {
//Render key
renderKey: 0,
};
},
</script>
(I have cut out as much irrelevant material as possible). However I am getting a weird problem with the data table, the console if throwing several errors, all roughly saying some version of:
[Vue warn]: Error in callback for immediate watcher "computedOptions": "TypeError: Cannot read property 'slice' of null"
and
TypeError: Cannot read property 'slice' of null
or
[Vue warn]: Error in getter for watcher "computedItems": "TypeError: Cannot read property 'slice' of null"
Before the table would not render at all but if I add
beforeUpdate() {
this.renderKey += 1;
},
to the child, forcing it to re render the table appears fine.
Is there any way to resolve those errors?
Thanks a million
Vuetify throw this error when the items array passed to datatable is undefined or null. A quick sollution is to set in your data the initial value of articles to [] instead of null.
data() {
return {
//For the article list from the server
articles: [], // this should always be an array, even if empty
//Headers for Datatable
headers: [
{ text: "Article #", value: "articleID" },
{ text: "Title", value: "articleTitle" },
{ text: "Content", value: "articleContent" },
{ text: "Click to Like", value: "liked", sortable: false },
{ text: "Likes", value: "articleLikes" }
]
};
},
I am getting this error in Vue v2.4.1. and I'm not sure what it means:
[Vue warn]: component option "computed" should be an object.
My code looks like this:
export default {
data() {
return {
bookings: [],
games: [],
slots: [],
startTime: {
time: moment().format("YYYY-MM-DD")
}
};
},
components: {
'date-picker': myDatepicker,
'reserved' : Reserved
},
ready() {
this.prepareComponent();
},
mounted() {
this.prepareComponent();
},
methods: {
prepareComponent() {
this.getGames();
this.getSlots();
this.getBookings(this.startTime.time);
},
onDateChange(){
},
formatSlot(slot){
},
getGames(){
},
getSlots() {
},
getBookings(date){
},
isReserved(gameId,slotId){
},
getReservedBooking(gameId,slotId){
},
isPastTime(time, date){
},
getUrl(date,slot_id,game_id){
}
}
}
You are getting this error because, somewhere in your project, you are defining a Vue component with the computed option set to something that is not an object.
Check your project for any instances where this is happening and replace the value of the computed option with an object.
Most likely, you have mistakenly written computed() { ... } instead of computed: { ... }.
Here is the basic example of a computed property from the documentation.
In My laravel + Spark + Vue js project, I have used https://github.com/Vanthink-UED/vue-core-image-upload, They have code like
export default {
props:{
cropBtn: {
type: Object,
default: function() {
return {
ok: '保存',
cancel: '取消',
}
}
}
}
As per their documentationm, If you want to change button text then do following
cropBtn Object {ok:'Save','cancel':'Give Up'} the text of crop
button
I have used like
<vue-core-image-upload
v-bind:class="['pure-button','pure-button-primary','js-btn-crop']"
v-bind:crop="true" url="/process-image"
extensions="png,gif,jpeg,jpg"
cropBtn="[{ok: 'Save',cancel: 'Cancel'}]"
v-on:imageuploaded="imageuploaded">
</vue-core-image-upload>
and
v-bind:cropBtn="items"
js file
module.exports = {
prop:['cropBtn'],
data() {
return {
items: [{
ok: 'Save',
cancel: 'Cancel',
}],
cropBtn: {
type: Object,
default: function() {
return {
ok: 'Save',
cancel: 'Cancel',
}
}
},
src: 'http://img1.vued.vanthink.cn/vued0a233185b6027244f9d43e653227439a.png'
};
}
};
But it is not working. I am getting same default Chinese value.
Any suggestions what can be the solution?
You need to use kebab-case when passing props that are declared in camel case and you must use v-bind or the shorthand : when passing javascript objects through props:
<vue-core-image-upload :crop-btn="{ok: 'Save',cancel: 'Cancel'}" ></vue-core-image-upload>
see: https://v2.vuejs.org/v2/guide/components.html#camelCase-vs-kebab-case