How to store Vue.js component data in Vuex? - vue.js

I'm building a link builder that lets people share multiple links from one link. At the moment I have several "cards" that users can put into their link template. For example, this allows them to have links to their music on Spotify (one card), or a link to their Youtube channel (another card).
I'm using VueDraggable to allow users to drag their cards into their template..
What I don't understand is, how should I store the cards components in the store so that they can be draggable? At the moment in my store I just have all of the cards as objects, as VueDraggable needs the data to be in 2 different lists..
export const state = () => ({
chosenCards: [
],
defaultCards: [
{id: 1, text: 'Twitter', font: 'Arial', destination: 'https://twitter.com/home', design: {color: '#1DA1F2', 'background-color': 'white', padding: '5px', margin: '5px', 'border-width' : '2px', 'border-color': '#1DA1F2', 'font-weight' : 600, font: 'Arial'}},
{id: 2, text: 'Spotify', font: 'Arial', destination: 'https://twitter.com/home', design: {color: '#1db954', 'background-color': 'white', padding: '5px', margin: '5px', 'border-width' : '2px', 'border-color': '#1db954', 'font-weight' : 600, font: 'Arial'}},
{id: 3, text: 'Youtube', font: 'Arial', destination: 'https://twitter.com/home', design: {color: '#c4302b', 'background-color': 'white', padding: '5px', margin: '5px', 'border-width' : '2px', 'border-color': '#c4302b', 'font-weight' : 600, font: 'Arial'}},
],
})
So I don't actually use any card components I've made. I want to be able to design the cards as components instead of just objects in my store, and still have them be draggable. How should I go about doing this?

Related

Cloudinary - add overlay text to thumbnailTransformation in image upload widget

I am using the upload image widget and I want to add a text overlay but don't know how, can someone answer me?
thumbnailTransformation: [{ width: 300, height: 300, crop: 'fill', border: "2px_solid_red" }],
You'll need to include an overlay key that's an object with overlay parameters, in this case, text specific.
For example -
thumbnailTransformation: [
{
width: 300,
height: 300,
crop: 'fill',
border: "2px_solid_red"
},
{
overlay: {
font_family: "Arial",
font_size: 20,
text: "Test"
},
gravity: "north_east"
}
]
Below is a JSFiddle you can try: https://jsfiddle.net/rhdvgy19/
All the other available text styling options can be found here -
https://cloudinary.com/documentation/image_transformations#styling_parameters

How do you apply a custom font when using Stripe in Vue? vue-stripe-elements-plus

I'm using the vue-stripe-elements-plus NPM module and I can't see how to add a custom font?
This plugin uses the options you pass in to the first element you create for creating the VUE elements.
It passes the style object to the style option when Stripe creates elements.
It passes the elements property to Stripe's elements function.
In here you can add a CustomFontSource object.
Please note, as in this example, if you want to use a Google font, you have to go to the URL provided and grab the URL within the #fontface descriptors. You would probably be better of hosting the font yourself as I fear these URLs may change over time.
stripeOptions: {
elements: {
fonts: [{
family: 'Lexend Deca',
src: 'url(https://fonts.gstatic.com/s/lexenddeca/v1/K2F1fZFYk-dHSE0UPPuwQ5qnJy_YZ2ON.woff2)',
unicodeRange: 'U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD',
style: 'normal',
weight: '400',
display: 'swap',
}],
},
style: {
base: {
color: 'red',
fontFamily: '"Lexend Deca", sans-serif',
fontSize: '18px',
fontWeight: '400',
fontSmoothing: 'antialiased',
},
},
},
Stripe components:
<card-number
:stripe="stripeId"
:options="stripeOptions"
/>
<card-expiry
:stripe="stripeId"
:options="stripeOptions"
/>
<card-cvc
:stripe="stripeId"
:options="stripeOptions"
/>

How to set dynamic styles in Vue.js component from Vuex store

I'm trying to set an array of components styles directly from the store, so that when the store changes, the design of each component changes too.
I store a set of links in my Vuex store like this:
links: [
{id: 1, text: 'Banana is a test', design: {color: 'red', 'background-color': 'blue', padding: '51px', margin: '5px', 'border-width' : '10px', 'border-color': 'blue', 'font-weight' : 600, font: 'Arial'}},
{id: 2, text: 'This is a test', design: {color: 'red', 'background-color': 'blue', padding: '20px', margin: '10px', 'border-width' : '10px', 'border-color': 'green', 'font-weight' : 600, font: 'Arial'}},
{id: 3, text: 'Monkey is a test', design: {color: 'red', 'background-color': 'blue', padding: '5px', margin: '5px', 'border-width' : '10px', 'border-color': 'green', 'font-weight' : 600, font: 'Arial'}},
]
and this is how I try to render them
<a v-for="link in links" :key=link.id :href="link.destination" :id=link.id :style="link.design">
{{link.text}}
</a>
the trouble is, when the design objects changes in the Vuex store, the links styles are not subsequently updated as I would expect.
In my Vue component I've tried getting the links in different ways, assuming this would change the reactivity. Currently I get them using a computed method like so:
computed: {
getLinks: function() {
return this.$store.state.links
}
},
but whenever I change the value of a background-color, say from 'blue' to 'red', I have to reload the page to see the change. Do I need to force a rerender of the page everytime I call my mutation?
This is my mutation for reference:
setSelectedItemDesign (state, payload ) {
state.selectedItem.design[Object.keys(payload)[0]] = Object.values(payload)[0]
}
and I'd call it from my component like this:
this.$store.commit('setSelectedItemDesign', {'background-color' : this.rgbaValue})
Thats because you read value from store directly here return this.$store.state.links. This way it is not reactive and also anitpattern, because you should not access store like that.
You should create getter to get value and then it should be ok.
The problem was that I was not updating the array in my store in a way that Vue observes to trigger a view update, as nada correctly pointed out.
You can see here for more details: vuejs.org/v2/guide/list.html#Array-Change-Detection

Axios not loading data to vue

I am trying to load cytoscape graph using vue and axios. Anyway cant configure cytoscape so I tried first with axios and vue only. There is still problem with scope, but I can't figure where? What should I change? How to properly set vue and axios.
EDIT
So after setting this.nodes i would like to draw a grapg in cytoscape.js , but I always get errors:
-The style property text-outline-color: is invalid
-Do not assign mappings to elements without corresponding data (e.g. ele 6b899f09-359e-424d-9461-d71c8c3fcd3b for property text-outline-color with data field faveColor); try a [faveColor] selector to limit scope to elements with faveColor defined
-Uncaught TypeError: Cannot set property 'mapping' of null
I believe it is array problem, but I can't figure out how to set array properly so this can work.
Here is code:
draw: function(){
this.cy = cytoscape({
container: document.getElementById('cy'),
layout: {
name: this.main_layout,
padding: 10
},
style: cytoscape.stylesheet()
.selector('node')
.css({
'shape': 'data(faveShape)',
'width': 'mapData(weight, 40, 80, 20, 60)',
'content': 'data(name)',
'text-valign': 'center',
'text-outline-width': 2,
'text-outline-color': 'data(faveColor)',
'background-color': 'data(faveColor)',
'color': '#fff'
})
.selector(':selected')
.css({
'border-width': 3,
'border-color': '#333'
})
.selector('edge')
.css({
'curve-style': 'bezier',
'opacity': 0.666,
'width': 'mapData(strength, 70, 100, 2, 6)',
'target-arrow-shape': 'triangle',
'source-arrow-shape': 'circle',
'line-color': 'data(faveColor)',
'source-arrow-color': 'data(faveColor)',
'target-arrow-color': 'data(faveColor)'
})
.selector('edge.questionable')
.css({
'line-style': 'dotted',
'target-arrow-shape': 'diamond'
})
.selector('.faded')
.css({
'opacity': 0.25,
'text-opacity': 0
}),
elements: {
nodes: this.nodes
},
ready: function(){
window.cy = this;
}
});
I assume that response.data is an array or object ans vm.projekt with null there is no vue-getter registred. So please try to do
Vue.set(vm, 'projekt', response.data) there is also a $set in every vue instance (this)
instead of
vm.projekt = response.data
In general i would advise you to push ajax-datas into reactive arrays, that works very well.

Google Visualization API customization

I'm making a website for school that involves a bunch of Google Visualizations. I can get them to work with the data I want, but I'm stuck customizing them. I have a very specific design I must follow, and it's not really working out at the moment.
The reason is that I don't know how to have two different styles on one element. For example :
legend: {textStyle: {color: '#d1dbbd', fontName: 'Century Gothic', fontSize: 15}},
legend: {position: 'bottom'},
This currently only positions the legend at the bottom. I'm trying to get these two in one line, but I don't know the proper syntax of the language (I've tried to find it online but to no avail. :( )
I've shuffled it around a few times like so
legend: {position: 'bottom'}, {textStyle: {color: '#d1dbbd', fontName: 'Century Gothic', fontSize: 15}},
or
legend: {position: 'bottom', {textStyle: {color: '#d1dbbd', fontName: 'Century Gothic', fontSize: 15}}},
Help ?
You are close with the format. You want one object with "position" and "textStyle" properties:
legend: {
position: 'bottom',
textStyle: {
color: '#d1dbbd',
fontName: 'Century Gothic',
fontSize: 15
}
}