Software
nuxt build --spa vs nuxt generate
What is the difference between
nuxt build --spavs
nuxt generateI am trying to compile three different variations:
1. regular nuxt with ssr 2. prerendered spa 3. spa without prerenderingI am struggling to find the appropriate commands for it
List rendering key
The documentation states that list rendering using v-for without key is
only suitable when your list render output does not rely on child component state or temporary DOM state (e.g. form input values).
Will the following code cause problems if itemArray is modifed using splice/push/pop?
<div v-for="item in itemArray"> ... <textarea v-bind:value="item.value" v-on:input="item.value = $event.target.value"> </textarea> ... </div>If not, what is an example where there would be a problem?
Difference between scoped CSS and "scope" by adding a parent class
When building an app using vue, vue-loader and the official boilerplate I noticed scoped css is used to limit the CSS to the current component. I don't see the point in this. I have always "scoped" css by defining it inside a wrapper class when I have felt the need for it.
For example in SASS:
.some-module { h1, h2 { font-weight: normal; } ul { list-style-type: none; padding: 0; } li { display: inline-block; margin: 0 10px; } a { color: #42b983; } }So what do i gain from using scoped CSS instead? Or is it merely just another method to achieve the same thing?
how to hot reload component with ts and vue-property-decorator
Every code I changed on the .ts file will trigger the browser refresh, and I do not want it work this way. I have tried many solutions like "vue-ts-loader", "vue-hot-reload-api",..., but I have not found a good one. How you guys fixed this issue?
Update the View of a web application from a DynamoDB update
Just wondering if anyone has done something like this. I'll add some context.
So there are two applications. A mobile app and a Vue.js web application which acts as a static DevOps board. The mobile app makes an updated to the DynamoDB table which the DevOps board should be listening too and updated the view. Like a live reload. I want to try and stay away from a timer of sorts to make a call to the DB again and pull down the objects.
I know Firebase acts like a live reload of data but I want to try and just use AWS unless someone has done something like this before.
Thanks
Can't load static files inside Vue.js component
I have component Login.vue and inside its template I paste
<img src="logo.png">The catalog structure is the same as here: https://vuejs-templates.github.io/webpack/static.html
I got static folder inside src folder.
I try many diffrent combinations like
<img src="src/assets/logo.png"> <img src="assets/logo.png">When I try to write with a dot prefix (absolute path)
<img src="./src/assets/logo.png">I got and error from babel compiler: Module not found: Error: Can't resolve './logo.png'
Getting Google Maps to work with Vue.js
I'm trying to get Google maps working with Vue.js.
This is the html I am using:
<strong>Map</strong><br> <div id="map-container"> <div id='location-map'></div> </div> ... <script src="https://maps.googleapis.com/maps/api/js?key=MYKEY"></script>and my Vue binding:
if(document.getElementById("map-container")) { const mapVue = new Vue({ el: '#map-container', data: { defaultLatLng: {lat: 37.5665, lng: 126.9780} }, mounted: function() { var map = new google.maps.Map(document.getElementById('location-map'), { zoom: 15, center: this.defaultLatLng, scrollwheel: false, disableDoubleClickZoom: true, panControl: false, streetViewControl: false, draggable: false }); var marker = new google.maps.Marker({ position: this.defaultLatLng, map: map }); } }) }But the map is not displaying. Am I doing something incorrectly here?
Thanks in advance!
Axios and vue-resource put method doesn't work
I have on front vuejs and on backend java. In one component I bring the users from the database.
Users.vue
getUsers() { this.$http.get("/user") .then((response) => { this.users = response.data.users; }) }Still here I use v-for to bring all users in another component User.vue.
<app-user v-for="user in users" :user="user" :key="user.index"></app-user>In user component I have a router link that takes me to another page where I can edit the username.
User.vue
<p class="user-name">{{user.firstName}}</p> <router-link :to="'/users/edit-user/'+user.id"> <a ><i class="ti-pencil-alt" aria-hidden="true"></i></a> </router-link>EditUser.vue
<template> <input type="text" :value="user.firstName" v-model="userInfo.firstName"> </template> <script> export default { data() { return { user: {}, userInfo: { firstName: '', } } }, created() { this.getUsers(); }, methods: { getUsers() { this.$http.get("/user/" + this.$route.params.id) .then((response) => { this.user = response.data; }) }, updateUser() { axios.put('/user', this.userInfo, {'headers':{'X-AUTH-TOKEN':localStorage.token}}, {'headers':{'Content-Type': 'application/json'}}) .then((response) => { console.log("Success! You edited the user"); }) .catch((response) => { console.log('Error in edit'); }) } }, } </script>I started learning vuejs a month ago and still have to learn :).
In the input I use :value="user.firstName" to bring the value for firstName that already exists. I try to use v-model="userInfo.firstName" to get new value for userName, but when I put this, the value, that existed already, disappears from the input.
To save data with post works fine but only with axios. I don't know why post doesn't work with vue-resource. So I tried put with axios too, but what I edit when I press save button, on EditUser.vue, my request doesn't go to server.
I say this because I saw that in the backend I don't get any error, nothing, but if I use post or get I can get or save users.
What do I do wrong in my code that I don't edit the user?
Vue removing wrong HTML node in dynamic list of components
I'm experimenting with Vue.JS and composing components together with dynamically.
There's a strange issue where although it seems to be updating the data correctly, if I remove one of the boxes with the call to splice() it always removes the last item in the rendered HTML.
Here's an example fiddle. I'm testing in Chrome.
https://jsfiddle.net/afz6jjn0/
Just for posterity, here's the Vue component code:
Vue.component('content-longtext', { template: '#content-longtext', props: { model: { type: String, required: true }, update: { type: Function, required: true } }, data() { return { inputData: this.model } }, methods: { updateContent(event) { this.update(event.target.value) } }, }) Vue.component('content-image', { template: '#content-image', }) Vue.component('content-list', { template: '#content-list-template', props: { remove: { type: Function, required: true }, update: { type: Function, required: true }, views: { type: Array, required: true } }, methods: { removeContent(index) { this.remove(index) }, updateContent(index) { return (content) => this.update(index, content) }, }, }) Vue.component('content-editor', { template: '#content-editor', data() { return { views: [ {type: 'content-longtext', model: 'test1'}, {type: 'content-longtext', model: 'test2'}, {type: 'content-longtext', model: 'test3'}, {type: 'content-longtext', model: 'test4'}, {type: 'content-longtext', model: 'test5'}, ], } }, methods: { newContentBlock(type) { this.views.push({type: 'content-longtext', model: ''}) }, updateContentBlock(index, model) { this.views[index].model = model }, removeContentBlock(index) { this.views.splice(index, 1) }, }, }) let app = new Vue({ el: '#app' })Vue.js unit tests axios-mock-adapter never called
testing the following spec with axios-mock-adapter
actions.spec.js
import actions from '@/vuex/actions' import * as types from '@/vuex/mutation_types' import axios from 'axios' import MockAdapter from 'axios-mock-adapter' describe('actions.js', () => { var mockAdapter, store, lists beforeEach(() => { // mock shopping lists lists = [{ id: '1', title: 'Groceries' }, { id: '2', title: 'Clothes' }] // mock store commit and dispatch methods store = { commit: (method, data) => {}, dispatch: () => { return Promise.resolve() // static method }, state: { shoppinglists: lists } } sinon.stub(store, 'commit') mockAdapter = new MockAdapter(axios) mockAdapter.onGet('http://localhost:3000/shoppinglists').reply(() => { console.log('SERVER ON GET: ') return new Promise((resolve, reject) => { setTimeout(() => { if (Math.random() > 0.1) { console.log('lists: ', lists) resolve([ 200, lists ]) } else { // reject() reason will be passed as-is. // Use HTTP error status code to simulate server failure. resolve([ 500, { success: false } ]) } }, 1000) }) }) }) afterEach(() => { // restore stubs and mock server store.commit.restore() mockAdapter.restore() }) describe('populateShoppingLists', () => { it('should call commit method with POPULATE_SHOPPING_LIST string parameter', () => { return actions.populateShoppingLists(store).then(() => { expect(store.commit).to.have.been.calledWith(types.POPULATE_SHOPPING_LISTS, lists) }) }) }) })as I can see in the following debug log, mockAdapter.onGet() is never called ( so not returning the spec lists), instead the axios instance is called and returning the db content...
what's wrong in my code ? thanks for feedback
console
... LOG LOG: 'ACTION POPULATE: ' LOG LOG: 'API FETCH SHOPPINGLISTS' LOG LOG: 'API RETURNED: ', [Object{title: 'TESTS', items: [..., ...], id: 3}, Object{title: 'LAST TEST', items: [..., ...], id: 4}] 1) should call commit method with POPULATE_SHOPPING_LIST string parameter actions.js populateShoppingLists AssertionError: expected commit to have been called with arguments POPULATE_SHOPPING_LISTS, [{ id: "1", title: "Groceries" }, { id: "2", title: "Clothes" }] POPULATE_SHOPPING_LISTS [{ id: 3, items: [{ checked: false, text: "Bananas" }, { checked: true, text: "Apples" }], title: "TESTS" }, { id: 4, items: [{ checked: true, text: "boots" }, { checked: true, text: "pants" }], title: "LAST TEST" }] [{ id: "1", title: "Groceries" }, { id: "2", title: "Clothes" }] at webpack:///test/unit/specs/vuex/actions.spec.js:75:42 <- index.js:17581:43 at <anonymous>actions.js
import * as types from './mutation_types' import api from '../api' import getters from './getters' export default { populateShoppingLists: ({ commit }) => { console.log('ACTION POPULATE: ') return api.fetchShoppingLists() .then(response => { console.log('API RETURNED: ', response.data) commit(types.POPULATE_SHOPPING_LISTS, response.data) }) .catch(e => { console.log('POPULATE ERROR : ', e) }) } }api/index.js
import { HTTP } from './http-common' export default { fetchShoppingLists: () => { console.log('API FETCH SHOPPINGLISTS') return HTTP.get('shoppinglists') } }api/http-common.js
import axios from 'axios' export const HTTP = axios.create({ baseURL: 'http://localhost:3000/' })Vue.js component with dynamic template (e.g. eventhandler)
lets say I made a compontent called test and inserted this into my html like so:
<test :data="foo"></test>How can I achieve that the on-click attribute value changes into the property value 'data'?
Vue.component('test', { props: ['data'], template: '<div v-on:click="type={{data}}"></div>' });Just to outline my expectations - this is what I am looking for:
<test :data="bar"></test>renders to
<div v-on:click="type='bar'"></divBTW: Thanks to everyone participates here in SO :)
Eventsource problems with webpack and vuejs
I'm making my own blog using express and vuejs. In login.vue, I found that websites redirected to localhost:8080/?#/login after i pushed 'submit button' in Chrome. (It works perfect in Firefox) so I had to log in 'twice' in order to sign in.
after post 'request', following errors occur before (response) => { ... }
EventSource failed loading : GET "localhost:8080/__webpack_hmr" XHR failed loading: POST "localhost:8080/login" Navigated to localhost:8080/?
but funny thing is after redirected to /?#/login, it worked successful. I just want to know about why this errors occured. I guess it might be Webpack error but I don't know how to fix it.
<template> <div id="app"> <div class="alert alert-primary" role="alert" v-if="showAlert"> <h4 class="alert-heading">{{alertStatus ? "Success":"Warning"}}</h4> <p>{{alertMsg}}</p> </div> <div v-if="!isLogged"> <form> <ul class="nav nav-pills justify-content-center"> <li class="nav-item"> <a class="nav-link" v-bind:class="{ active: logMode }" v-on:click="changeMode">Sign In</a> </li> <li class="nav-item"> <a class="nav-link" v-bind:class="{ active: regMode }" v-on:click="changeMode">Sign Up</a> </li> </ul> <div class="form-group" key="email"> <input type="email" class="form-control" id="email" v-model="email" aria-describedby="emailHelp" placeholder="Enter email"> <small id="emailHelp" class="form-text text-muted">We'll never share your email with anyone else.</small> </div> <div class="form-group" v-if="regMode" key="email2"> <input type="email" class="form-control" id="emailConfirm" v-model="emailConfirm" placeholder="Enter email again"> </div> <div class="form-group" v-if="regMode" key="nick"> <input type="text" class="form-control" id="nickname" v-model="nick" placeholder="Enter nickname"> </div> <div class="form-group" key="password"> <input type="password" class="form-control" id="password" v-model="password" placeholder="Password"> </div> <div class="form-check" key="check"> <label class="form-check-label"> <input type="checkbox" class="form-check-input"> Check me out </label> </div> <button v-on:click="submit" class="btn btn-primary">{{isMode}}</button> </form> </div> <div v-else> <span> Already Signed in. </span> </div> </div> </template> <script> export default { name: 'login', computed: { logMode: function () { if (this.isMode === 'Login') return true else return false }, regMode: function () { if (this.isMode === 'Register') return true else return false } }, methods: { changeMode: function () { if (this.isMode === 'Login') this.isMode = 'Register' else if (this.isMode === 'Register') this.isMode = 'Login' }, submit: function () { console.log('submit on') if (this.isMode === 'Register') { this.$http.post('/register', { email: this.email, nick: this.nick, password: this.password }) .then((response) => { console.log('get response!') }) .catch(function (error) { console.log(error) }) } else { if (this.email) { console.log('email exist') this.$http.post('/login', { email: this.email, password: this.password }) .then((response) => { console.log('hello response!', response.data) var token = response.data.token if (token) { console.log('param test: ', this.email, response.data.nick, token) this.isLogged = true this.token = token } }) .catch(function (error) { console.log(error) }) } } } }, data () { return { email: '', emailConfirm: '', nick: '', password: '', showAlert: false, alertMsg: '', alertStatus: false, isLogged: false, isMode: 'Login', token: '' } } } </script> <style> #login{ margin: 50px; } .nav{ width: 320px; padding: 10px; } .inputs-move { transition: all 1s; } .inputs-item { display: inline-block; } .inputs-enter-active, .inputs-leave-active { transition: all 1s; } .inputs-enter, .inputs-leave-to { opacity: 0; transform: translateY(-30px); } </style> also source codes are in https://github.com/Azurepeal/kajarga
Vue2 render showing symbols at the begining
I am working on a project that uses Laravel 5.4 & Vue2 (Laravel Socialite) to render messages with Pusher. I am trying to fix several "bugs" and here is one I was not able to fix yet:
I have this function on a Vue element:
showChatBox : function(conversation) { indexes = $.map(this.chatBoxes, function(thread, key) { if(thread.id == conversation.id) { return key; } }); if(indexes[0] >= 0) { console.log('prevented second opening of chat box'); } else{ this.$http.post(base_url + 'data/' + conversation.id).then( function(response) { if(response.status) { var chatBox = JSON.parse(response.body).data; chatBox.newMessage = ""; chatBox.user = conversation.user; chatBox.minimised = false; this.chatBoxes.push(chatBox); vm = this; setTimeout(function(){ vm.autoScroll('.chat-conversation'); },100) } }); } },I tried to "debug" the chatBoxes element with: console.log(vm.chatBoxes[0].conversationMessages.data[5].body);
And with the Vue Tools for Firefox and I see the message (for example):
how are you?
The original way to render it on the HTML:
<div class="chat-box" v-bind:class="[chatBox.minimised ? 'chat-box-small' : '', ]" v-for="chatBox in chatBoxes"> <!-- Chats Boxes --> <div class="chat-box-header"> <span class="side-left"> <a href="@{{ chatBox.user.username }}" target="_blank">@{{ chatBox.user.name }}</a> </span> <ul class="list-inline side-right"> <li class="minimize-chatbox"><a href="#"><i class="fa fa-minus" @click.prevent="chatBox.minimised ? chatBox.minimised=false : chatBox.minimised=true" aria-hidden="true"></i></a></li> <li class="close-chatbox"><a href="#" @click.prevent="chatBoxes.$remove(chatBox)" ><i class="fa fa-times" aria-hidden="true"></i></a></li> </ul> </div> <div class="chat-conversation scrollable smooth-scroll"> <ul class="list-unstyled chat-conversation-list"> <li class="message-conversation" v-bind:class="[({{ Auth::id() }}==message.user.id) ? 'current-user' : '', ]" v-for="message in chatBox.conversationMessages.data"> <div class="media"> <div class="media-left"> <a href="#"> <img v-bind:src="message.user.avatar" alt="images"> </a> </div> <div class="media-body "> <p class="post-text"> @{{ message.body }} <- important line </p> </div> </div> </li> </ul> </div> <div class="message-input"> <fieldset class="form-group"> <input class="form-control" v-model="chatBox.newMessage" v-on:keyup.enter="postMessage(chatBox)" id="exampleTextarea" > </fieldset> <!-- <ul class="list-inline">this fields are hidden because in dev 1.0 we dont use this fuctionality ,if we enable this the height of chat list to be increased <li><a href="#"><i class="fa fa-camera-retro" aria-hidden="true"></i></a></li> <li><a href="#"><i class="fa fa-smile-o" aria-hidden="true"></i></a></li> </ul> --> </div> </div>When it is rendered, it has the symbols in the wrong side:
?how are you
I also tried to render that with <p v-html="message.body"></p> but it looks the same. What should I do?
Thanks in advance.
VueJS slots with v-for loop do not display proper elements
I'm trying to create a component that displays a subset of items passed to it.
So far I have a 'sublist' component with named slots as follows:
... data: () => ({ startItem : 0 }) ... <template> <div> <slot v-for="ctr in maxItems" :name="'s-' + (ctr + startItem - 1)"></slot> </div> </template>In the parent I do the following:
<sublist :max-items="5"> <div v-for="(i,index) in items" :slot="'s-'+index"> {{index}} </div> </sublist>When it loads, everything renders fine:
0 1 2 3 4
However when I increment startItem in the sublist component, the output becomes:
5 1 2 3 4
So it removes the 0th slot and stuffs slot 5 in its place. What is a proper way to replace the slots or make them "dynamic"? I'm using VueJS 2.4.2
Vue: Component :prop="object[key]" aren't reactive
I'm trying to bind a value from an Object into the prop of a Component, but it isn't reactive. I'm even using $this.set, but it doesn't work at all. Here's my template:
<div class="grid"> <emoji-card v-for="name in shuffledEmoji" :name="name" :ticked="tickedEmoji[name]" :key="name" @click="tickEmoji(name)" /> </div>- shuffledEmoji: Array<String>
Here, tickedEmoji is an Object with keys being strings, and values being Booleans. tickEmoji just sets tickedEmoji[name] for that name to be true:
methods: { tickEmoji (name) { this.$set(this.tickedEmoji, name, true) } },That method gets called fine, but the Component doesn't notice the changes.
Child component:
<template> <div class="card" @click="$emit('click')"> <img draggable="false" :src="`/static/blobs/${name}.png`"> <img v-show="ticked" class="green-tick" draggable="false" src="/static/ui/green_tick.png"> </div> </template> <script> export default { name: 'emoji-card', props: ['name', 'ticked'] } </script>What am I doing wrong here? The child component never gets updated whenever tickEmoji is called.
Editing a form with save and cancel options
I'm new to VueJS. I'm trying to create a form with simple Save and Cancel functionality. When binding the model to form fields they get updated immediately as the inputs are changed, but I don't want that tight binding. Instead, I want to be able to save when the "Save" button is pressed and revert the changes when the "Cancel" button is pressed.
What's the suggested Vue way of doing this? Thanks!
See in JSFiddle
<template> <div id="app"> <div> First Name: <input type="text" v-model="user.firstName" :disabled="!isEditing" :class="{view: !isEditing}"> </div><div> Last Name: <input type="text" v-model="user.lastName" :disabled="!isEditing" :class="{view: !isEditing}"> </div> <button @click="isEditing = !isEditing"> {{ isEditing ? 'Save' : 'Edit' }} </button> <button v-if="isEditing" @click="isEditing = false">Cancel</button> </div> </template> <script> var app = new Vue({ el: '#app', data: { isEditing: false, user: { firstName: 'John', lastName: 'Smith' } } }) </script> <style> .view { border-color: transparent; background-color: initial; color: initial } </style>Vue.js - uncheck radio button
I'm trying to set up a simple Vue instance with a collection of radio buttons. The goal is that, if the user clicks on a radio button that is already checked, it will uncheck the respective radio button. But I couldn't do this using Vue yet. Here's my code so far:
HTML:
<div id="app"> <div v-for="(val, key) in list"> <input type="radio" name="radio" :value="val" v-model="selected" :id="val"> <label :for="val" @click="uncheck( val )">{{ val }}</label> </div> <button @click="uncheckAll">Uncheck all</button> </div>JS:
var app = new Vue({ el: '#app', data : { list: [ 'one', 'two', 'three' ], selected: 'two', }, methods : { uncheck: function( val ){ console.log( val, this.selected ); if ( val == this.selected ){ this.selected = false; } }, uncheckAll: function(){ this.selected = false; } } })Seems like the uncheck method is called, but then the radio button triggers a change event and then updates the value of selected again. uncheckAll method works as expected, probably because it's not tied to the data using v-model.
Any tips or suggestions to make this work? Here's a pen I created for this example: https://codepen.io/diegoliv/pen/JrPBbG
Vuex: Tracking Mutations On Object/Class Properties
I'm currently attempting to track mutations on properties in other JS classes or objects, currently changes aren't being broadcasted to views that include them, while other properties defined in the state object are broadcasted when mutated.
Vuex Store: export default new Vuex.Store({ state: { audio: new Audio() }, getters: { duration: state => { return state.audio.duration }, currentTime: state => { return state.audio.currentTime } } }); Vue Template <template> <div> {{ currentTime }} :: {{ duration }} </div> </template> <script> export default { name: 'component', computed: { currentTime() { return this.$store.getters.currentTime }, duration() { return this.$store.getters.duration } } } </script>Current Time and Duration is always is always "0" in the template. Is there a built-in mechanisms to track these mutations, or will I need to write a custom solution, such as unfortunately needing to examine the currentTime every second (if the audio is active)
Vue2: Custom Directive Like v-if
I'm trying to create a custom directive like v-if so it will only render if the data being passed into the element isn't empty. For example:
<div v-if="!_.isEmpty(data.employer)">{{ data.employer.name }}</div>This will render only if data.employer isn't empty so it won't throw a reference error. I'm trying to create a directive that will simplify this to just v-notEmpty="data.employer" and run the logic inside the directive but the issue is that it's doing the hook on the custom directive after the element is being rendered so it throws the reference error that employer is undefined.
Is there any way to get a custom directive to work exactly like the v-if which runs the logic before the element is actually created. This is what I had so far:
Vue.directive('notEmpty', (el, binding) => { if (_.isEmpty(binding.value)) { el.style.display = 'none'; } else { el.style.display = 'initial'; } });VueJs adding new key to object reference issue
I have an issue when adding a new key to an object and then dynamically modifying the fields associated.
For example add a new column, set column name to "url", then attempt to update the value of url for row 1. In my example the value does not actually update even though the field has v-model="row[field.name]. Is there something I should do to make sure row[field.name] is changed when field.name changes
Code: https://codepen.io/RuttyJ/pen/zdgbPB
<table> <thead> <tr> <template v-for="(field, f) in fields"> <th> <flex-row> <flex-column style="width: 100%;"> <flex> <input type="text" :value="field.name" @input="updateField(f, 'name', $event.target.value)" style="width:100%"> </flex> <flex style="width: 100%;"> <select :value="field.type" @change="updateField(f, 'type', $event.target.value)" style="width:100%"> <option v-for="fieldType in fieldTypeOpts" :value="fieldType.value" :selected="fieldType.value == field.type">{{fieldType.label}}</option> </select> </flex> </flex-column> <flex> <button @click="removeField(f)" style="height:100%;">X</button> </flex> </flex-row> </th> </template> <td> <button @click="newField()">+</button> </td> </tr> </thead> <tbody> <tr v-for="(row, r) in rows"> <td v-for="field in fields"> <template> <template v-if="'checkbox' == field.type"> <input type="checkbox" style="float:right;" v-model="row[field.name]" > </template> <input type="number" v-else-if="'number' == field.type" style="width:100%" :value="row[field.name]" @input="updateRow(r, field.name, $event.target.value)"> <input type="text" style="width:100%" v-else v-model="row[field.name]"> {{field.name}} <pre>{{field}}</pre> <pre>{{row}}</pre> </template> </td> <td><button @click="removeRow(r)">X</button></td> </tr> </tbody> <tfoot> <tr> <td v-for="(field, i) in fields"> </td> <td> <button @click="newRow()">+</button> </td> </tr> </tfoot> </table>FYI i tried both with v-model and value/update()