link274 link275 link276 link277 link278 link279 link280 link281 link282 link283 link284 link285 link286 link287 link288 link289 link290 link291 link292 link293 link294 link295 link296 link297 link298 link299 link300 link301 link302 link303 link304 link305 link306 link307 link308 link309 link310 link311 link312 link313 link314 link315 link316 link317 link318 link319 link320 link321 link322 link323 link324 link325 link326 link327 link328 link329 link330 link331 link332 link333 link334 link335 link336 link337 link338 link339 link340 link341 link342 link343 link344 link345 link346 link347 link348 link349 link350 link351 link352 link353 link354 link355 link356 link357 link358 link359 link360 link361 link362 link363 link364 link365 link366 link367 link368 link369 link370 link371 link372 link373 link374 link375 link376 link377 link378 link379 link380 link381 link382 link383 link384 link385 link386 link387 link388 link389 link390 link391 link392 link393 link394 link395 link396 link397 link398 link399 link400 link401 link402 link403 link404 link405 link406 link407 link408 link409 link410

[Vue.js] Using Environment Variables with Vue.js Subscribe to RSS

I’ve been reading the official docs and I’m unable to find anything on environment variables. Apparently there are some community projects that support environment variables but this might be overkill for me. So I was wondering if there’s something simple out of the box that works natively when working on a project already created with vue.js CLI.

For example, I can see that if I do the following the right environment prints out meaning this is already setup?

mounted() {
console.log(process.env.ROOT_API)
}

I’m a kinda new to env variables and Node.

FYI using vue.js 3.0 beta.

Solution :

If you use vue.js cli with the Webpack template (default config), you can create and add the environment variables to a .env file.

The variables will automatically be accessible under process.env.variableName in the project. Loaded variables are also available to all vue-cli-service commands, plugins and dependencies.

You have a few options, this is from the Environment Variables and Modes documentation:

.env # loaded in all cases
.env.local # loaded in all cases, ignored by git
.env.[mode] # only loaded in specified mode
.env.[mode].local # only loaded in specified mode, ignored by git

the .env file should look like this:

VUE_APP_MY_ENV_VARIABLE=value
VUE_APP_ANOTHER_VARIABLE=value

It is my understanding that all you need to do is create the .env file and add the variables then you’re ready to go! :)

As noted in comment below:
If you are using vue.js cli 3, only variables that start with VUE_APP_ will be loaded.

Solution 2:

If you are using vue.js cli 3, only variables that start with VUE_APP_ will be loaded.

In the root create a .env file with:

VUE_APP_ENV_VARIABLE=value

With this, you will be able to use process.env.VUE_APP_ENV_VARIABLE in the project (.js and .vue.js files).

Update

According to @ali6p, with vue.js Cli 3, isn’t necessary to install dotenv dependency.

Solution 3:

In the root of the project create the environment files:

.env
.env.someEnvironment1
.env.SomeEnvironment2

To then load those configs, you would specify the environment via mode i.e.

npm run serve –mode development //default mode
npm run serve –mode someEnvironment1

In the env files you simply declare the config as key-value pairs, but if you’re using vue.js 3, you must prefix with VUE_APP_:

In the .env:

VUE_APP_TITLE=This will get overwritten if more specific available

.env.someEnvironment1:

VUE_APP_TITLE=My App (someEnvironment1)

You can then use this in any of the components via:

myComponent.vue:

<template>
<div>
{title}
</div>
</template>

<script>
export default {
name: “MyComponent”,
data() {
return {
title: process.env.VUE_APP_TITLE
};
}
};
</script>

Now if you ran the app without a mode it will show the ‘This will get…’ but if you specify a someEnvironment1 as the mode then you will get the title from there.

You can create configs that are ‘hidden’ from git by appending .local to the file: .env.someEnvironment1.local - very useful for when you have secrets.

Read the docs for more info.

Solution 4:

A problem I was running into was that I was using the webpack-simple install for VueJS which didn’t seem to include an Environment variable config folder. So I wasn’t able to edit the env.test,development, and production.js config files. Creating them didn’t help either.

Other answers weren’t detailed enough for me, so I just “fiddled” with webpack.config.js. And the following worked just fine.

So to get Environment Variables to work, the webpack.config.js should have the following at the bottom:

if (process.env.NODE_ENV === ‘production’) {
module.exports.devtool = ‘#source-map’
// http://vue-loader.vuejs.org/en/workflow/production.html
module.exports.plugins = (module.exports.plugins || []).concat([
new webpack.DefinePlugin({
‘process.env’: {
NODE_ENV: ‘“production”‘
}
}),
new webpack.optimize.UglifyJsPlugin({
sourceMap: true,
compress: {
warnings: false
}
}),
new webpack.LoaderOptionsPlugin({
minimize: true
})
])
}

Based on the above, in production, you would be able to get the NODE_ENV variable

mounted() {
console.log(process.env.NODE_ENV)
}

Now there may be better ways to do this, but if you want to use Environment Variables in Development you would do something like the following:

if (process.env.NODE_ENV === ‘development’) {

module.exports.plugins = (module.exports.plugins || []).concat([
new webpack.DefinePlugin({
‘process.env’: {
NODE_ENV: ‘“development”‘
}
})
]);

}

Now if you want to add other variables with would be as simple as:

if (process.env.NODE_ENV === ‘development’) {

module.exports.plugins = (module.exports.plugins || []).concat([
new webpack.DefinePlugin({
‘process.env’: {
NODE_ENV: ‘“development”‘,
ENDPOINT: ‘“http://localhost:3000"',
FOO: “‘BAR’”
}
})
]);
}

I should also note that you seem to need the “‘’” double quotes for some reason.

So, in Development, I can now access these Environment Variables:

mounted() {
console.log(process.env.ENDPOINT)
console.log(process.env.FOO)
}

Here is the whole webpack.config.js just for some context:

var path = require(‘path’)
var webpack = require(‘webpack’)

module.exports = {
entry: ‘./src/main.js’,
output: {
path: path.resolve(__dirname, ‘./dist’),
publicPath: ‘/dist/‘,
filename: ‘build.js’
},
module: {
rules: [
{
test: /\.css$/,
use: [
‘vue-style-loader’,
‘css-loader’
],
}, {
test: /\.vue$/,
loader: ‘vue-loader’,
options: {
loaders: {
}
// other vue-loader options go here
}
},
{
test: /\.js$/,
loader: ‘babel-loader’,
exclude: /node_modules/
},
{
test: /\.(png|jpg|gif|svg)$/,
loader: ‘file-loader’,
options: {
name: ‘[name].[ext]?[hash]‘
}
}
]
},
resolve: {
alias: {
‘vue$’: ‘vue/dist/vue.esm.js’
},
extensions: [‘*‘, ‘.js’, ‘.vue’, ‘.json’]
},
devServer: {
historyApiFallback: true,
noInfo: true,
overlay: true
},
performance: {
hints: false
},
devtool: ‘#eval-source-map’
}

if (process.env.NODE_ENV === ‘production’) {
module.exports.devtool = ‘#source-map’
// http://vue-loader.vuejs.org/en/workflow/production.html
module.exports.plugins = (module.exports.plugins || []).concat([
new webpack.DefinePlugin({
‘process.env’: {
NODE_ENV: ‘“production”‘
}
}),
new webpack.optimize.UglifyJsPlugin({
sourceMap: true,
compress: {
warnings: false
}
}),
new webpack.LoaderOptionsPlugin({
minimize: true
})
])
}

if (process.env.NODE_ENV === ‘development’) {

module.exports.plugins = (module.exports.plugins || []).concat([
new webpack.DefinePlugin({
‘process.env’: {
NODE_ENV: ‘“development”‘,
ENDPOINT: ‘“http://localhost:3000"',
FOO: “‘BAR’”
}
})
]);

}

Solution 5:

Create two files in root folder (near by package.json) .env and .env.production
Add variables to theese files with prefix VUE_APP_ eg: VUE_APP_WHATEVERYOUWANT
serve uses .env and build uses .env.production
In the components (vue.js or js), use process.env.VUE_APP_WHATEVERYOUWANT to call value
Don’t forget to restart serve if it is currently running
Clear browser cache

Be sure you are using vue-cli version 3 or above

For more information: https://cli.vuejs.org/guide/mode-and-env.html

Solution 6:

In vue-cli version 3:

There are there options for .env files:
Either you can use .env or:

.env.test
.env.development
.env.production

You can use custom .env variables by using the prefix regex as /^/ instead of /^VUE_APP_/ in /node_modules/@vue/cli-service/lib/util/resolveClientEnv.js:prefixRE

This is certainly not recommended for the sake of developing an open source app in different modes like test, development, and production of .env files. Because everytime you npm install .. , it will be overrided.

Solution 7:

For those using vue.js CLI 3 and the webpack-simple install, Aaron’s answer did work for me however I wasn’t keen on adding my environment variables to my webpack.config.js as I wanted to commit it to GitHub. Instead I installed the dotenv-webpack plugin and this appears to load environment variables fine from a .env file at the root of the project without the need to prepend VUE_APP_ to the environment variables.

[Vue.js] V-for to show specific properties of objects Subscribe to RSS

when making many tables, so I made a table-making component. There are only 3 different things per table:

the object (an array of objects. 1 row per object)
the headers specific for that table
the object properties I specifically want to display

My component:

Vue.component(‘table-component’, {
props: {
headers: Array,
data_for_rows: Object,
data_properties_to_display: Array,
},
template: `
<div>
<table class=”table-hover”>
<thead>
<tr>
<th v-for=’item in headers’>{item}</th>
</tr>
</thead>
<tbody>
<tr v-for=’object in data_for_rows’>
<td v-for=’property in data_properties_to_display’>{object.property}</td>
</tr>
</tbody>
</table>
</div>
`
});

The HTML itself:

<table-component :headers=”[‘Party’,’Members’,’Votes With Party %’]“ data_for_rows=”glance_data”
:data_properties_to_display=”[‘partyName’,’memberCount’,’percentage’]“>
</table-component>

The goal is to be able to print the properties values within an object (specifically by passing the object itself and the properties-to-be-printed as separate props to the component). Can I?

Solution :

{object.property} would be looking for a property named property on the object instance in that nested loop, right? I’m thinking you might want something more like {object[ property ]}.

[Vue.js] Vue router-view does not show children Subscribe to RSS

there is a VueRouter with two levels:

const router = new VueRouter({
routes: [
{
path: ‘/‘,
name: ‘Home’,
component: HomeComponent
},
{
path: ‘/about’,
name: ‘About’,
component: AboutComponent
children: [
{
path: ‘plans’,
name: ‘Plans’,
component: PlansComponent
},
},
]

The App.vue.js file has the following code:

<template>
<div>
<div>
<nav>
<template v-for=”route in routes”>
<div>
<router-link class=”router-link” :key=”route.path” :to=”route.path”>
{route.name}
</router-link>
<div v-for=”child in route.children”>
<router-link class=”router-link router-link-child” :key=”child.path” :to=”{path: route.path + ‘/‘ + child.path}”>
{child.name}
</router-link>
</div>
</div>
</template>
</nav>
</div>
<router-view></router-view>
</div>
</template>

My problem is that the menu is rendered correctly, but clicking the child item, the component which is rendered is its parent component.

What am I doing wrong?

Solution :

This is the normal vue-router behavior : if you want the nested route to be rendered, you need to add a <router-view /> inside AboutComponent.

Exemple here : https://jsfiddle.net/yyx990803/L7hscd8h/

The User component contains the <router-view />

[Vue.js] Why am i getting , how to work with a promise Subscribe to RSS

when new to Vue.js and Axios. Working with a promise always confuses me.

Can anyone guide me here. when calling an API looking for an access_token.

to store this token and use it in a separate different API call.

there is tried variations of axios, fetch, request, syn-request. Axios is what to use.

<template>
<div class=”col-xs-6”>
<label>Access Token:</label>
<input type=”text” name=”name1” v-model=”token”>
</div>
</template>
<script>

import axios from ‘axios’

/* eslint-disable */
export default {
data () {
return {
token: ‘’
}
},
mounted () {
this.token = this.displayAccessToken()
console.log(‘token:’+this.token)
},
methods: {
displayAccessToken(){
function getAccessToken(){
return axios({
method: ‘POST’,
‘url’: ‘my_api_end_point’,
‘auth’: {
‘username’: ‘my_username’,
‘password’: ‘my_password’
},
‘headers’: {
‘content-type’: ‘application/json’
}
}).then(function(response) {
console.log(‘response:’ + response)
return response.data.access_token;
});
}

async function saveToken(){
let output = await getAccessToken()
return output
}

return saveToken();
}
}
}
</script>

Solution :

I believe you are overcomplicating the response fetching process. See if the following adjustments help, and please be sure to only call the next APIs subsequently (right after this token is set), that is when the first Promise is resolved.

export default {
data () {
return {
token: ‘’
}
},

async mounted () {
await this.displayAccessToken();

console.log(‘token:’ + this.token);
},

methods: {
async displayAccessToken() {
this.token = await axios({
method: ‘POST’,
‘url’: ‘my_api_end_point’,
‘auth’: {
‘username’: ‘my_username’,
‘password’: ‘my_password’
},
‘headers’: {
‘content-type’: ‘application/json’
}
})
.then(function(response) {
console.log(‘response:’ + response);

return response.data.access_token;
});
}
}
}

Also, if all this method does is returning a token, I would probably make it a void function and call the method setAccessToken instead, but of course that would depend on the use case.

[Vue.js] Uncaught ReferenceError module is not defined at build.js 1 vuejs, webpack, SSR (i used npm script-loader but no use) Subscribe to RSS

getting error while integrating bundle.js, and i used “script-loader” in but no use.
libraries used
vuejs, vuex, ssr, vuetify, webpack.js

Error:

build.js:1 Uncaught ReferenceError: module is not defined
at build.js:1 .

Solution :

change script from

<script src=”/dist/build.js”></script>

to

<script nomodule src=”/dist/build.js”></script>

add nomodule attribute in script tag, its happen because we used libraryTarget: ‘commonjs2’ in webpack config

finally my index.html will be like

<!doctype html>
<html lang=”en”>
<head>

</head>
<body>

<script nomodule src=”/dist/build.js”></script>

</body>
</html>

Note:

do not make any changes in src attribute

[Vue.js] Wait for VueX value to load, before loading component Subscribe to RSS

When a user tries to directly navigate load a component url, an http call is made in my vuex actions, which will define a value in my state once it resolves.

I don’t want to load my component until the http call is resolved, and the state value is defined.

For Example, in my component

export default {
computed: {
…mapState({
// ** this value needs to load before component mounted() runs **
asyncListValues: state => state.asyncListValues
})
},

mounted () {
// ** I need asyncListValues to be defined before this runs **
this.asyncListValues.forEach((val) => {
// do stuff
});
}
}

How can I make my component wait for asyncListValues to load, before loading my component?

Solution :

The way to do it is to store state values.

For example, if the store relies on single API, you would do something like this. However, for multiple APIs, it’s a good idea to store each api load state individually, or using a dedicated object for each API.

There are usualy 4 states that you can have, which I prefer to have in a globally accessible module:

// enums.js
export default {
INIT: 0,
LOADING: 1,
ERROR: 2,
LOADED: 3
};

Then, you can have the variable stored in the vuex state, where the apiState is initialized with INIT. you can also initialize the array with [], but that shouldn’t be necessary.

import ENUM from “@/enums”;
// store.js
export default new Vuex.Store({
state: {
apiState: ENUM.INIT,
accounts: [],
// …other state
},
mutations: {
updateAccounts (state, accounts) {
state.accounts = accounts;
state.apiState = ENUM.LOADED;
},
setApiState (state, apiState) {
state.apiState = apiState;
},
},
actions: {
loadAccounts ({commit) {
commit(‘setApiState’, ENUM.ERROR);
somFetchInterface()
.then(data=>commit(‘updateAccounts’, data))
.catch(err=>commit(‘setApiState’, ENUM.ERROR))
}
}
});

Then, by adding some computeds, you can toggle which component is shown. This show the benefit of using state, since you can easily identify the Error state, and show a loading animation when state is not ready.

<template>
<ChildComponent v-if=”apiStateLoaded”/>
<Loader v-if=”apiStateLoading”/>
<Error v-if=”apiStateError”/>
</template>
<script>
import ENUM from “@/enums”;
export default {
computed: {
…mapState({
apiState: state=> state.apiState
}),
apiStateLoaded() {
return this.apiState === ENUM.LOADED;
},
apiStateLoading() {
return this.apiState === ENUM.LOADING || this.apiState === ENUM.INIT;
},
apiStateError() {
return this.apiState === ENUM.ERROR;
},
})
}
</script>

Alternatively, if you just initialize the asyncListValues in the store with an empty array [], you can avoid errors that expect an array.

Solution 2:

One approach would be to split the component into two different components. the new parent component could handle fetching the data and rendering the child component once the data is ready.

ParentComponent.vue

<template>
<child-component v-if=”asyncListValues && asyncListValues.length” :asyncListValues=”asyncListValues”/>
<div v-else>Placeholder</div>
</template>
<script>
export default {
computed: {
…mapState({
asyncListValues: state => state.asyncListValues
})
}
}
</script>

ChildComponent.vue

export default {
props: [“asyncListValues”],
mounted () {
this.asyncListValues.forEach((val) => {
// do stuff
});
}
}

Solution 3:

Since you mentioned vue-router in the question, you can use beforeRouteEnter which is made to defer the rendering of a component.

For example, if you have a route called “photo”:

import Photo from “../page/Photo.vue”;

new VueRouter({
mode: “history”,
routes: [
{ name: “home”, path: “/“, component: Home },
{ name: “photo”, path: “/photo”, component: Photo }
]
});

You can use the beforeRouteEnter like this:

<template>
<div>
Photo rendered here
</div>
</template>
<script>
export default {
beforeRouteEnter: async function(to, from, next) {
try {
await this.$store.dispatch(“longRuningHttpCall”);

next();
} catch(exception) {
next(exception);
}
}
}
</script>

What it does is, waiting for the action to finish, updating the state like you want, and then the call to next() will tell the router to continue the process (rendering the component inside the <router-view></router-view>).

Tell me if you need an ES6-less example (if you do not use this syntax for example).

You can check the official documentation of beforeRouteEnter on this page, you will also discover you can also put it at the route level using beforeEnter.

[Vue.js] window is not defined vuejs and vuetify SSR Subscribe to RSS

getting error while adding/integrating Vuetify like.. import Vuetify from ‘vuetify/lib’ Vue.use(Vuetify) in main.js

main.js

import Vuetify from ‘vuetify/lib’
Vue.use(Vuetify)

Solution :

change loader in webpack from

………
module: {
rules: [
{
test: /\.styl$/,
loader: [‘style-loader’, ‘css-loader’, ‘stylus-loader’]
},
…..

to

………
module: {
rules: [
{
test: /\.styl$/,
loader: [‘css-loader’, ‘stylus-loader’]
},
…..

remove ‘style-loader’ loader

to install loaders

npm i stylus-loader css-loader –save-dev

[Vue.js] Vue js form binding for label and radio button Subscribe to RSS

when trying to produce a list of forms that are polls dynamically from the data. However using :for or v-bind:for doesn’t produce any html markup in the browser so the labels aren’t selecting the relative input when clicked. there is created a JSFiddle (SCSS wont work in JS Fiddle for some reason). Also the project is a Nuxt build.

Code:
https://jsfiddle.net/mc4rdle/o19bgjpe/2/

Markup:

<div class=”option” v-for=”answer in poll.answers” :key=”answer.answer.id”>
<input type=”radio” :id=”answer.id” :value=”answer.answer”>
<label class=”option” :for=”answer.id”>
<div class=”indicator”></div>
<div class=”label”>{ answer.answer }</div>
</label>
</div>

Data:
polls: [

{
id: 1,
question: ‘How do you feel about the current salary?’,
answers: [
{
id: 1,
answer: ‘Satisfied’
},
{
id: 2,
answer: ‘Content’
},
{
id: 3,
answer: ‘Unhappy’
}
]
},
{
id: 2,
question: ‘What group activity should we do??’,
answers: [
{
id: 1,
answer: ‘Yoga’
},
{
id: 2,
answer: ‘Table Tennis’
},
{
id: 3,
answer: ‘Pints’
}
]
}
]

Thanks in advance :)

Solution :

the input id is duplicated because it based only on answer’s id. You can make it unique by combine both poll.id + ‘-‘ + answer.id

<div class=”option” v-for=”answer in poll.answers” :key=”answer.answer.id”>
<input type=”radio” :id=”poll.id + ‘-‘ + answer.id” :value=”answer.answer” :name=”poll.id”>
<label class=”option” :for=”poll.id + ‘-‘ + answer.id”>
<div class=”indicator”></div>
<div class=”label”>{ answer.answer }</div>
</label>
</div>

Demo on jsfiddle

[Vue.js] Dynamics inputs, the v-model update all values in v-for Subscribe to RSS

I try this following code with Vue.js 2:

<div id=”app”>
<div v-for=”(item, index) in items”>
<div>
<input type=”text” v-model=”items[index].message”>
<input type=”text” v-model=”items[index].surface”>
</div>
</div>
<button @click=”addNewfield”>Add</button>
</div>

var app = new Vue({
el: ‘#app’,
data: {
item: {
message: ‘test’,
surface: 45
},
items: [],
},
mounted() {
this.items.push(this.item)
},
methods: {
addNewfield() {
this.items.push(this.item);
}
}
})

The goal is to create news input when user click on Add button. I tried different ways like :

<input type=”text” v-model=”item.message”>

But it doesn’t work. If you write in “message” input, all “message” inputs will be updated.

How can I only updated the concerned value ?

Thanks for help !

Solution :

This is happening because objects in Javascript are stored by reference. This means that every time you push this.item onto the array, it’s adding a reference to the exact same object as the last.

You can avoid this by creating a new object each time:

methods: {
addNewfield() {
const obj = {
message: ‘test’,
surface: 45
}
this.items.push(obj);
}
}

Another option would be to clone the original object each time like:

methods: {
addNewfield() {
const clone = Object.assign({}, this.item);
this.items.push(clone);
}
}

[Vue.js] Vue.js router with Ruby on Rails routes Subscribe to RSS

I’m currently working on a application with a Ruby on Rails backend and Vue.js frontend. It’s a single page application. I’m using the webpacker gem to build my main js file.

I’ve added vue-router and and a couple frontend routes. I’m able to navigate using <router-link> which correctly renders the appropriate component. What I can’t figure out is how do I setup my frontend routes so that someone can directly navigate to a url without hitting my rails routes.

For example if I type /sample-route I’d like to hit my Vue.js route and not my rails route. I still want to be able to make api calls to my rails routes as well. For example /api/users.

Any help is appreciated.

Solution :

Depending on how many routes you have, you can add the vue.js routes to routes.rb and send them to the root vue.js application route. e.g. Webpacker is rendering the js pack with controller#action vue_controller#app. the vue.js app router uses /user/profile. In routes.rb, add a route:

get “/user/profile” => “vue_controller#app” # <- The controller action rendering the vue.js pack

If it seems unmaintainable to redefine every vue.js route in routes.rb, you may want to look into a universal fallback route that sends them to the vue.js app controller action. As long as you don’t change the route, but just respond with the vue.js controller action, the vue.js router will take care of rendering the right components for that route when the page loads.

In Rails 4, you can use something like the answers in this SO question to help you out with setting up a “catch-all” route Rails catch-all route.

EDIT: Using a catch all route does lead to some problems with 404’s. If the user requests a route that doesn’t exist, the Rails app will still send them the vue.js pack. To fix this, you would need to add some unknown route handling in the vue.js router to render something like a 404 page.

Solution 2:

My problem was solved by adding <router-view></router-vew> into my main Vue.js component.

Here’s my rails routes file as well:

Rails.application.routes.draw do
namespace :api do
# api routes here
end

root ‘application#index’
get ‘/*path’, to: ‘application#index’
end