Vue 2.0 - Computed issue - vuejs2

When on click start method "increment" variable "clicks" change but why it not change "counter". It should be because i have in counter function reference to "clicks" variable.
new Vue({
el: '#app',
data: {
title: 'helloworld',
cssClass: '',
clicks: 0,
counter: 0
},
methods: {
changeTitle() {
this.title = 'helloworld new';
},
increment() {
this.clicks++;
}
},
computed: {
counter() {
return this.clicks * 2;
}
}
});
https://jsfiddle.net/freeq343/b7fyeyxm/

Don't define counter on your data. The computed value acts like a data property.
new Vue({
el: '#app',
data: {
title: 'helloworld',
cssClass: '',
clicks: 0
},
methods: {
changeTitle() {
this.title = 'helloworld new';
},
increment() {
this.clicks++;
}
},
computed: {
counter() {
return this.clicks * 2;
}
}
});

Related

Data not being passed from Child Data to Parent Props

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
}

Map array inside computed property

So I wanted to see if I can get some guidance from the community if there is a better way to approach this:
So I have the following vue.js app:
new Vue({
name: 'o365-edit-modal-wrapper',
el: '#o365-modal-edit-wrapper',
data: function() {
const default_apps = [
{
'post_title': 'Excel',
}, {
'post_title': 'Word',
}, {
'post_title': 'SharePoint',
}];
return {
available_list: [],
selected_list: default_apps.map(function(name, index) {
return { name: name.post_title, order: index + 1, fixed: false };
}),
}
},
computed: {
dragOptions() {
// Pass in additional <draggable> options inside the return for both lists.
return {
tag: 'div',
group: 'o365apps',
disabled: !this.editable,
ghostClass: "ghost",
};
},
},
});
The selected_list returns the following items:
I was told that it's bad practice to do array mapping inside the data return, but to instead map inside the computed call - Could someone lead me in the right direction and just see if my code makes sense?
I tried defining an empty array as shown below:
return {
available_list: [],
selected_list:[],
}
& then inside the computed property, I tried accessing it using the following return but wasn't getting any data back:
selected_list() {
return this.default_apps.map(function(name, index) {
return { name: name.post_title, order: index + 1, fixed: false };
});
},
All help is appreciated - Thanks a bunch!
your are almost there except for a few details:
It's ok to map data inside data as long as you put them inside the return object literal data() { return { default_apps: [] } }.
Once default_apps is inside the return object of data, you can access the data inside of it from a computed property using the this keyword: this.default_apps.map()...
new Vue({
name: 'o365-edit-modal-wrapper',
el: '#o365-modal-edit-wrapper',
data: function() {
return {
default_apps: [
{ post_title: 'Excel' },
{ post_title: 'Word' },
{ post_title: 'SharePoint'}
],
available_list: [],
}
},
computed: {
selected_list() {
return this.default_apps.map(function(name, index) {
return { name: name.post_title, order: index + 1, fixed: false };
});
},
dragOptions() {
// Pass in additional <draggable> options inside the return for both lists.
return {
tag: 'div',
group: 'o365apps',
disabled: !this.editable,
ghostClass: "ghost",
};
},
},
});

Get params of route Shopware 6

I try to extend the product detail page and get the productId out of the routes.
Shopware.Module.register('sw-product-content-element', {
routeMiddleware(next, currentRoute) {
if (currentRoute.name === 'sw.product.detail') {
currentRoute.children.push({
name: 'sw.product.detail.content-element',
path: '/sw/product/detail/:id/content-element',
component: 'sw-product-detail-content-element',
meta: {
parentPath: "sw.product.index"
},
props: {
default(route) {
console.log(route)
return {
productId: route.params.id
};
}
}
});
}
next(currentRoute);
}
});
I try to pass my productId as props to my component, but in my component productId is undefined.
Component.register('sw-product-detail-content-element', {
template,
props: {
productId: {
required: true,
type: String
},
},
data() {
return {
product: null
};
},
created() {
console.log(this.productId)
},
....
I found a solution. I do not need to pass my value as props, I can just use this.$route.params.id
Component.register('sw-product-detail-content-element', {
template,
props: {
productId: {
required: true,
type: String
},
},
data() {
return {
product: null
};
},
created() {
this.productId = this.$route.params.id
console.log(this.productId)
},
....

Vue-Apollo - can't access result of query

i can't access the result object of my apollo query. I want to use the result to show it in a plot.ly graph.
const apolloClient = new Apollo.lib.ApolloClient({
networkInterface: Apollo.lib.createNetworkInterface({
uri: '{% url 'graphql' %}',
transportBatching: true,
}),
connectToDevTools: true,
})
const apolloProvider = new VueApollo.ApolloProvider({
defaultClient: apolloClient,
})
const VALUE_QUERY = Apollo.gql`
query {
allSensordata {
id
value
}
}
`
This is just the Vue Component for using with plot.ly.
//VueJS Component
Vue.component("reactive-chart", {
props: ["chart"],
template: '<div :ref="chart.uuid" style="width:600px;height:250px;"></div>',
mounted() {
Plotly.plot(this.$refs[this.chart.uuid], this.chart.traces, this.chart.layout);
},
watch: {
chart: {
handler: function() {
Plotly.react(
this.$refs[this.chart.uuid],
this.chart.traces,
this.chart.layout
);
},
deep: true
}
}
});
Here is the Vue Main Code where i want to bring the apollo graphql result to the graph.
//VueJS Main App
var app = new Vue({
delimiters: ['[[', ']]'],
el: "#app",
// Apollo GraphQL
apolloProvider,
apollo: {
allSensordata: {
query: VALUE_QUERY,
loadingKey:'loading',
},
},
data() {
return {
loading: 0,
chart: {
uuid: "123",
traces: [
{
y: [1,2,3,4,3,2,1], //Here should be: this.allSensordata.value
line: {
color: "#5e9e7e",
width: 4,
shape: "line"
}
}
],
layout: {}
}
};
},
});
I think i didn't get the object structure of the Apollo-module. Thanks for your help!

Using Select2 (multiple selections) with vue.js

I'm new to vue and have followed their 'custom directive' at http://vuejs.org/examples/select2.html.
This works well when only selecting one item, but when you're selecting multiple items it only passes the first one. I need it to pass all values selected.
I have a jsfiddle set up displaying the code which is available here.
https://jsfiddle.net/f3kd6f14/1/
The directive is as below;
Vue.directive('select', {
twoWay: true,
priority: 1000,
params: ['options'],
bind: function() {
var self = this
$(this.el)
.select2({
data: this.params.options
})
.on('change', function() {
self.set(this.value)
})
},
update: function(value) {
$(this.el).val(value).trigger('change')
},
unbind: function() {
$(this.el).off().select2('destroy')
}
Any help would be appreciated.
this.value doesn't work like you expect when Select2 is in multiple value mode (more info here: Get Selected value from Multi-Value Select Boxes by jquery-select2?).
Try this (working fiddle here: https://jsfiddle.net/02rafh8p/):
Vue.directive('select', {
twoWay: true,
priority: 1000,
params: ['options'],
bind: function() {
var self = this
$(this.el)
.select2({
data: this.params.options
})
.on('change', function() {
self.set($(self.el).val()) // Don't use this.value
})
},
update: function(value) {
$(this.el).val(value).trigger('change')
},
unbind: function() {
$(this.el).off().select2('destroy')
}
})
var vm = new Vue({
el: '#el',
data: {
selected: [], // Result is an array of values.
roles : [
{ id: 1, text: 'hello' },
{ id: 2, text: 'what' }
]
}
})
In Vue 2, to get all select2 values onchange:
Change this:
.on('change', function () {
self.$emit('input', this.value); // Don't use this.value
});
To this:
.on('change', function () {
self.$emit('input', $(this).val());
});