link2055 link2056 link2057 link2058 link2059 link2060 link2061 link2062 link2063 link2064 link2065 link2066 link2067 link2068 link2069 link2070 link2071 link2072 link2073 link2074 link2075 link2076 link2077 link2078 link2079 link2080 link2081 link2082 link2083 link2084 link2085 link2086 link2087 link2088 link2089 link2090 link2091 link2092 link2093 link2094 link2095 link2096 link2097 link2098 link2099 link2100 link2101 link2102 link2103 link2104 link2105 link2106 link2107 link2108 link2109 link2110 link2111 link2112 link2113 link2114 link2115 link2116 link2117 link2118 link2119 link2120 link2121 link2122 link2123 link2124 link2125 link2126 link2127 link2128 link2129 link2130 link2131 link2132 link2133 link2134 link2135 link2136 link2137 link2138 link2139 link2140 link2141 link2142 link2143 link2144 link2145 link2146 link2147 link2148 link2149 link2150 link2151 link2152 link2153 link2154 link2155 link2156 link2157 link2158 link2159 link2160 link2161 link2162 link2163 link2164 link2165 link2166 link2167 link2168 link2169 link2170 link2171 link2172 link2173 link2174 link2175 link2176 link2177 link2178 link2179 link2180 link2181 link2182 link2183 link2184 link2185 link2186 link2187 link2188 link2189 link2190 link2191

[Vue.js] <V-Model> doesn't work inside <V-Select> and only give no data available

lets say to make 2 text field and 1 v-select in vuejs using vuetify

Comodity ID (v-model = id)
Comodity Name (v-model = name)
v-select (v-model = selectType, :item= [‘Using Document ID’, id])

but whenever i try using the data such as this.id or id v-select always return No data available

I tried some of this topic but it doesn’t solve my problem:

vue.js Preselect Value with Select, v-for, and v-model

vue.js dynamic v-model within v-for

vue.js JS - Bind select option value to model inside v-for

this is my code :

<v-flex lg12 sm12>
<v-text-field label=”Kode Penjualan” name=”kodePenjualan” v-model=”kodePenjualan”>
</v-text-field>
</v-flex>

<v-flex lg12 sm12>
<v-text-field label=”Komoditas” name=”komoditas” v-model=”komoditas”>
</v-text-field>
</v-flex>

<v-flex lg12 sm12>
<v-select
v-model=”selectDocs”
:items=”tipeDocs”
label=”Dokumen yang Dimiliki”
\></v-select>
</v-flex>

this is my script:

data: () => ({
kodePenjualan: null,
komoditas: null,
selectDocs: null,
tipeDocs: [
‘Dokumen Usaha Dagang Perantara’,
kodePenjualan
],
}),

this is what i got right now

This is what to achieved

can someone help me with this?

Solution :

Finally I can solve this, it seems i must computed tipeDocs properly to update my own :items,

computed: {
tipeDocs() {
return [
‘Dokumen Usaha Dagang Perantara’,
this.kodePenjualan
]
}
}

I hope this solution can help a lot of people who got stuck at the same problem with me

source : Answer for my question in vue.js Forum

[Vue.js] VueJS Child component not getting prop data from parent

NOTE: This is not a duplicate question as none of the answers here have been able to solve my problem.

Child component:

<template>
<div>
<v-card>
<v-card-text>
<p> Activity for Financial Year { this.currentFinancialYear.string_date }
</p>
</v-card-text>
<div class=”px-3 pt-5”>
<v-select
label=”Financial Year”
v-model=”currentFinancialYear”
:items=”years”
item-text=”string_date”
:return-object=”true”
\></v-select>
</div>
</v-card>
</div>
</template>

<script>

export default {
name: ‘HeatMap’,
props: {
years: {
type: Array
},
financialYear: {
type: Object
},
cardWidth: {
type: String,
default: ‘860px’
}
},
data() {
return {
currentFinancialYear: {}
}
},
watch: {
currentFinancialYear (newVal, oldVal) {
if (newVal) {
this.getData()
return newVal
}
return oldVal
},
financialYear (newVal, oldVal){
this.currentFinancialYear = newVal
},
years (newVal) {
return newVal
}
},
methods: {
getData() {
// Some axios code
}
}
</script>

parent component:

<template>
<div>
<v-layout class=”headline pt-5” align-center> <p>Pulse</p> </v-layout>
<HeatMap
:years=’years’
:financialYear=’finacialYear’
:cardWidth=”‘860px’”
/>
</div>
</template>

<script>
import HeatMap from ‘@/components/charts/HeatMap’
import { getYears } from ‘@/services/MetricsService’

export default {
name: ‘MetricsDisplay’,
components: {
HeatMap
},
data () {
return {
years: [],
finacialYear: {}
}
},
created () {
getYears().then(response => {
for (var i = 0 ; i < response.data.data.items.length - 1 ; i++) {
this.years[i] = {
start: new Date(response.data.data.items[i], 3, 1).toISOString(),
end: new Date(response.data.data.items[i] + 1, 2, 31).toISOString(),
string_date: response.data.data.items[i] + ‘ - ‘ + (response.data.data.items[i] + 1)
}
}
this.financialYear = this.years[this.years.length - 1]
})
}
}
</script>

So, as you can see, the parent sends the array years and the object financialYear as props to the child. there is placed a watch on the those props in the child component so as to update the data as and when it comes. But for some reason, currentFinancialYear comes as undefined.

Also, as you can see in the child, the v-select uses the years array to fill its content. The first time the component is loaded, there are no elements in the v-select which indicates that the years are empty too. Since the currentFinancialYear is responsible for the selection of the item of the v-select, no item is selected as well.

Just to show what the data looks like:

years:

[
{
end: “2018-03-31T18:30:00.000Z”
start: “2017-03-31T18:30:00.000Z”
string_date: “2017 - 2018”
},
{
end: “2019-03-31T18:30:00.000Z”
start: “2020-03-31T18:30:00.000Z”
string_date: “2017 - 2018”
}
]

currentFinancialYear :

[
{
end: “2018-03-31T18:30:00.000Z”
start: “2017-03-31T18:30:00.000Z”
string_date: “2017 - 2018”
}
]

when aware of the fact that the parent-child lifecycle looks like this:

created() of parent
created() of child
mounted() of child
mounted() of parent.

there is read the Vue.js guidelines where they tell us to put the prop variables under watch which is why there is done it this way.

If I write a console.log(this.years) in the created(), the years are getting printed. Even so, I cannot initialize currentFInancialYear of get the years in my v-select.

there is also tried to initialise currentFinancialYear in mounted() and created() but with no luck.

The solution that I require is:

On the first load of the component, the data values of the child, years, financialYear, currentFinancialYear should have the values that have been passed from the parent, such that my v-select has elements.

Can someone please explain how to exactly time parent-child prop data passing?

Solution :

I think the issue you are having is a rather semantic one to do with what an array or object actually is and how you watch it.

Obviously we can define an object (or array) as const something = {} and can do this because the constant is truly constant and is an object container, that doesn’t change, however the contents of the container can change.

That is what the problem is here because you are setting up to watch the object or array container and not its contents. Fortunately vue.js has us covered on this with some of it’s more obscure functionality. You will need to utilise ‘immediate’ and ‘handler’ in the watch, like so:

watch: {
currentFinancialYear: {
handler: function (val, oldVal) {
if (newVal) {
this.getData()
return newVal
}
return oldVal
},
immediate: true
},
}

You can see all about it in the docs or there is a blog post covering it here.

[Vue.js] API call in lazy-load function, limiting the api response

I’ve set up a project where Im limiting the API response to 5, and upon scrolling to the bottom o the page, I make a new API call to fetch the next 2 items in the API. But with the current code it only checks if the 5 items previously fetched exists in the cards state. Im quite unsure as to how to go about fetching the 2 next items in the API? Does anyone have any suggestions as to how to go about this? Thanks,

var app = new Vue({
el: ‘#app’,
data: {
cards: []
},
methods: {
scroll(card) {
window.onscroll = () => {
let bottomOfWindow = document.documentElement.scrollTop +
window.innerHeight === document.documentElement.offsetHeight;
if(bottomOfWindow) {
const url =
https://api.jsonbin.io/b/5cab36508b8d1301a25bd8fa/1/';
axios.get(url)
.then(response => {
for (var i = 0; i < this.cards.length; i++) {
console.log(‘Cards id: ‘, this.cards[i].id)
if(this.cards[i].id !==
response.data.results[i].id){
for (var x = 0; x < 2; x++) {
this.cards.push(response.data.results[x])
}

} else{
console.log(‘No more cards to load’)
}
}
}
})
}
}
},
getAPI(){
const url = ‘https://api.jsonbin.io/b/5cab36508b8d1301a25bd8fa/1/';

axios.get(url)

.then(response => {
for (var i = 0; i < 5; i++) {
this.cards.push(response.data.results[i]);
}
})
.catch(function (error) {
console.log(error);
})
.then(function () {
// always executed
});
console.log(this.cards)

}
},
mounted() {
this.scroll(this.card)
}
})

Solution :

Changed the method in which you do the checking. Instead of doing it from cards length you loop through the results length and once you reach a card that doesnt exist you add them, keep track of the amount added and return after 2 or when there is none left. I changed the loop logic to so.

//Card with position i from results doesn’t exist
if(this.cards[i] == undefined){
//add this card - maybe add more logic to check for duplicate incase of reordering of response
this.cards.push(response.data.results[i])
//track card added
cardsAdded++;
} else {
console.log(‘No more cards to load’)
}

//check if cards added has reach limit of 2
if(cardsAdded == 2)
return;

See: https://jsfiddle.net/as4dm03q/

[Vue.js] How to make a custom decorator globally available to a vue.js 2 app?

I created a typescript decorator that adds some additional arguments to the method passed. It works completely fine without the decorator using optional parameters. Most of the times these parameters are not needed to be passed but once in a while these parameters are needed to be passed.

However I see that other developers don’t know what the other argument to pass are unless they see the implementation or jsdoc of the method, which they shouldn’t be concerned with.

So I created a decorator that will add the parameters in correct order and correct state. Everything works fine however now everyone has to remember to add an additional import to MyDecorator. So to make this decorator globally available.

Also in our app we are using decorators for creating components, props, getters, actions. It would be nice if I can make these global too. Almost all our component uses those and putting an import each time is just boilerplate. (nothing wrong with it, just makes it easier for all of us)

This is an example of the app’s component syntax with the decorator in pseudo code.

<script lang=”ts”>
import { Vue, Component, Prop, Emit } from ‘vue-property-decorator’;
import { MyDecorator } from ‘./src/utils’;
import { Getter } from ‘vuex-class’;

@Component({})
export default class MyComponent extends vue.js {
@Getter(‘something’, { namespace: ‘whatever’ })
something: number;

mounted() {
@MyDecorator()
doSomething(‘do it please’);
}
}
</script>

How all vue.js components can get the decorators available without using the import? Is it possible?

Solution :

After @LShapz’s comment I saw that using a plugin can do it. I still need to import vue.js though.

import { Component } from ‘vue-property-decorator’;
import { MyDecorator } from ‘@/src/utils’;

const MyPlugin: any = {};
MyPlugin.install = (Vue, options) => {

Vue.Awesome = Component; // this I will never use as it will require to edit all files in my project

Vue.MyDecorator = MyDecorator;
Vue.prototype.MyProtoDecorator = MyDecorator;
};
// the MyPlugin can be placed on another file and exported

Vue.use(MyPlugin);

To use it :

<script lang=”ts”>
import { vue.js } from ‘vue-property-decorator’;
import { Getter } from ‘vuex-class’;

@Vue.Awesome({}) // this is to show it is possible. Not practical
export default class MyComponent extends vue.js {
@Getter(‘something’, { namespace: ‘whatever’ })
something: number;

mounted() {
@Vue.MyDecorator() // this is the thing that is practical for my case
doSomething(‘done it somehow’);

@this.MyProtoDecorator() // second way
doSomething(‘done again’);

}
}
</script>

[Vue.js] Changing the assets directory in Vue

I’m working on a project that was created using the vue.js cli 3.0. And on creation a src/assets folder is also made. This folder can include some images for example.

Is it possible to change the path of the assets to something different?

I tried changing the assetsDir setting in vue.config.js. But this only changes the output path in the build.

Edit:

I should note that I would like to load assets based on a “vendor” environment variable. So if I set this to vendorX it should load src/assets/vendorX and with vendorY it should load src/assets/vendorY.

Edit 2:

It appears that the directory name doesn’t matter to the vue.js Cli. I changed the assets folder name to vendors. But my guess is that vue.js includes all resources files in src by default. So I’m now looking for a way to change this, or maybe find a different solution.

Solution :

If the assets folder was setup with an alias, that would be found in webpack.config, however the vue-cli appears to create a project with hardcoded paths to the assets. Try changing the src path for the assets across all files to ./assetsDir/myImg.png.

[Vue.js] Integrate existing static html website into existing vue js web app

I created a contact form with vue.js and vuetify as a new vue.js project. Now I would like to integrate it into the existing static html page.
I tried to add the vue.js app as a vue.js instance which didn’t seem to be the right approach.
Would it be easier to existing html & css code into the new light weight vue.js project setup?

Can you recommend a simple github project as an example which includes vue.js just as an instance into an existing website?

Solution :

vue.js is awesome because it’s scalable. You can use vue.js simply for rendering a button or to create large scale applications.

All you need is to load vue.js and have one element with an id. vue.js doesn’t care what’s outside that element. You can even have multiple vue.js instances on the same page.

Example:

<div id=”contactForm”>
<div v-text=”limits” :style=”appStyle”></div>
</div>
<p>You can have any html outside the vue.js app, it will display… normally.
</p>
<p>You can place the vue.js instance anywhere you want, as long as the element you instantiate it on exists in DOM when you try to instantiate it.
<p>And <code>vue.js</code> has to be loaded before you call the constructor. That’s about it.</p>

<script src=”https://cdn.jsdelivr.net/npm/vue"></script>
<script>
new Vue({
el: ‘#contactForm’,
computed: {
limits(){ return ‘There are no limits.’ },
appStyle() { return {
color: ‘red’,
border: ‘1px solid #ddd’
}
}
}
});
</script>

[Vue.js] Vue V model create object dynamically

I currently have:

<div id=”fields” v-for=”(key, field) in ui.account.search_field_url_map” v-bind:key=”field.stageName”>
<h2>{meta.account[field]}</h2>
<input type=”text” :v-model=”search.field = field” :name=”field” placeholder=”John”>
</div>

This div loads data with v-for this object has a key that to be able to use inside of my v-model where data is, inside my data I have:

data(){
search: {}
}

to create objects inside of search based on the data that is being passed through the v-for

Right now if I do

:v-model=”search.field = field”
I get:

field: “BillingCity”

But it to be:

BillingCity: “Whatever input from the form here”

How can I do this?

Solution :

Doing:

v-model=”search[field]“

did the trick for me

[Vue.js] vue.js / v-for How to style html depending on list index

there is a list, of which to style the items in a different way, depending on their indexes:

<ul>
<li
v-for=”(item, index) in myList()”
:key=”index”>{item}
</li>
</ul>

If item reaches index 4 and 5, it to be <strong>. How do I use v-if or indexof in this case the right way?

Or should I go with dynamic classes in this case?

Solution :

There are several ways to do this:

1. Bind a method that returns an object to the style attribute

You can do this by binding the <li> element’s style attribute to a method that accepts its index. In the method, you return a CSSStyleDeclaration object that is appropriate. For example, if i is 4 or 5, then you set fontWeight to bold:

new Vue({
el: ‘#app’,
methods: {
myList: function() {
return [‘Lorem’, ‘Ipsum’, ‘Dolor’, ‘Sit’, ‘Amet’, ‘Foo’, ‘Bar’, ‘Baz’];
},
listItemStyle: function(i) {
var style = {};

if (i === 4 || i === 5) {
style.fontWeight = ‘bold’;
}

return style;
}
}
});
<script src=”https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id=”app”>
<ul>
<li
v-for=”(item, index) in myList()”
:style=”listItemStyle(index)”
:key=”index”>
{item}
</li>
</ul>
</div>

2. Use <component> to determine if a <strong> tag should be rendered

This is not my preferred method, since I personally prefer binding styles instead of dictating appearance using DOM elements. However, if you want to use <strong> instead of setting font-weight: bold, you can simply make use of the <component is=”[tag]“> method to decide which HTML tag to be rendered in place:

new Vue({
el: ‘#app’,
methods: {
myList: function() {
return [‘Lorem’, ‘Ipsum’, ‘Dolor’, ‘Sit’, ‘Amet’, ‘Foo’, ‘Bar’, ‘Baz’];
},
tag: function(i) {
if (i === 4 || i === 5) {
return ‘strong’;
}

return ‘span’;
}
}
});
<script src=”https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id=”app”>
<ul>
<li
v-for=”(item, index) in myList()”
:key=”index”>
<component v-bind:is=”tag(index)”>
{item}
</component>
</li>
</ul>
</div>

[Vue.js] Vue Apollo - Cannot query with variable Cannot assign to read only property 'name' of object

I’m looking to query a django-graphene powered GraphQL backend with a vue.js Apollo / Nuxt powered front end to retrieve a single product’s data.

My method of trying to send the query results in the following error:

ERROR Cannot assign to read only property ‘name’ of object ‘GraphQLError: Syntax Error: Expected Name, found $’

at errorMiddleware (node_modules\@nuxt\server\dist\server.js:320:18)
at call (node_modules\connect\index.js:235:7)
at next (node_modules\connect\index.js:183:5)
at nuxtMiddleware (node_modules\@nuxt\server\dist\server.js:205:5)

My current code is as follows:

_slug.vue

<template>
<div>
<h1>{ product.name }</h1>
<div class=”description” v-html=”product.description”></div>
</div>
</template>

<script>
import { SINGLE_PRODUCT_QUERY } from ‘@/graphql/products’

export default {
props: [‘id’, ‘slug’],
data() {
return {
product: {
name: ‘Test Product’,
description: ‘Test Description’,
slug: ‘test’
}
}
},
apollo: {
product: {
query: SINGLE_PRODUCT_QUERY,
variables: {
slug: ‘test-product’
}
}
}
}
</script>

graphql/products.js

import gql from ‘graphql-tag’

export const SINGLE_PRODUCT_QUERY = gql `
query {
product($slug: string!) {
name
description
slug
},
}
`;

The following query works fine with my backend:

query {
product (slug: “test-product”) {
id
name
slug
}
}

I understand it could be a simple syntax error, but I’m not totally sure how to fix it.

EDIT: The correct query is as follows - thanks @DanielRearden:

export const SINGLE_PRODUCT_QUERY = gql `
query product( $slug: String!) {
product(slug: $slug) {
name
description
slug
},
}
`;

Solution :

As mentioned in the comments, you need to use String not string. Further to that the query should look more like this:

export const SINGLE_PRODUCT_QUERY = gql`
query Product($slug: String!) {
product(slug: $slug) {
name
description
slug
},
}
`;

[Vue.js] Vue.js how to replace the text of the button clicked

I my app UI there is a table with a set of permissions listed. In each row there is a toggle-button that sets the default state of each permission to either “deny” or “grant” in the DB.

If the user clicks the button, async action is triggered in the background. It all works perfectly fine, but what to add is when user click the button its inner html changes to a spinner or some sort of “wait…” text and the button get disable while the action runs. This is to prevent user from clicking multiple time is the action take a bit longer to complete, giving impression like nothing is happening.

Now, I know how to do it in jQuery or even plain JS, but there is no idea how to access the button properties in VUE.js

My button look like this:

<button @click=”defaultPermissionState(perm.id,’grant’,$event)”>Deny</button>

I’m only recently started into vue.js, so still learning it ;)

UPDATE: I’ve actually managed to find a way to do it by exploring the $event and being able to change the text and button properties by doing this:

event.path[0].innerHTML = ‘wait…’;
event.path[0].disabled = true;

but this does not look like a very elegant solution, so if anyone knows of something better I would still like to hear it

Solution :

You can use v-if with :disabled. Check this quick example:

new Vue({
el: “#app”,
data: {
isLoadingArray: []
},
methods: {
clicked(index) {
this.$set(this.isLoadingArray, index, true)

setTimeout(() => {
this.$set(this.isLoadingArray, index, false)
}, 2000)
}
}
})
.lds-dual-ring {
display: inline-block;
width: 64px;
height: 64px;
}

.lds-dual-ring:after {
content: “ “;
display: block;
width: 46px;
height: 46px;
margin: 1px;
border-radius: 50%;
border: 5px solid #fff;
border-color: #fff transparent #fff transparent;
animation: lds-dual-ring 1.2s linear infinite;
}

@keyframes lds-dual-ring {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
<script src=”https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id=”app”>
<button type=”button” @click=”clicked(0)” :disabled=”isLoadingArray[0]“>
<div v-if=”isLoadingArray[0]“ class=”lds-dual-ring”></div>
<span v-else>click me</span>
</button>

<button type=”button” @click=”clicked(1)” :disabled=”isLoadingArray[1]“>
<div v-if=”isLoadingArray[1]“ class=”lds-dual-ring”></div>
<span v-else>click me</span>
</button>

<button type=”button” @click=”clicked(2)” :disabled=”isLoadingArray[2]“>
<div v-if=”isLoadingArray[2]“ class=”lds-dual-ring”></div>
<span v-else>click me</span>
</button>

</div>

Solution 2:

You can do it like this

data: function() {
return {
waiting: false,
…otherstuffs
}
},
methods: {
callAsync() {
this.waiting = true;
callASYNC()
.then((result) => {
this.waiting = false;
})
}
}

In the HTML

<button :disabled=”waiting”> { waiting ? ‘Waiting …’ : ‘Deny’ } </button>

So basically, just set a flag before you hit the request, and set it back when the call finishes. Use this flag to set the button value to whatever you want

Solution 3:

Hide the button and show the spinner using a data or computed property. Update the ‘busy’ property from the async function.

<button v-if=’!busy’ @click=”defaultPermissionState(perm.id,’grant’,$event)”>Deny</button>
<spinner v-else />

Solution 4:

you can use $event to change the inner html for buttons

$event.path[0].innerHTML = “Write the inner html”

Solution 5:

This should help

<template>
<button disabled={disableBtn}
@click=”defaultPermissionState(perm.id,’grant’,$event)”>{btnText}
</button>
</template>

export default {
data() {
return {
btnText: ‘Deny’,
disableBtn: false
}
},
method: {
defaultPermissionState(id, type, e) {
this.disableBtn = true;
this.btnText = ‘Clicking…..’;
}
}
}