Software

Is it idiomatic to update a property of a prop, without an event?

Vuejs - Tue, 2017-08-29 19:37

I pass the list of inputs as a prop,

v-for input in inputProps v-model input.value

Should I be using events, instead of v-model?

Passing an event to manually update a property of a value in a list would involve

[index]'path to property', would it not?

Categories: Software

How to Initialize Data Properties with Prop Values

Vuejs - Tue, 2017-08-29 18:05

Still a little bit young in VueJS but I'm loving every bit of it. But now, fixated somewhere.
I want to initialize some values in data() using values passed via props. This is so that I can be able to mutate them later on, since it is not recommended to mutate props inside a component. In fact the official docs recommend this property initialization using prop values as shown below:

{ props: ['initialCounter'], data: function () { return { counter: this.initialCounter } }

I have something like the one below:

<template> <div class="well"> <!-- Use Prop value directly on the template: works (but of no help in initializing data) --> Department: {{department.name}} <!-- Use prop value but gotten via computed property: Works inside the template but not in the initialization --> Department: {{fetchDepartment.name}} <!-- Use the array I initialized with the prop value: Does not work --> Department: {{this_department.name}} </div> </template> <script> export default { name: 'test', props: ['department'], data() { return { this_department: this.department // below does not work either //this_department: this.fetchDepartment } }, created() { // shows empty array console.log(this.department) }, mounted() { // shows empty array console.log(this.department) }, computed: { fetchDepartment() { return this.department } } } </script>

As seen in the commented sections above, the initialization is not successful. Neither does the value of this.department appear either from the created() or the mounted() hooks. And note, I can see it is defined using the Chrome Vue Devtools. So my question is, how exactly should I initialize data() attributes using props values, or which is the best way of going around this issue?

Categories: Software

Props not being assigned to data() attribute in Vue

Vuejs - Tue, 2017-08-29 17:26

I am creating a Vue component, which should refresh restaurants depending on user dynamically selected filters.

Therefor I have to update the filteredRestaurants in the data() function of my Vue component. However, at first, when the Vue component is rendered, it takes the restaurant information from the "restaurants" prop.

I have tried to insert the "restaurants" into the filteredRestaurants data attribute to set it as a default value. Unfortunatelly then the stores wouldnt show at tall, as if the "restaurants" prop is inserted after the filteredRestaurants is assigned its value.

My question is, how can i get the "restaurants" prop into filteredRestaurants so that I can later on, re-render the Vue component when the user changes the filters.

<template lang="html"> <div class="test"> <Filters></Filters> <div> <ul class="o-list c-stores"> <Result v-bind:total="restaurants.length" v-bind:open="isOpen" v-on:toggle="toggleRestaurantList"></Result> <li v-for="(restaurant, index) in restaurants" class="c-stores__location" :class="{'first': isFirst(index), 'last': isLast(index, restaurants)}"> <Location :index="index" :store="restaurant" :link="() => setCurrentRestaurant(restaurant)"></Location> </li> </ul> </div> </div> </template> <script> import eventHub from './../../event-hubs/storefinder' import Location from './Location' import Filters from './Filters' import Result from './Result' export default { props: ["restaurants", "isOpen", "currentSearch"], data() { return { attributes : [], // Here I am assigning the prop filteredRestaurants : this.restaurants } }, head: { title: function () { return { inner: this.$t('storefinder.overview') } }, meta: function functionName() { return [{ name: 'og:title', content: this.$t('storefinder.overview') + ' - ' + this.$t('storefinder.name'), id: "og-title" }, { name: 'description', content: this.$t('storefinder.description'), id: "meta-description" }, { name: 'og:description', content: this.$t('storefinder.description'), id: "og-description" }, ] } }, components: { Location, Filters, Result }, methods: { toggleRestaurantList() { eventHub.$emit('showRestaurantList'); }, setCurrentRestaurant(restaurant) { this.trackRestaurantSelect(restaurant.publicNameSlug); this.$router.push({ name: "store", params: { restaurant: restaurant.publicNameSlug } }); }, trackRestaurantSelect(restaurantName) { dataLayer.push({ 'event': 'GAEvent', 'eventCategory': 'restaurants', 'eventAction': 'clickResult', 'eventLabel': restaurantName, 'eventValue': undefined, 'searchTerm': this.currentSearch && this.currentSearch.toLowerCase(), 'amountSearchResults': 1 }); }, created() { eventHub.$on('addFilterTheRestaurants', (attribute) => this.attributes.push(attribute)); eventHub.$on('removeFilterTheRestaurants', (attribute) => this.attributes = this.attributes.filter(item => item !== attribute)); }, isLast: function (idx, list) { return idx === list.length - 1; }, isFirst: function (idx) { return idx === 0; }, } } </script>

The only way this worked, was when I had the filteredRestaurants as a function which returned "restaurants", and I called it inside the Vue template:

filteredRestaurants(){ return this.restaurants }

Any help appreciated.

Categories: Software

Vue js method with argument and setTimeout

Vuejs - Tue, 2017-08-29 16:41

I can't figure out why this code works..

data: { return { userMinerals: 0, mineralsLimit: 1000, miners: 0, superMiner: 0, minerPrice: 10, superMinerPrice: 100, minersLimit: 10 } } methods: { counter() { setInterval(() => { this.userMinerals += this.miners; if(this.checkLimit(this.userMinerals, this.mineralsLimit)) { this.userMinerals = this.mineralsLimit; } }, 100); }, addMiner() { if (this.userMinerals >= this.minerPrice) { this.miners += 1; this.userMinerals -= this.minerPrice; this.counter(); } } }

.. but if I try to put parameters into counter() the code stops working

methods: { counter(typeOfCredits) { setInterval(() => { typeOfCredits += this.miners; if(this.checkLimit(this.userMinerals, this.mineralsLimit)) { typeOfCredits = this.mineralsLimit; } }, 100); }, addMiner() { if (this.userMinerals >= this.minerPrice) { this.miners += 1; this.userMinerals -= this.minerPrice; this.counter(this.userMinerals); } } }

From the console I can see that typeOfCredits gets incremented as it should but it doesn't update the value in the view. Thx for help

Categories: Software

Directive v-if doesn't work when changing tab

Vuejs - Tue, 2017-08-29 15:43

I'm trying to build a simple listing system that shows a list of items for different platforms, each platform is on a seperate tab . I created the tab switching logic via VueJS from scratch .

What I'm doing:

Basically I have two platforms : twitter and facebook, when user click on one of the tabs, the frontend send an ajax request to my server to fetch posts for that platform and render them via v-for .

I added a button called edit for each post, when user press it , it calls a function edit(p), where p is the current post that user want to edit .

in edit(p) I change an atrribute p.editing which using v-if shows a text area and a timepicker (I'm using flatpicker) for that post .

What's Wrong:

All this works fine when I'm on the first tab, but once I switch the tab, it stop working, after debugging I noticed that v-if is not working event p.editing is updated when edit(p) is called, here's the code :

var posts_app = new Vue({ el: "#posts_app", data: { platforms : ['facebook','twitter'], current_tab: { 'facebook' : true, 'twitter': false }, platform_posts: { 'facebook': [], 'twitter': [] }, posts: undefined, }, methods:{ showTab: function(i){ platform = this.platforms[i] // UI stuff : to make the clicked tab active for(p in this.current_tab){ if(p == platform){ this.current_tab[p] = true } else{ this.current_tab[p] = false } } // Show content by platform this.posts = this.platform_posts[platform] }, edit: function(p){ p.editing = true console.log(p) Vue.nextTick(function(){ document.getElementsByClassName("dt-input")[0].flatpickr({enableTime : true}); }) }, save: function(p){ p.editing = false } }, created(){ self = this posts_loaded = false for(var i = 0;i < this.platforms.length; i++){ (function(index){ self.$http.get('/fan/posts',{params:{platform : self.platforms[index]}}).then(function(resp){ self.platform_posts[self.platforms[index]] = resp.body posts_loaded = true })//Promise of Ajax call }// Closure body )(i)//Closure } this.showTab(0) }, delimiters: ['[[',']]'] })

and my basic html template :

<div class = "panel-body"> <img class = "pull-right responsive" v-bind:src = "p.image"/> <textarea v-if = "p.editing" class = "post-text-input" v-model = "p.text"></textarea> <p class = "post-text" v-if = "!p.editing">[[p.text]]</p> <p class = "post-source" v-if = "p.type == 'article'"> Source : [[post_source(p)]]</p> <p class = "post-time"><b>Scheduled on <i v-if = "!p.editing">[[p.time]] </i></b> <input placeholder="Choose a date and a time" class = "flatpickr dt-input" v-model = "p.time" v-if = "p.editing" /> </p> </div> <div class = "panel-footer clearfix"> <button class = "btn btn-danger">Delete</button> <button class = "btn btn-info pull-right" @click = "edit(p)" v-if = "!p.editing">Edit</button> <button class = "btn btn-success pull-right" @click = "save(p)" v-if = "p.editing">Save</button> </div>

Code explanation:

So, when a tab is clicked, showTab(index) is called where index is the number of tab, if index is 0 then we switched to facebook tab, if it's 1 then we're in the twitter tab, we send an AJAX request to get the posts for that current platform (tab) and fill it in platform_posts[current_platform], we then render them via v-for . All of this is working like a charm .

Second part, when user click on the edit button for a given post, it replace the text paragraph element with a textarea using v-model to keep track of change and update the time paragraph with an input which acts as datetime picker via flatpickr library . Basically this lib can turn any input into a datetime pickr using this line of code :

elemnt.flatpickr({config_options})

Where element is an HTML element . You can notice that I'm using Vue.nextTick, this is to make sure that the input is not hidden anymore (it shouldn't be since p.editing is updated) . All of this work like a charm when I'm on the first tab, the problem is that when I switch the tab it stop working .

Here's a gif I made to show you the error : http://imgur.com/a/QME4P

As you can see, the behaviour is very weird, it works perfectly on the twitter tab and it's weird on the facebook tab .

Categories: Software

App language: state or setting?

Vuejs - Tue, 2017-08-29 15:08

Should I have the app language in the:

  • app's store and all the app reactive to the store's state (eventual server side rendering of strings included)
  • settings (ie: not changeable in the front-end), so the language strings and all server side differences are loaded on a page reload, and if we need to change it back a reload might be necessary

Is the answer to this based in opinions or is there a clear way to take this decision and which are the technical reasons for the choice?

My own experience is to use as a setting, mostly because of a older paradigma (MVC, static pages, etc...), before state stores in the front end and the possibility to re-render the app with JavaScript without having to reload it.

Categories: Software

No 'Access-Control-Allow-Origin'

Vuejs - Tue, 2017-08-29 15:06

I face this problem:

XMLHttpRequest cannot load http://localhost:8000/scripts/advaced_donwload/advancedUpload/vueupload/store.php. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access.

This is my code:

storeMeta(file) { var fileObject = this.generateFileObject(file) return new Promise((resolve, reject) => { this.$http.post('http://localhost:8888/vueupload/store.php', { name: file.name }).then((response) => { fileObject.id = response.body.data.id resolve(fileObject) }, () => { reject(fileObject) }) }) }
Categories: Software

How to break axios promise with conditional?

Vuejs - Tue, 2017-08-29 14:46

In a vue.js app, I have this part that deals with the fetching data for unlimited pagination:

fetchData() { this.loading = true this.page++; axios.get(this.BASE_URL + '/api/jokes/'+'?page='+this.page).then( response => this.jokes = response.data) .then( if (this.jokes.length == null) {throw new Error("end of pagination")} ) .catch(function (error) { }); document.body.scrollTop = document.documentElement.scrollTop = 0; this.loading = false; },

I want to stop rendering empty jokes and break out of the function if the response is empty. As you can see in the code abouve, I put a conditional in another then, but get error on the if:

Module build failed: SyntaxError: Unexpected token (169:20)

So I'm wondering what's the correct way to achieve this?

Categories: Software

When I change router-link not wokring jquery

Vuejs - Tue, 2017-08-29 14:34

When I change router-link, my plugins not working in vue component, but when I refreshing page the first time working, but I go another page and come back the page, plugins not working

Categories: Software

How to get selected value from components in vuejs

Vuejs - Tue, 2017-08-29 13:48

I am currently using https://github.com/Bubblings/vue-date-picker in my project. The src code is exactly like this: https://github.com/misterGF/CoPilot/blob/master/src/components/views/Setting.vue and you can the datepicker working in this page: https://copilot.mistergf.io/setting

So, basically this is the code:

<template lang="html"> <div class=""> <div class="input-group"> <span class="input-group-addon"> <i class="fa fa-fw fa-calendar"></i> </span> <datepicker :readonly="true" format="MMM/D/YYYY" id="dateInput" width="100%"></datepicker> </div> </div> </template> <script> import datepicker from 'vue-date-picker' export default { name: 'Settings', components: { datepicker }, computed: { datetime () { return new Date() } }, methods: { clearInput (vueModel) { vueModel = '' } } } </script> <style> .datetime-picker input { height: 4em !important; } </script> <style lang="css"> </style>

So, I am not sure once someone selects a date, how to get that inside my computed property or methods

Categories: Software

Webpack mix, Vue - output files on cdn subdomain

Vuejs - Tue, 2017-08-29 13:31

I am struggling with webpack. I want to have the compiled files in public-cdn folder. However, the following code creates files in several different locations. Including E:\cdn. Chunks, app.js, css files - everything in different location.

Paths:

main folder: www/Project
laravel public: www/Project/public
cdn folder: www/Project/public-cdn

webpack.mix.js

mix.webpackConfig({ output : { path : '/public-cdn/', publicPath : 'http://cdn.ywg.localhost/', chunkFilename : 'js/[name].js' }, }); mix.sass('resources/assets/sass/styles.scss', '../public-cdn/css') .options({processCssUrls: false }); mix.sass('resources/assets/sass/invoice.scss', '../public-cdn/css') .options({processCssUrls: false }); mix.js('resources/assets/js/frontApps.js', '../public-cdn/js') .extract(['vue']);

I tried experimenting with Path and PublicPath parameters. PublicPath doesn't seem to work at all.

Categories: Software

export 'default' (imported as 'Three') was not found in 'three'

Vuejs - Tue, 2017-08-29 13:20

Overview In main.js, add

import Three from 'three'

Vue.use(Three)

Start dev server with npm run dev. Expected behavior The Vue project should load without errors. Actual behavior The dev server gives this warning:

warning in ./src/main.js 7:8-14 "export 'default' (imported as 'Three') was not found in 'three'

And the browser's js console displays the error:

Uncaught TypeError: Cannot read property 'installed' of undefined at Function.Vue.use (eval at <anonymous> (app.js:723), <anonymous>:3443:15) at eval (eval at <anonymous> (app.js:778), <anonymous>:14:45) at Object.<anonymous> (app.js:778) at __webpack_require__ (app.js:660) at fn (app.js:84) at Object.<anonymous> (app.js:964) at __webpack_require__ (app.js:660) at app.js:709 at app.js:712
Categories: Software

VueJS dont display input value if its 0

Vuejs - Tue, 2017-08-29 12:57

I have a input field that gets pre populated from my DB, but I wont want it to be pre filled if the value is 0

Eg:

<input v-model="price" type="text">

If

data: { price: 0 }

I dont want my input field to display 0, I know that I can do stuff like :disabled="price == 0" but this will hide the whole inputfield, I just dont want to display the value if its 0

Categories: Software

VueJS's transitions and CSS animations

Vuejs - Tue, 2017-08-29 12:30

I'm trying to implements a transition between two elements containing CSS animations simply by following the documentation's example.

My HTML contains : A button to change my state :

<button @click="toggled = !toggled"> Toggle class ({{ toggled }}) </button>

The transition with the two loader (a red and a black one) :

<transition name="fade" mode="out-in"> <div class="loader" v-if="toggled" key="toggled"></div> <div class="loader red" v-else key="notToggled"></div> </transition>

It appears that the VueJS's transition is waiting for the animation to finish before displaying the next. Am I doing something wrong ?

Reproduce the issue : https://jsfiddle.net/f2vozp35/2/

Categories: Software

Get element where Event is binded

Vuejs - Tue, 2017-08-29 12:15

I am binding an event to an element either using @click property in Vue (it behaves the same as javascript .onclick property).

The problem I have is when the event is called by propagating from the child DOM nodes click events I get the child DOM element as target property and I cannot find a way a clean way (without searching for the parents, as the element might me nested deep inside) to access the DOM element that the event was registered onto inside the event callback.

<td @click="onCellClick($event)"> <div class="text"> <span>default</span> </div> </td>

Categories: Software

How to render div's dynamically in Vue?

Vuejs - Tue, 2017-08-29 11:45

I want to add button on my page. When we click that button, above generates div where we can add photo. When we click twice, we have two divs etc. The problem is that my code is not generating... How I can achieve this?

And another question. How I can add +1 to identifier while adding another div?

<div v-for="row in rows" class="row"> <div v-model="test" class="col-3"> <photo :upload_url="" :parent="this" identifier="image01"></photo> </div> </div> <button type="button" class="button btn-primary" @click="addRow()">Add row</button> addRow() { this.rows.push({ test: "" <-- I DON'T KNOW WHAT TO DO HERE }); }
Categories: Software

Webpack+Babeljs cannot transpile ES6

Vuejs - Tue, 2017-08-29 11:41

I am building a javascript web application using vue-cli.

I noticed there is some const keywords in the compiled javascript code. And the browser said SyntaxError: Unexpected keyword 'const'. Const declarations are not supported in strict mode

The compiled code looks like:

"use strict"; eval("/*blabla*/ const xxx ...");

My babelrc:

{ "presets": [ ["env", { "modules": false, "targets": { "browsers": ["> 1%", "last 2 versions", "not ie <= 8"] } }], "stage-2" ], "plugins": ["transform-runtime"], "env": { "test": { "presets": ["env", "stage-2"], "plugins": ["istanbul"] } } }

The babel-loader configuration file is like:

{ test: /\.js$/, loader: 'babel-loader', include: [resolve('src'), resolve('test')] },
Categories: Software

Mapping JSON responses to model classes in Vue.js

Vuejs - Tue, 2017-08-29 11:15

Is there a best practice or de-facto library for Vue.js when it comes to mapping JSON API responses to "real" javascript Model objects? Coming from iOS Development, there are excellent libraries like JSONModel and MagicalRecord dealing with exactly this matter.

Most Vue.js tutorials/examples I could find just seem to work with the plain JSON responses. IMHO, this gets cumbersome real quick. For instance, when dealing with raw data like date strings which would be better of as real Date objects. So it involves some sort of (de)serialization functionality. Also, it'd be nice to have stuff like Foo.findAll(), Foo.findById(1) or foo.save() to create appropriate calls to the backend service.

I found vue-model which looks promising, but it doesn't seem to have a lot of traction. This makes me wonder, if mapping JSON to objects is just not something a lot of people do in their SPAs? What are alternative approaches?

Categories: Software

vue-i18n : how to use inside vue instance filter

Vuejs - Tue, 2017-08-29 11:14

I want to use a filter to perform translations.
Problem is that 'this' doesn't point to my vue instance inside my filter function.

This is what I currently have.

inside my template I have this:

<p>{{ parking.status | translate }} </p>

inside my component I have this:

new Vue({ ... filters: { translate: function(value, vue) { return this.$i18n.t('MLAA-47'); }

The error I get is that this == undefined.
How do i point it to my vue instance inside my filter function ?

Categories: Software

What is the difference between watch and computed methods in vuejs

Vuejs - Tue, 2017-08-29 11:01

They both seem to do the same thing, and I can't tell when to use which

Categories: Software

Pages