# [Vue.js] Select option entries are only shown on the first select attempt

when using vuetify and an I’m trying to populate a select box…

…using this JSON Object:

[
{
“configurator”: {
“group”: {
“property”: [
{
“id”: “STATUS”,
“value”: [
{
“id”: “OK”,
“text”: “OK”
},
{
“id”: “NOK”,
“text”: “not OK”,
“selected”: “true”
}
]
}
]
}
}
}
]

…and I’m trying to render this component:

<v-list v-for=”(item, i) in jsonObjPruef.configurator.group.property” :key=”i”>
<v-select
v-model=”item.value”
:items=”item.value”
:label=”item.text”
/>
</v-list>

Page loads without warnings and errors and I can select from the expected values (“OK”, “not OK”).

While choosing e.g. “OK” the following warning is displayed:

[vue.js warn]: Invalid prop: type check failed for prop “items”. Expected Array, got String with value “OK”.

And now if I’m trying to select again I only can pick the value I chose before (“OK”).

The select option entries are only shown on the first select attempt.

Any idea what I’m missing here?

### Solution :

tl;dr: v-model means: “where user selection is saved”. If you save it over the same exact property which holds the options, the options are gone and the <v-select> is broken.

v-model replaces jsonObjPruef.configurator.group.property with the selected option, when you select it. Which makes the <v-select> no longer have items.

You should specify a different v-model - a model property in which you store the selection, (i.e: results):

<v-list v-for=”(item, i) in jsonObjPruef.configurator.group.property” :key=”i”>
<v-select
v-model=”results[i]“
:items=”item.value”
:label=”item.text”
/>
</v-list>

In data, you need to initialize results : {}.

Now results will hold the selected results and you can place a watcher on it to trigger additional functionality when it changes. It doesn’t have to be an object, it could be an array. It depends on what you currently have.
Obviously, you can rename results to something less generic, which makes more sense in the specific example.

If you need more help, please add a mcve.

# [Vue.js] How to use Vue method as image source?

in vue.js when trying to use the result from a method as the source for an image:

HTML:

<img :src=”getEnergyIcon(type)”>

JS:

data() {
return {

energyTypeMap: new Map([
[‘colorless’,‘@/assets/images/energy-icons/20px-Colorless-attack.png’],
[‘darkness’,‘@/assets/images/energy-icons/20px-Darkness-attack.png’],
[‘dragon’,‘@/assets/images/energy-icons/20px-Dragon-attack.png’],
[‘fairy’,‘@/assets/images/energy-icons/20px-Fairy-attack.png’],
[‘fighting’,‘@/assets/images/energy-icons/20px-Fighting-attack.png’],
[‘fire’,‘@/assets/images/energy-icons/20px-Fire-attack.png’],
[‘grass’,‘@/assets/images/energy-icons/20px-Grass-attack.png’],
[‘lightning’,‘@/assets/images/energy-icons/20px-Lightning-attack.png’],
[‘metal’,‘@/assets/images/energy-icons/20px-Metal-attack.png’],
[‘psychic’,‘@/assets/images/energy-icons/20px-Psychic-attack.png’],
[‘water’,‘@/assets/images/energy-icons/20px-Water-attack.png’],
])

}
},

And:

methods: {
getEnergyIcon(type){
return this.energyTypeMap.get(type.toLowerCase());
}
},

The method returns the correct path, but the image doesn’t use that path as the source:

the result to be the same as the hardcoded result, but to achieve this by using the method, because when going to use dynamic data that gives me one of the 11 types, I cannot use hardcoded paths.

there is been Googling around to find a solution but I can’t find a solution that uses a direct method as a source for the image. How do I do this?

### Solution :

Found this topic:

How to reference static assets within vue.js javascript

That mentioned the following:

In a vue.js regular setup, /assets is not served.

The images become src=”…” strings, instead.

And required me to use:

require();

Which I did like this:

data() {
return {
card: {},
energyTypeMap: new Map([
[‘colorless’,require(‘@/assets/images/energy-icons/20px-Colorless-attack.png’)],
[‘darkness’,require(‘@/assets/images/energy-icons/20px-Darkness-attack.png’)],
[‘dragon’,require(‘@/assets/images/energy-icons/20px-Dragon-attack.png’)],
[‘fairy’,require(‘@/assets/images/energy-icons/20px-Fairy-attack.png’)],
[‘fighting’,require(‘@/assets/images/energy-icons/20px-Fighting-attack.png’)],
[‘fire’,require(‘@/assets/images/energy-icons/20px-Fire-attack.png’)],
[‘grass’,require(‘@/assets/images/energy-icons/20px-Grass-attack.png’)],
[‘lightning’,require(‘@/assets/images/energy-icons/20px-Lightning-attack.png’)],
[‘metal’,require(‘@/assets/images/energy-icons/20px-Metal-attack.png’)],
[‘psychic’,require(‘@/assets/images/energy-icons/20px-Psychic-attack.png’)],
[‘water’,require(‘@/assets/images/energy-icons/20px-Water-attack.png’)],
])
}
},

It has solved my problem.

# [Vue.js] Build prod dont display font - basic webpack init

I need to use font named myFontName from ttf file in production environment after launch this command :

npm run build

For this test, there is only initialize project with this command :

vue.js init webpack myProjectName

In dev environment (npm run dev) i can display and use my font. But i cant see the same font after build. However, in the production environment i can see my font in css rules (browser console).

So, font seems to be display in dev and not in production.

This is my tree project:

src
|_assets
|_components
|componentfile.vue
|_fonts
|_myFontFile.ttf

This is my dist folder tree :

dist
|_js
|_static
|_fonts
|_myFontFile.ttf

I call my font directly in my component.vue.js file :

<script scoped>
@font-face{
font-family:”myFontName”;
src: url(“./fonts/myFontFile.ttf”) format(“truetype”);
}
<script>

Webpack is nativ from init. there is this loader in my webpack.base.conf.js :

{
}
}
…]

### Solution :

VueRouter doesn’t support setting a route’s meta property to be a function like you’re trying to do.

But you could have the title property be able to also be set as a function which takes in the route as a param:

{
path: ‘/page1’,
component: Page1Component,
meta: {
title: route => dynamic title is ${route.query.param} } } And then add a check in the beforeEach hook to set the document.title to the returned value of the title function, in the cases where it is a function: router.beforeEach((to, from, next) => { const { title } = to.meta; document.title = typeof title === ‘function’ ? title(to) : title; next(); }); ### Solution 2: As said in the vue.js router documentation, the to and from objects in navigation guards are both route object, like the$route variable accessible in the component.

Therefore, you can do this :

router.beforeEach((to, from, next) => {
document.title = to.query.param;
next();
});

# [Vue.js] prepend and append a tag at each occurence of a string

Basically there is a simple search feature where you can search anything, my problem at the moment is that I need to highlight the searched word on all my articles. For example if I search “Spain” and there is a article like with the following title: “Spain is the best country, on Spain we have…” I need to highlight both “Spain” words.

I already made some attempts & currently there is a function below where my entry.title is the article title, “Spain is the best country, on Spain we have…” and the search Word is “Spain”, this solves my problem but just with 1 occurrence.

processTitle () {
let newTitle = this.entry.title
if(this.entry.title.includes(this.searchWord) && this.searchWord) {
newTitle = this.entry.title.split(this.searchWord)
console.log(newTitle)
return ${newTitle[0]} <b>${this.entry.title}</b> ${newTitle[1]} } return newTitle }, I Need to have a fresh new title where there is all occurrences of the searched word highlighted. Any help with this? ### Solution : You can use regex to search entire string globally for all occurences of the phrase and replace it with a new one const title = “Spain is the best country, on Spain we have…”; const searchWord = “Spain”; function replaceAll(title, searchWord) { const replacement = <b>${searchWord}</b>
return title.replace(new RegExp(searchWord, ‘g’), replacement);
};

console.log(replaceAll(title, searchWord));

# [Vue.js] Check if Shift + letter is pressed in JS / Vue 2

Is there a way to check if Shift + letter is pressed in lodash’s debounce?

fetchDebounced: _.debounce(function(e) {
if (e.keyCode === 16 && e.keyCode >= 46 && e.keyCode <= 90) {
console.log(‘shift + letter is pressed’)
}
}

Doesn’t work in my case, using it on keyup event. to print out console message, only when SHIFT+LETTER, for example, Shift+a is pressed (or Shift+z). Is it possible?

### Solution :

You can use onkeydown and e.shiftKey:

document.onkeydown = function(e) {
if (e.shiftKey && e.keyCode >= 46 && e.keyCode <= 90) {
console.log(“SHIFT + “ + e.keyCode);
return false;
}
}

### Solution 2:

As per this answer:

event.shiftKey is a boolean. true if the Shift key is being pressed, false if not. altKey and ctrlKey work the same way.

So basically you just need to detect the keydown as normal with onkeydown, and check those properties as needed.

### Solution 3:

To achieve expected result, use below option of using shiftkey press and keyCode check between 65-90(A-Z) on key up to track as one event

function checkCode(e) {
if(e.shiftKey){
console.log(e.shiftKey && (e.keyCode >= 65 || e.keyCode <= 90))
}
}
<input onkeyup = “checkCode(event)” />

### Solution 4:

Because people are answering, this is the best answer from this previously-asked question.

…onkeyup = function(e) {
if (e.keyCode == 13)
{
// if (e.shiftKey === true)
if (e.shiftKey) // thruthy
{
// new line
}
else
{
// run the function
}
return false;
}
}

Also note Das_Geek’s answer above, that altKey and ctrlKey work the same way, per the venerable Niet the Dark Absol.

# [Vue.js] CORS when using axios but works normal using curl

I’m trying to use GET from an API(not mine). I test it using simple curl it works normal, but when I try to use axios, axios sends OPTION. Server only accepts GET,HEAD,POST so its throw CORS

Any idea why axios sends OPTION, not GET?

Here’s my curl

<?php
$curl = curl_init(); curl_setopt_array($curl, [
CURLOPT_URL => ‘https://xxxxxx'
]);
$resp = curl_exec($curl);

# [Vue.js] Laravel Mix Using Mix() to cache bust around another helper

there is a helper defined below:

function cdn($file) { return env(‘CDN_URI’, ‘’).’/‘.ltrim($file, ‘/‘);
}

In my blade, when serving the bundled vue.js js file with the helper:

<script type=”text/javascript” src=”{ cdn(‘/dist/js/app.js’) }”></script>

when having caching issues now so to start using versioning. I read in Laravel Mix docs that to imoport the versioned files, put them in the mix() . Would I be able to wrap that around my other helper as follows:

<script type=”text/javascript” src=”{ mix(cdn(‘/dist/js/app.js’)) }”></script>`

### Solution :

To enable versioning, you need to add the following in the webpack.mix.js when you are compiling the assets.

mix.version();

Something along the lines of:

const mix = require(‘laravel-mix’);

mix.js(‘resources/js/app.js’, ‘public/js’)
.sass(‘resources/sass/app.scss’, ‘public/css’)
.version();

Then after you add this to the template:

<script src=”{ mix(‘js/app.js’) }”></script>

Compile the assets with npm run prod, and if you view the source, you will see something like the following where you put the JavaScript.

<script src=”/js/app.js?id=476befa31a13c804b084”></script>

Finally, you can add the cdn() helper, make sure to wrap the helper around the mix() function.

<script src=”{ cdn(mix(‘js/app.js’)) }”></script>

# [Vue.js] Vue add class to target but remove from other instances

I’m attempting to create a sortable table component in vue.js and it’s all working but I just wanted to add some little finishing touches, one thing I wanted was to add a class to the column that is currently being sorted and remove it from all other columns but I can’t work out how to do the last part. I keep reading things saying that I shouldn’t be trying to target DOM elements in vue.js which makes me also think my use of event.target.classList.add() isn’t correct either.

This is my method as it stands now:

methods: {
sort_column (event, index) {
if (this.sortAsc) {
this.sortAsc = false
return this.tableData.sort((a, b) => {
if (a[index] < b[index]) return -1;
if (a[index] > b[index]) return 1;
return 0;
})
} else {
this.sortAsc = true
return this.tableData.sort((a, b) => {
if (a[index] > b[index]) return -1;
if (a[index] < b[index]) return 1;
return 0;
})
}
},
}

and this is where it is called:

<th v-for=”(item, index) in headings” :key=”index”
@click=”sort_column($event, index)””> Back in the days of jQuery, I would just target the parent of the clicked element, find all of the columns and remove the class from it but if I can’t (or shouldn’t) target DOM elements in vue.js then I’m at a loss for the right way to do this. ### Solution : The only thing that comes to my mind would be assigning the class with vue.js like this. https://vuejs.org/v2/guide/class-and-style.html#Object-Syntax Store the index of the column that was sorted (in a variable named idxSorted for this example) and then do (tested): <th :class=”{ sorted: (index === idxSorted) }” v-for=”(item, index) in headings” :key=”index” @click=”sort_column($event, index)””>

You can assign the sortable–down and sortable–up classes the same way with an additional check for sortAsc.