Feed aggregator

Vue.js component not registering event

Vuejs - Fri, 2017-09-01 18:09

I am working on a small progress bar component using Vue.js. On the vm-progress component, the computed properties work as expected. However, on the three buttons, the increase_progress method is not being called. After installing the vue.js browser extension, no events are registered. I have tried adding debug and print statements without any luck.

<template> <div class="progbar"> <a class="app-task-title" style="text-align:center;">Text</a> <div class="app-bar"> <vm-progress :percentage="calc_percentage" :text-inside="true" :stroke-width="18" ></vm-progress> </div> <button v-on:click="increase_progress(5)" class="prog-bar-button" id="five_button" >+5m</button> <button @click="increase_progress(10)" class="prog-bar-button" id="ten_button" >+10m</button> <button v-on:click="increase_progress(30)" class="prog-bar-button" id="thirty_button" >+30m</button> </div> </template> <script type="text/javascript"> import Progress from 'vue-multiple-progress' export default { data (){ return { completed_minutes:0, total_minutes:60, percent_complete:0 }; }, components :{ 'vm-progress': Progress }, methods:{ increase_progress: function(minutes){ this.completed_minutes += minutes this.completed_minutes%=(this.total_minutes + 1); if((this.completed_minutes >= this.total_minutes) || (this.completed_minutes < 0)){ return } } }, computed:{ calc_percentage: function(){ return Math.round((100.0*this.completed_minutes)/this.total_minutes); } } } </script> <style > .progbar{ border: 2px solid #000000; height: auto; width: 90%; margin-right: 5%; margin-left: 5%; display: grid; grid-template-columns: 10% 81% 3% 3% 3%; grid-template-rows: 25px; align-items: center; justify-content: center; } .prog-bar-button{ font-family:Verdana; font-size: 10px; display: flex; align-items: center; justify-content: center; } .app-task-title{ grid-column-start: 1; grid-column-end: 2; font-size: 20px; text-align:center; vertical-align: middle; display:inline; } .app-bar{ grid-column-start: 2; grid-column-end: 3; align-self: center; } .progbar #five_button{ grid-column-start: 3; grid-column-end: 4; } .progbar #ten_button{ grid-column-start: 4; grid-column-end: 5; } .progbar #thirty_button{ grid-column-start: 5; grid-column-end: end; } </style>
Categories: Software

What is the worker.js file produced by vue.js?

Vuejs - Fri, 2017-09-01 18:04

Using Vue.js + vue.cli + webpack, I run npm run build, which creates a dist/ directory with my index.html and dist/static/ which contain all of the compiled JS, CSS, and other static assets. However, it also produces a file at e.g. dist/c93aff04b4ee373cfcc0.worker.js. Not loading this file does nothing to hinder the functionality of the application. Questions:

  • What is this file and what does it do?
  • Why is it so large (over half a Megabyte)
  • Why isn't it in dist/static/ with the rest of the JavaScript that is produced by the compiler?
Categories: Software

Why are Vue.js builds so huge?

Vuejs - Fri, 2017-09-01 18:01

I use Vue.js + vue-cli + webpack to create SPA's. The build sizes it produces are staggeringly large compared to the source I create. I recognize that a whole lot of library code is pulled in, but is there any way to optimize it further. As an example, my 200KB of templates and JavaScript, produces 2.1MB in JavaScript code alone! Is there anything that can be done to optimize this?

Categories: Software

Vue.js + git build process

Vuejs - Fri, 2017-09-01 17:57

I use vue.js + vue-cli + webpack to build my applications. During development I will run npm run dev to have webpack continuously watch my sources, compile everything, and reload the browser. To create production build, I can simply run npm run build. I would like to do this in a way that when I make a git commit, if my sources have changed, the build is created automatically.

My current approach is to simply use git pre and post commit hooks to automatically run npm run build and add the built files to the commit. This has the following downsides:

  • Even if other parts of the repo are changed, I re-run the build process for the Vue app, and it takes a very long time.
  • It makes resolving merge conflicts nearly impossible.
  • It creates a lot of cruft in the repo, ballooning its size

Typically I use a Vue.js frontend with a Django backend in the same repo, and deploy to Heroku or similar via a git push. What other methods are out there for accomplishing this task that don't have the above downsides?

Categories: Software

A 'Beats Per Minute' calculator seems less accurate in Vue.js

Vuejs - Fri, 2017-09-01 17:32

I'm trying to create a 'beats per minute' (BPM) calculator, identical (for now) to the one you can find here. But for some reason, when I use the BPM calculator at that link on a test song, it gets within 1 BPM of the actual value of 85.94 within of 7 keypresses and just gets more accurate from there, ending within 0.05 of the actual BPM, whereas with my (essentially identically-coded) Vue.js version, it starts much higher (182-->126-->110) and goes down from there, but even after 60 keypresses it's still off by ~2 BPM, and after a full song, it was still off by about 0.37 BPM.

Here's the code for the plain-JavaScript version at that link:

var count = 0; var msecsFirst = 0; var msecsPrevious = 0; function ResetCount() { count = 0; document.TAP_DISPLAY.T_AVG.value = ""; document.TAP_DISPLAY.T_TAP.value = ""; document.TAP_DISPLAY.T_RESET.blur(); } function TapForBPM(e) { document.TAP_DISPLAY.T_WAIT.blur(); timeSeconds = new Date; msecs = timeSeconds.getTime(); if ((msecs - msecsPrevious) > 1000 * document.TAP_DISPLAY.T_WAIT.value) { count = 0; } if (count == 0) { document.TAP_DISPLAY.T_AVG.value = "First Beat"; document.TAP_DISPLAY.T_TAP.value = "First Beat"; msecsFirst = msecs; count = 1; } else { bpmAvg = 60000 * count / (msecs - msecsFirst); document.TAP_DISPLAY.T_AVG.value = Math.round(bpmAvg * 100) / 100; document.TAP_DISPLAY.T_WHOLE.value = Math.round(bpmAvg); count++; document.TAP_DISPLAY.T_TAP.value = count; } msecsPrevious = msecs; return true; } document.onkeypress = TapForBPM; // End -->

And here's my version:

computed: { tappedOutBpm: function() { let totalElapsedSeconds = (this.timeOfLastBpmKeypress - this.timeOfFirstBpmKeypress) / 1000.0 let bpm = (this.numberOfTapsForBpm / totalElapsedSeconds) * 60.0 return Math.round(100*bpm)/100; }, }, methods: { tapForBPM: function() { let now = new Date; now = now.getTime(); // let now = window.performance.now() if (this.timeOfFirstBpmKeypress === 0 || now - this.timeOfLastBpmKeypress > 5000) { this.timeOfFirstBpmKeypress = now this.timeOfLastBpmKeypress = now this.numberOfTapsForBpm = 1 } else { this.timeOfLastBpmKeypress = now this.numberOfTapsForBpm++ } } }
Categories: Software

Vue $route is not defined in App.vue

Vuejs - Fri, 2017-09-01 16:26

I'm trying to get the name of the current route in my App.vue but all I get it's a null response.

In my App.vue:

export default { created() { console.log(this.$route.name) } }

In my ./router/index.js:

import Vue from 'vue' import Router from 'vue-router' Vue.use(Router) const Hero = () => import ('../components/Hero.vue') const Home = () => import('../pages/Home.vue') const Videos = () => import ('../pages/Videos.vue') const VideosYoutube = () => import ('../pages/VideosYoutube.vue') const VideosFacebook = () => import ('../pages/VideosFacebook.vue') const VideosTwitter = () => import ('../pages/VideosTwitter.vue') const test = () => import('../pages/Example.vue') const routes = [{ name: 'home', path: '/', component: Home }, { name: 'videos', path: '/videos', components: { default: Videos, hero: Hero } }, { name: 'videos-youtube', path: '/videos/youtube', components: { default: VideosYoutube, hero: Hero } }, { name: 'videos-facebook', path: '/videos/facebook', components: { default: VideosFacebook, hero: Hero } }, { name: 'videos-twitter', path: '/videos/twitter', components: { default: VideosTwitter, hero: Hero } }, { name: 'test', path: '/test', component: test }] export default new Router({ mode: 'history', routes })

I'm using Vue 2, Vue-Router 2 and webpack + babel es2015 presets.

It's weird because when I use the Vue Devtools, in my App component I can see the route object. On site.dev/videos:

Vue Devtools screenshot

And, finally, if I try to log this.$router I get an empty route like {name: null, meta: {…}, path: "/", hash: "", query: {…}, …}...

Here someone says to not use es6 style functions but it doesn't sound like a good solution and I don't really know how to do that.

Categories: Software

How can I bind checkbox values to a null object in VueJS?

Vuejs - Fri, 2017-09-01 16:26

I'm trying to store all the selected checkbox items in a property.

This is a 'generic' property in one of my object models, it holds all different types of data.

This property is initialized as null, so Vue doesn't understand that it's supposed to be an array. So it only ever binds one checkbox value to this property.

When I initialize this property using [] to declare it as array, it works as intended. However the objects are passed down externally as JSON so initializing them as array is not an option.

var working = new Vue({ el: "#a", data: { options: ["Apple", "Banana", "Citrus"], answers: [], //<- I'm unable to do this in my scenario } }); var notWorking = new Vue({ el: "#b", data: { options: ["Apple", "Banana", "Citrus"], answers: null } });

Here is a quick JSfiddle I made showcasing what I mean.

https://jsfiddle.net/ojvfy39p/12/

What adjustments must I make to the "Non working example" to achieve what the "Working example" does? I'

Categories: Software

Listen to events from parent component in child and execute child’s method in vue without hub

Vuejs - Fri, 2017-09-01 14:37

There seems to be a lot of discussion around this topic such as Stackoverflow answer using hub, Stackoverflow answer using refs, so I really like to ask experts to provide for once a clear concise answer to this question. If the answer is also just not possible please state that!

Here is the scenario: There are two components, a parent and a child

<Parent> // There is a button here that can be clicked to emit an event using 'this.$emit()' <Child></Child> // The child listens and once hears the event, it does something </Parent> What to be achieved?

Clicking the button in the Parent emits a certain event, the child will be constantly listening and once it hears the event it executes an action, such as calling a method of its own.

What is out there about this so far?
  1. Using a hub, in Vue Hub it is clearly stated this is for Non Parent-Child Communication, so what is the point in using it for a parent-child communication?

  2. Using Refs, which is given as an end solution when it is not possible to use props and events. So why it is not possible with events at first place?

My own thought

It seems to me the firing of an event and listening to it is only possible from child to parent, basically one way communication. The parent is able to emit an event but child component(s) are not able to capture the event. Why? I tried this and didn’t work:

In the parent component I have (triggered by clicking a button in the parent component):

methods: { generateCharts: function () { this.$emit('generate-charts') console.log('charts generated') }

In the child component I have:

mounted () { this.parent.$on('generate-charts', function () { console.log('event captured') // Here nothing gets logged to the console }) }
Categories: Software

How to access the getter from another vuex module?

Vuejs - Fri, 2017-09-01 13:47

Within a vuex getter I know it is possible to access the state from another vuex module like so:

pages: (state, getters, rootState) => { console.log(rootState); }

How can I access a getter from another vuex module instead of the state though?

I have another vuex module called filters that I need to access, I have tried this:

rootState.filters.activeFilters

Where activeFilters is my getter but this does not work. using rootState.filters.getters.activeFilters also does not work.

Categories: Software

How to send data from web to api?

Vuejs - Fri, 2017-09-01 12:47

Sorry for question but I don't understand that.

I have this:

<a @click.prevent="Submit(0)" href="#">NO</a> <a @click.prevent="Submit(1)" href="#">OK</a>

Now in my vue method submit I want to post value 0 or 1 to my api and then store it in database. I have controller UserVote and model Vote. I am green here.

I must send it like this:

submit(value){ this.$http.post('/user/vote', JSON.stringify(WHAT HERE?)).then(response => { toastr.success(response.body.data[0]); if(response.body.redirect) { window.location.href = response.body.redirect; } }, response => { if(response.status == 422) { opinion = response.body.data; } else if(response.status == 401) { toastr.error(response.body.data.message); } }); }

How my link should do? Where I post that? How I can upload that to db? I need just know, then I will be know everything.

Categories: Software

Eventbus in Vue.js isn't updating my component

Vuejs - Fri, 2017-09-01 12:35

I have two components and I want to display what the user enters in one on the other component. I don't really want to use a state manager like vuex because it's probably a bit overkill as it's a small application

this is my main.js:

import Vue from 'vue' import App from './App.vue' import VueRouter from 'vue-router'; import { routes }from './routes'; export const EventBus = new Vue(); Vue.use(VueRouter); const router = new VueRouter({ routes, mode: 'history' }); new Vue({ el: '#app', router, render: h => h(App) })

Component that emits the event called addHtml.vue

<template> <div> <h1>Add HTML</h1> <hr> <button @click="navigateToHome" class="btn btn-primary">Go to Library</button> <hr> Title <input type="text" v-model="title"> <button @click="emitGlobalClickEvent()">Press me</button> </div> </template> <script> import { EventBus } from '../../main.js' export default { data: function () { return { title: '' } }, methods: { navigateToHome() { this.$router.push('/'); }, emitGlobalClickEvent() { console.log(this.title); EventBus.$emit('titleChanged', this.title); } } } </script>

the file that listens for the event thats emitted and to display what was entered on the other component:

<template> <div> <h1>Existing Items</h1> <hr> <p>{{ test }}</p> </div> </template> <script> import { EventBus } from '../main.js'; export default { data: function () { return { test: '' } }, created() { EventBus.$on('titleChanged', (data) => { console.log('in here!',data); this.test = data; }); } } </script>

the console.log('in here!',data); inside the listener gets printed out to the console so I know it's picking it up however {{ test }} doesn't get updated to what the user enters when I click back onto the component to view if it was updated, it just remains blank? Any Ideas?

Categories: Software

declare onended event in a child of vuejs template

Vuejs - Fri, 2017-09-01 12:20

In my template of a custom music player I have a html5 tag child, is what play music, and I want to request next song after end, I think that put all the onended event inside the templete isn't a good practice and I want how to make this correctly.

Here it is the template:

<template> <footer id="player" class="player"> <progress min="0" max="1" value="0" ref="progress"></progress> <div class="div-player"> <i class="material-icons play-button player-button" >skip_previous</i> <i class="material-icons play-button player-button" v-on:click="togglePause">play_circle_outline</i> <i class="material-icons play-button player-button" >skip_next</i> <audio ref="audioTag" :src="source" autoplay preload="none" @timeupdate="onTimeUpdateListener"></audio> <a class=".primary-text-color" style="text-align: center; font-size: small;">{{ title }}</a> </div> <!-- <progress min="0" max="1" value="0" ref="progress"></progress> --> </footer> </template>

I started by putting the listener into the component logic but wasn't work. Any help with this??

Categories: Software

Float 1000.00 is smaller than 999.00, why is this? Vue Javascript [duplicate]

Vuejs - Fri, 2017-09-01 12:10

This question already has an answer here:

I have 2 floats:

console.log(parseFloat(this.bid).toFixed(2)); console.log(parseFloat(this.highestBid.bid).toFixed(2));

Output:

enter image description here

if(parseFloat(this.bid).toFixed(2) <= parseFloat(this.highestBid.bid).toFixed(2)) { // triggers this }

Why is this If statement triggering? 1000.00 is clearly larger than 999.50...

This only happens when this.bid gets 1000 or larger.

if this.bid is 999.51 it works perfectly.

Why is this happening?

Categories: Software

Using custom components as router-link tag in Vue

Vuejs - Fri, 2017-09-01 11:50

I'm trying to make the following Vue component work:

<template> <div> <cx-button href="/new"> Create </cx-button> <router-link tag="cx-button" to="/new" class="cx-raised">Create</router-link> </div> </template> <script> import cxButton from '../elements/cxButton/cxButton'; export default { // ... components: { cxButton } } </script>

But it throws: [Vue warn]: Unknown custom element: <cx-button> - did you register the component correctly? For recursive components, make sure to provide the "name" option. found in ---> <RouterLink>.

Name of the button element is provided.

cx-button component is rendered fine by itself, same for router-link without using cx-button as value in tag property. The question is: what should I do to make router-link use custom elements, such as my button, as its tag?

Categories: Software

VueJs input previsualization, does not change my data inside FileReader listener

Vuejs - Fri, 2017-09-01 11:23

I'm new to VueJs and currently designing a image picker component. I'm struggling with the file uploaded event, as my mutable properties doesn't want to update inside the event listener.

There's a part of the template code:

<input @change="handleUpload" type="file" :name="imageName" /> <img :src="mutableImageString" alt="Image" class="img-responsive" />

And the logic :

handleUpload: function (e) { var reader = new FileReader(); var file = e.target.files[0]; reader.onload = function () { this.mutableImageString = file; } if (file) { reader.readAsDataURL(file); } },

mutableImageString isn't updated, however if I take it out of the onload event, it's updated but with an empty value. Any idea? Thanks!

PS: Sorry about my poor english :c

Categories: Software

Tag <slot> cannot appear inside <table> due to HTML content restrictions. It will be hoisted out of <table> by the browser

Vuejs - Fri, 2017-09-01 11:19

I am new to vuejs, While running the following code I am getting the error mentioned at the bottom. Please suggest what should I change.

<template> <div class="panel panel-default"> <div class="panel-body"> <table class="table table-striped"> <thead> <tr> <th v-for="item in thead"> <div class="dataviewer-th" @click="sort(item.key)" v-if="item.sort"> <span>{{item.title}}</span> <span v-if="params.column === item.key"> <span v-if="params.direction === 'asc'">&#x25B2;</span> <span v-else>&#x25BC;</span> </span> </div> <div v-else> <span>{{item.title}}</span> </div> </th> </tr> </thead> <tbody> ----52----- <slot v-for="item in model.data" :item="item"></slot> </tbody> </table> </div> <div class="panel-footer pagination-footer"> <div class="pagination-item"> <span>Per page: </span> <select v-model="params.per_page" @change="fetchData"> <option>10</option> <option>25</option> <option>50</option> </select> </div> </div> </div> </template> <script> //some code </script>

While running the above code I am getting the following error

ERROR in ./resources/assets/js/components/valuechain/DataViewer.vue 51 | <tbody> 52 | <slot v-for="item in model.data" :item="item"></slot> | ^ 53 | </tbody>

Tag cannot appear inside due to HTML content restrictions. It will be hoisted out of by the browser

Categories: Software

Momentjs used in Vue displays UTC time, but local time expected

Vuejs - Fri, 2017-09-01 11:11

The momentjs documentation says: 'By default, moment parses and displays in local time.' (https://momentjs.com/docs/#/parsing/utc/).

If I display the output of moment() directly via javascript, thats indeed the case:

<div id="divLocal"> </div> document.getElementById("divLocal").innerHTML = moment();

Output: Fri Sep 01 2017 10:56:45 GMT+0200

If I do the same using Vuejs, it shows UTC time:

<div id='app'> <span>{{datenow}}</span> </div> new Vue({ el: '#app', data: { datenow: '' }, methods: { time() { var self = this; this.datenow = moment(); }, }, mounted: function() { this.time(); } });

Output: 2017-09-01T09:02:38.169Z

Example: https://jsfiddle.net/nv00k80c/1/

Someone has an idea why this is happening? If I use moment().format() in Vue, the output is also correct. But I wonder where and why there is a difference?

Categories: Software

Submit a form in vue. How do I reference the form element?

Vuejs - Fri, 2017-09-01 11:00

I want to do a classic form submission from my Vue page, from a method. I don't want to use an input type=submit. How do I reference the form element in the page from my method? Surely I don't have to do document.getElementById()?

Categories: Software

router-link replace with vue-router?

Vuejs - Fri, 2017-09-01 10:37

With the router-link tag with vue-router, "Setting replace prop will call router.replace() instead of router.push() when clicked, so the navigation will not leave a history record", according to the docs. But this doesn't seem to be happening for me, so I think I must be misunderstanding something. I have a navigation menu in my SPA and the router-link in each menu item has a replace prop. Yet when I click on each menu item in turn, it clearly does add to the history, in that the back button takes me back to the previous item, and I can actually see in the Firefox history the list of URLs being added to. What am I doing wrong?

Categories: Software

What vue.js hook do I need to use to validate an internal variable on page load?

Vuejs - Fri, 2017-09-01 10:17

I want to display an error message if necessary when a page loads. The only way I can get this to work is to call the validation method from outside the Vue instance.

Is there an internal hook that I could be using instead?

http://jsfiddle.net/edwardtanguay/ahd34a3v

HTML: <div id="app"> <input v-model="startTime" v-on:keyup="validateTime(startTime)"/> <div> {{errorMessage}} </div> </div> JavaScript: var vm = new Vue({ el: '#app', data: function() { return { startTime: 'hello', errorMessage: '' } }, mounted: function() { this.validateTime(startTime); }, methods: { validateTime: function(time) { this.errorMessage = 'the length is ' + time.length; } } }); // vm.validateTime(vm.startTime); //WORKS BUT IS NOT IN AN INTERNAL HOOK
Categories: Software

Pages