link2603 link2604 link2605 link2606 link2607 link2608 link2609 link2610 link2611 link2612 link2613 link2614 link2615 link2616 link2617 link2618 link2619 link2620 link2621 link2622 link2623 link2624 link2625 link2626 link2627 link2628 link2629 link2630 link2631 link2632 link2633 link2634 link2635 link2636 link2637 link2638 link2639 link2640 link2641 link2642 link2643 link2644 link2645 link2646 link2647 link2648 link2649 link2650 link2651 link2652 link2653 link2654 link2655 link2656 link2657 link2658 link2659 link2660 link2661 link2662 link2663 link2664 link2665 link2666 link2667 link2668 link2669 link2670 link2671 link2672 link2673 link2674 link2675 link2676 link2677 link2678 link2679 link2680 link2681 link2682 link2683 link2684 link2685 link2686 link2687 link2688 link2689 link2690 link2691 link2692 link2693 link2694 link2695 link2696 link2697 link2698 link2699 link2700 link2701 link2702 link2703 link2704 link2705 link2706 link2707 link2708 link2709 link2710 link2711 link2712 link2713 link2714 link2715 link2716 link2717 link2718 link2719 link2720 link2721 link2722 link2723 link2724 link2725 link2726 link2727 link2728 link2729 link2730 link2731 link2732 link2733 link2734 link2735 link2736 link2737 link2738 link2739

[Vue.js] How do you import a JSON file with VueJS / Typescript?

I just created a clean VueJS new project and I can’t get loading a JSON file to work.

Reproduction / Issue

For easy reproduction I’ve created a Github repo with my issue:
https://github.com/devedse/VueJSImportJsonFile

In the Home.vue.js page I’m trying to get Json loading to work. (https://github.com/devedse/VueJSImportJsonFile/blob/master/src/views/Home.vue)

When you open this solution in VSCode the following line shows an error:

import theJson from ‘@/assets/hi.json’;

Can’t find module ‘@/assets/hi.json’

When running NPM Serve the following error pops up:

What I’ve already tried

I’ve already searched all of stackoverflow and tried everything in the following posts:

Importing json file in TypeScript

Typescript compiler error when importing json file

https://github.com/chybie/ts-json

Edit 1:

Ok I now managed to get it to work when running npm run serve by adding this to the tsconfig.json:

{
“compilerOptions”: {
“resolveJsonModule”: true
}
}

However the error in VSCode seems to stay. Is there a way to fix this too?

Solution :

Simply add resolveJsonModule”: true to the tsconfig.json under compilerOptions:

diff –git a/tsconfig.json b/tsconfig.json
index 499f5e2..a05dab1 100644
-– a/tsconfig.json
+++ b/tsconfig.json
@@ -6,6 +6,7 @@
“jsx”: “preserve”,
“importHelpers”: true,
“moduleResolution”: “node”,
+ “resolveJsonModule”: true,
“esModuleInterop”: true,
“allowSyntheticDefaultImports”: true,
“sourceMap”: true,

[Vue.js] V for loop incremental

<table style=”cursor:default”>
<tbody>
<tr v-for=”j in status_data.length/2”>
<td class=”w3-border w3-border-black w3-round-large w3-center” :bgcolor=”getColor(status_data[j-1].MESSAGE_CODE)”>{ status_data[j-1].PROCESS_CODE }</td>
<td class=”w3-border w3-border-black w3-round-large w3-center” :bgcolor=”getColor(status_data[j].MESSAGE_CODE)”>{ status_data[j].PROCESS_CODE }</td>
</tr>
</tbody>
</table>

how can i control value of j in above code , it is like

for i in status_data.length/2
do action
i=i+2

to increment value by 2 in every iteration .

Solution :

If you want it by pairs, go through the array and collect pairs whenever the index is an even number.

status_data
.map((v, i) => i%2 === 0 ? arr.slice(i, i+2) : [])
.filter(x => x.length > 0)

console> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
.map((v, i) => i%2 === 0 ? arr.slice(i, i+2) : [])
.filter(x => x.length > 0)

// will return an array like [[1,2],[3,4],[5,6],[7,8],[9,10],[11,12]]

Beware that this will ignore the last element if the array has an odd number of elements

[Vue.js] Work process for data passing in VueJS 2 application

when pretty new to VueJS 2, so wanted to see if when working in the correct way. there is a system where someone uploads a file that contains data, which will then be used to create charts. So I display the uploaded files to them

<tr v-for=”file in files.data” :key=”file.id”>
//file information
<td>
<router-link :to=”{ name: file.chart, params: { fileName: file.name }”
tag=”a” exact> View Results
</router-link>
</td>
</tr>

So you can see there is a link in the table, that directs them to the chart page for the file they uploaded. It includes the params for the file name to be loaded.

On the chart page, I get the params within the created method. I then pass these to the component for the chart to be displayed

<template>
<div>
//some information
<div class=”row”>
<div class=”col-12” id=”parentDiv”>
<barchart :file-name = this.fileName></barchart>
</div>
</div>
</div>
</template>

<script>
import Barchart from ‘../charts/Barchart’;
export default {
components: {
‘barchart’: Barchart
},
data() {
return {
fileName: ‘’
}
},
created() {
this.fileName = this.$route.params.fileName;
}
}
</script>

Finally, there is the Barchart component. This is what creates the chart based on the file uploaded data.

<script>
import * as d3 from ‘d3’;

export default {
props: {
fileName: {
type: String,
required: true
}
},
methods: {
createBarChart() {
//d3 to create chart using the file that was uploaded
}
},
created() {
let vm = this;
d3.json(‘storage/‘ + this.fileName)
.then(function (data) {
vm.createBarChart(data);
}).catch(function (error) {
// handle error
});
}
};
</script>

To me, there seems to be a lot of passing of data from one component to the next. I pass it from the files display component (which displays all uploaded files), then to the page for the chart, which then passes it to the chart component.

The other issue is, if when on the charts page, and I refresh the page, then the chart no longer has the filename prop and therefore the chart does not render. How would I handle this
situation?

Any advice appreciated

Solution :

The reason that you are losing the chart on refresh is due to the use of the created method.

In the chart component remove the entire created method and reference the route param directly in the barchart reference, like so:

<template>
<div>
//some information
<div class=”row”>
<div class=”col-12” id=”parentDiv”>
<barchart :file-name=”$route.params.fileName”></barchart>
</div>
</div>
</div>
</template>

<script>
import Barchart from ‘../charts/Barchart’;
export default {
components: {
‘barchart’: Barchart
},
data() {
return {

}
}
}
</script>

Solution 2:

You may want to look into vuex to manage the data passing from parent to some deeply nested child.

Before you decide you want to persist the file in the nested component, you may want to consider if this is good UX (does it make sense that when the user refreshes the page, the old file they had uploaded is still cached?) You can look into using localStorage to store things locally so that upon refresh, the data is still there without needing the user to re-enter it.

[Vue.js] vuejs computed or methods which one is best to use vuex getters?

All we know that both of computed properties and getters are cached, so when we use getters inside computed properties, we have some data that is cached two times, one in the component and the other in the store.
Is it better to use getters inside of methods?

Solution :

You should map the getters inside the components so they are not computed twice but instead reference the method in the getter.

import { mapGetters } from ‘vuex’

export default {
// …
computed: {
// mix the getters into computed with object spread operator
…mapGetters([
‘doneTodosCount’,
‘anotherGetter’,
// …
])
}
}

more info can be found here:
https://vuex.vuejs.org/guide/getters.html#the-mapgetters-helper

[Vue.js] Vue components inside component

What is a good way to build system of nested components with a small advancing of rendering? See desired code with main question (‘HOW TO…’) below:

tab.vue.js (child component)

<template>
<slot></slot>
</template>

<script>
export default {
name: ‘Tab’,
props: [‘title’]
}
</script>

tabs.vue.js (container component)

<template>
<div class=”tabs-switchers”>
<b
v-for=”(o, i) in items”
:key=”`tab-button-${i}`“
\>
{ o.componentInstance.props.title }
</b>
</div>
<div class=”tabs-contents”>
<div class=”tabs-contents-item”
v-for=”(o, i) in items”
:key=”`tab-item-${i}`“
\>
<!– HOW TO RENDER TAB CONTENT HERE??? –>
</div>
</div>
</template>
<script>
export default {
name: ‘Tabs’,
computed () {
items () {
return this.$slots.default
}
}
}
</script>

page.vue.js (component with example of using)

<template>
<tabs>
<tab title=”tab 1”><p>Tab #1 content</p></tab>
<tab title=”tab 2”><p>Tab #2 content</p></tab>
<tab title=”tab 3”><p>Tab #3 content</p></tab>
</tabs>
</template>

Solution :

You should not need v-for for rendering the slot contents.

Vue.component(‘Tabs’, {
template: `
<div class=”tab-container”>
<slot></slot>
</div>
`
})

Vue.component(‘Tab’, {
template: `
<div class=”tab”>
<strong>{title}</strong>
<slot></slot>
</div>
`,

props: [‘title’]
})

new Vue().$mount(‘#app’);
<script src=”https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id=”app”>
<tabs>
<tab title=”tab 1”>
<p>Tab #1 content</p>
</tab>
<tab title=”tab 2”>
<p>Tab #2 content</p>
</tab>
<tab title=”tab 3”>
<p>Tab #3 content</p>
</tab>
</tabs>
</div>

[Vue.js] Getting authenticated user informations with Django Rest Framework, JWT and Vuejs

I’m building an app using DRF as a backend and Vuejs for the frontend, I’ve already managed to create the authentication system using JWT tokens in DRF, but I’m having a hard time trying to get the authenticated user informations. When I register the user I store, the token in local storage as

localStorage.setItem(‘user-token’, response.data.token)

But when I try to get the user’s informations sending a http get request with an authorization header I get a 401 forbidden error

detail: “Authentication credentials were not provided.”

Here’s my code:
I set the header authorization like this with axios

const token = localStorage.getItem(‘user-token’)
if (token) {
axios.defaults.headers.common[‘Authorization’] =Basic ${token}
}

The get request in vue

getUser(){
axios.get(this.url +’/api/auth/user/‘)
.then( (response) =>{
console.log(response.data);
});

My views.py

class UserViewSet(APIView):
permission_classes = [permissions.IsAuthenticated]
def get(self, request):
serializer = UserSerializer(request.user)
return Response(serializer.data)

My serializer

class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = (‘username’, )

When I remove the permissions class, I get an empty username field as a response otherwise it’s a 401 error as mentioned before.
I can see that the authorization header is sent in the browser.
Any solutions please?

my settings.py

INSTALLED_APPS = [
‘django.contrib.admin’,
‘django.contrib.auth’,
‘django.contrib.contenttypes’,
‘django.contrib.sessions’,
‘django.contrib.messages’,
‘django.contrib.staticfiles’,

#Third party
‘webpack_loader’,
‘rest_framework’,
‘corsheaders’,

#Local apps
‘users’,

]

MIDDLEWARE = [
‘django.middleware.security.SecurityMiddleware’,
‘django.contrib.sessions.middleware.SessionMiddleware’,
‘django.middleware.common.CommonMiddleware’,
‘django.middleware.csrf.CsrfViewMiddleware’,
‘django.contrib.auth.middleware.AuthenticationMiddleware’,
‘django.contrib.messages.middleware.MessageMiddleware’,
‘django.middleware.clickjacking.XFrameOptionsMiddleware’,

#Cors
‘corsheaders.middleware.CorsMiddleware’,

]

REST_FRAMEWORK = {
‘DEFAULT_AUTHENTICATION_CLASSES’: (

#’rest_framework.authentication.BasicAuthentication’,
‘rest_framework_jwt.authentication.JSONWebTokenAuthentication’,
‘rest_framework.authentication.SessionAuthentication’, #Oauth, JWT
),
‘DEFAULT_PERMISSION_CLASSES’: (
‘rest_framework.permissions.IsAuthenticatedOrReadOnly’,
),
‘DEFAULT_FILTER_BACKENDS’: (
‘rest_framework.filters.SearchFilter’,
‘rest_framework.filters.OrderingFilter’,
),
‘SEARCH_PARAM’: ‘q’,
‘ORDERING_PARAM’: ‘ordering’,

}

JWT_AUTH = {
‘JWT_ENCODE_HANDLER’:
‘rest_framework_jwt.utils.jwt_encode_handler’,

‘JWT_DECODE_HANDLER’:
‘rest_framework_jwt.utils.jwt_decode_handler’,

‘JWT_PAYLOAD_HANDLER’:
‘rest_framework_jwt.utils.jwt_payload_handler’,

‘JWT_PAYLOAD_GET_USER_ID_HANDLER’:
‘rest_framework_jwt.utils.jwt_get_user_id_from_payload_handler’,

‘JWT_RESPONSE_PAYLOAD_HANDLER’:

#’rest_framework_jwt.utils.jwt_response_payload_handler’
‘users.api.utils.jwt_response_payload_handler’,

‘JWT_ALLOW_REFRESH’: True,
‘JWT_REFRESH_EXPIRATION_DELTA’: datetime.timedelta(days=7),

‘JWT_AUTH_HEADER_PREFIX’: ‘JWT’, # Authorization: JWT <token>
‘JWT_AUTH_COOKIE’: None,

}

#Cors
CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_CREDENTIALS = True

Solution :

Default authrization header for the DRF is

axios.defaults.headers.common[‘Authorization’] =Token ${token}

Until and unless you haven’t make the changes, if this still not work please provider the setting file code.

[Vue.js] Alternating v-for DOM elements on same level

when trying to have two alternating loops after each other on the same level. If I wrap it in a parent element and loop thru it brakes the styles.

Here is an example of what when trying to do:

<div v-for=”category in items” class=”cat-name”>{ category.name }</div>
<div v-for=”category in items” class=”cat-meta”>{ category.metaData }</div>

Wanted Result:

<div class=”cat-name”>name1</div>
<div class=”cat-meta”>metadata1</div>
<div class=”cat-name”>name2</div>
<div class=”cat-meta”>metadata2</div>
<div class=”cat-name”>name3</div>
<div class=”cat-meta”>metadata3</div>

and so on…

I really hope that this is possible since it completely breaks the styles when I tried:

<div v-for=”category in items”>
<div class=”cat-name”>{ category.name }</div>
<div class=”cat-meta”>{ category.metaData }</div>
</div>

Really appreciate any help and input.
Thanks, -J

Solution :

You could wrap both the elements in a template tag.
Unlike a basic tag, this one will not be rendered in the DOM.

<template v-for=”category in items”>
<div class=”cat-name”>{ category.name }</div>
<div class=”cat-meta”>{ category.metaData }</div>
</template>

[Vue.js] How to use a jQuery plugin inside Vue

I’m building a web application inside VueJS but I encounter a problem. to use a jQuery extension (cropit to be specific) but I don’t know how to instantiate/require/import it the right way without getting errors.

I’m using de official CLI tool and de webpack template for my App.

I included jQuery like this in my main.js file:

import jQuery from ‘jQuery’
window.jQuery = jQuery

Now I’m building an image editor component where to instantiate crept like this:

export default {
ready () {
$(document).ready(function ($) {
$(‘#image-cropper-wrapper-element’).cropit({ /* options */ })
})
},
}

But I keep getting errors…Now my question is how to properly instantiate jQuery and plugins via NPM/Webpack/Vue?

Thanks in advance!

Solution :

Option #1: Use ProvidePlugin

Add the ProvidePlugin to the plugins array in both build/webpack.dev.conf.js and build/webpack.prod.conf.js so that jQuery becomes globally available to all the modules:

plugins: [

// …

new webpack.ProvidePlugin({
$: ‘jquery’,
jquery: ‘jquery’,
‘window.jQuery’: ‘jquery’,
jQuery: ‘jquery’
})
]

Option #2: Use Expose Loader module for webpack

As @TremendusApps suggests in his answer, add the Expose Loader package:

npm install expose-loader –save-dev

Use in the entry point main.js like this:

import ‘expose?$!expose?jQuery!jquery’

// …

Solution 2:

You need to use either the globals loader or expose loader to ensure that webpack includes the jQuery lib in the source code output and so that it doesn’t throw errors when the use $ in the components.

// example with expose loader:
npm i –save-dev expose-loader

// somewhere, import (require) this jquery, but pipe it through the expose loader
require(‘expose?$!expose?jQuery!jquery’)

If you prefer, you can import (require) it directly within the webpack config as a point of entry, so I understand, but I don’t have an example of this to hand

Alternatively, you can use the globals loader like this:
https://www.npmjs.com/package/globals-loader

Solution 3:

Suppose you have vue.js project created with vue-cli (e.g. vue.js init webpack my-project).
Go to project dir and run

npm install jquery –save

Open file build/webpack.base.conf.js and add plugins:

module.exports = {
plugins: [
new webpack.ProvidePlugin({
$: ‘jquery’,
jquery: ‘jquery’,
‘window.jQuery’: ‘jquery’,
jQuery: ‘jquery’
})
]

}

Also at top of file add:

const webpack = require(‘webpack’)

If you are using ESLint, open .eslintrc.js and add next globals: {

module.exports = {
globals: {
“$”: true,
“jQuery”: true
},

Now you are ready to go. Use $ anywhere in the js.

NOTE You don’t need to include expose loader or any other stuff to use this.

Originally from https://maketips.net/tip/223/how-to-include-jquery-into-vuejs

Solution 4:

I use it like this:

import jQuery from ‘jQuery’

ready: function() {
var self = this;
jQuery(window).resize(function () {
self.$refs.thisherechart.drawChart();
})
},

Solution 5:

First install jquery using npm,

npm install jquery –save

I use:

global.jQuery = require(‘jquery’);
var $ = global.jQuery;
widows.$ = $;

[Vue.js] Passing props dynamically to dynamic component in VueJS

I’ve a dynamic view:

<div id=”myview”>
<div :is=”currentComponent”></div>
</div>

with an associated vue.js instance:

new vue.js ({
data: function () {
return {
currentComponent: ‘myComponent’,
}
},
}).$mount(‘#myview’);

This allows me to change my component dynamically.

In my case, there is three different components: myComponent, myComponent1, and myComponent2. And I switch between them like this:

Vue.component(‘myComponent’, {
template: “<button @click=\“$parent.currentComponent = ‘myComponent1’\“></button>”
}

Now, I’d like to pass props to myComponent1.

How can I pass these props when I change the component type to myComponent1?

Solution :

To pass props dynamically, you can add the v-bind directive to the dynamic component and pass an object containing the prop names and values:

So the dynamic component would look like this:

<component :is=”currentComponent” v-bind=”currentProperties”></component>

And in the vue.js instance, currentProperties can change based on the current component:

data: function () {
return {
currentComponent: ‘myComponent’,
}
},
computed: {
currentProperties: function() {
if (this.currentComponent === ‘myComponent’) {
return { foo: ‘bar’ }
}
}
}

So now, when the currentComponent is myComponent, it will have a foo property equal to ‘bar’. And when it isn’t, no properties will be passed.

Solution 2:

If you have imported you code through require

var patientDetailsEdit = require(‘../patient-profile/patient-profile-personal-details-edit’)

and initalize the data instance as below

data: function () {
return {
currentView: patientDetailsEdit,
}

you can also reference the component through the name property if you r component has it assigned

currentProperties: function() {
if (this.currentView.name === ‘Personal-Details-Edit’) {
return { mode: ‘create’ }
}
}

Solution 3:

You can also do without computed property and inline the object.

<div v-bind=”{ id: someProp, ‘other-attr’: otherProp }”></div>

Shown in the docs on V-Bind - https://vuejs.org/v2/api/#v-bind

[Vue.js] How to get `id` value as option value and `cname` as option label when using `v-select` in vuejs?

when trying to get id values as option value in VueJs when using v-select. Now, when getting trouble to get the id value which will be selected. Would someone help me please to solve this problem?

My index.html file is -

<!DOCTYPE html>
<html>
<head>
<title>VueJs | Select2</title>
<link rel=”stylesheet” href=”https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/css/bootstrap.min.css">
</head>
<body>
<div id=”pageContent”>
<form method=”POST” @submit.prevent=”addSection()”>
<div class=”form-group”>
<label for=”className”>Select Class</label>
<v-select name=”className” v-model=”className” :options=”academicClasses.map(({cname}) => cname)”></v-select>
</div>
<div class=”form-group”>
<button type=”submit” class=”btn btn-success save-btn”><i class=”fa fa-check”></i> Save</button>
</div>
</form>
</div>

<script src=”https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/js/bootstrap.min.js"></script>
<script src=”https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src=”https://unpkg.com/axios/dist/axios.min.js"></script>
<script src=”https://unpkg.com/vue-select@latest"></script>

</body>
</html>

And my vujs script is -

Vue.component(‘v-select’, VueSelect.VueSelect);

var app = new Vue({
el: ‘#pageContent’,
data: {
className: ‘’,
academicClasses: [],
academicClasses: [
{
id: 1,
cname: ‘One’
},
{
id: 2,
cname: ‘Two’
},
{
id: 3,
cname: ‘Three’
},
{
id: 4,
cname: ‘Four’
}
],
},

methods: {
addSection(){
alert(this.className);
}
}
})

Would you please visit in JSFiddle for what when trying to explain! please visit - JsFiddle

Solution :

Change here:

<v-select name=”className” v-model=”className” :options=”academicClasses.map(academicClass => ({label: academicClass.cname, value: academicClass.id}))”></v-select>

and here:

alert(this.className.label + ‘ - ‘ + this.className.value);

Documentation: Dropdown Options

Solution 2:

You want to pass an array of object for the options prop in the following structure:

[{
label: item.cname,
value: item.id
}]

Vue.component(‘v-select’, VueSelect.VueSelect);

var app = new Vue({
el: ‘#pageContent’,

data() {
return {
className: ‘’,

academicClasses: [
{ id: 1, cname: ‘One’},
{ id: 2, cname: ‘Two’ },
{ id: 3, cname: ‘Three’ },
{ id: 4, cname: ‘Four’ }
],
}
},

methods: {
addSection() {
alert(this.className);
}
},

computed: {
opts() {
return this.academicClasses.map(item => ({
label: item.cname,
value: item.id
}));
}
},

watch: {
className(val) {
console.log(val);
}
}
})

Vue.config.devtools = false;
Vue.config.productionTip = false;
<script src=”https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src=”https://unpkg.com/vue-select@latest"></script>

<div id=”pageContent”>
<form method=”POST” @submit.prevent=”addSection()”>
<div class=”form-group”>
<label for=”className”>Select Class</label>
<v-select name=”className” v-model=”className” :options=”opts”></v-select>
</div>
<div class=”form-group”>
<button type=”submit” class=”btn btn-success save-btn”><i class=”fa fa-check”></i> Save</button>
</div>
</form>
</div>