Software

vuejs custom directive does not seem to register

Vuejs - Thu, 2017-08-17 15:36

I am building custom directive, it is stored in its own file

autosize.js and it looks like this:

import Vue from 'vue' import autosize from 'autosize' Vue.directive('autosize', { bind: function() { console.log('autosize bind') var self = this Vue.nextTick(function() { autosize(self.el) }) }, update: function(value) { console.log('autosize update') var self = this Vue.nextTick(function() { self.el.value = value autosize.update(self.el) }) }, unbind: function() { autosize.destroy(this.el) } })

I use it inside file component and import it like this:

import Autosize from 'components/directives/autosize.js'

register it like this:

directives: { Autosize }

Inside my file component i try to use it like this :

<textarea v-autosize="input" :value="input" @input="update" class="form-control">{{input}}</textarea>

Autosize is a plugin that is supposed to make textarea grow, ofcourse nothing happens when i test adding more text. But it seems that its not autosize that fails to work but perhaps I have missed something, not even these get printed:

console.log('autosize bind') console.log('autosize update')

when I dynamically create the component.

Anyone has an idea what I have missed so that directive is not binding or updating?

Categories: Software

Vue v-show update after changing data with method

Vuejs - Thu, 2017-08-17 14:32

I'm iterating over this array of object's and in each object there's a property - keyword.edited which iniitalized with the value - false the all loop looks like this:

<tr v-for="(keyword, index) in keywords"> <td>{{keyword.tag_name}}</td> <td @click="edit_keyword(index)"> <el-input-number v-show="keyword.edited" :step="step" size="small" v-model="keyword.max_bid"></el-input-number> </td> </tr>

now since initalized with false none of the keywords will show. problem is when i click edit_keyword(index) the value of the relevant keyword changes to true:

edit_keyword(index){ this.keywords[index].edited = !this.keywords[index].edited return this.keywords[index].edited }

but the DOM won't update, or in other words the relevant keyword won't show as i expected. any idea how can i achive this one? tried to implement same idea with computed property as well and still didn't work...

Categories: Software

Rate limiting free text search

Vuejs - Thu, 2017-08-17 14:27

I'm using VueJS for the front-end of my application and Laravel for the backend. Where is the best place to reduce calls to the server with a free text search?

Search input 'hello'

@keyup will make 5 server requests

1st = h 2nd = he 3rd = hel 4th = hell 5th = hello

Ideally, I would like to be able to stop server requests until the user has stopped typing, or has delayed presses in keystrokes. That way I would only be sending 1 or 2 requests to the server for each search.

Categories: Software

routing with params in vuejs using router-link

Vuejs - Thu, 2017-08-17 13:50

I am trying to build a spa using vuejs in which I have a list of users now when I click a user it should route to a new page with user details of the particular user how to params the user id in router-link

Categories: Software

reach vuejs property above v-for

Vuejs - Thu, 2017-08-17 11:58

Well, basicly i have a array of items which every item should be rendered in a v-for, this panels has some properties like for example the color, that is the one that is causing me troubles.

I have this code:

<template> <div> <h4 class="text-center">Actions History</h4> <div class="col-md-10"> <div :style="panel.color" class="panel panel-default"> <ul class="list-group"> <li v-for="panel in getPanels" class="list-group-item">A section {{panel.section}} was {{panel.action}}</li> </ul> </div> </div> <div class="col-md-2"> <!-- here lives the buttons--> <div class="btn btn-default">Clear All</div> </div> </div> </template>

important part:

<div :style="panel.color" class="panel panel-default">

the panel.color should be the color of each panel in the list group item, but since the v-for is under it i can't access each element of the list, it is undefined. How can i solve this? is there another way?

Categories: Software

suppressing the v-html wrapping tag

Vuejs - Thu, 2017-08-17 11:53

Consider the following code. I want to toggle an excerpt and description. The code directly below does that, but it means having the <a> outside of the article, and I would prefer it inside.

<article v-if="!toggle" v-html="item.excerpt"></article> <a href="#" v-if="!toggle" @click.prevent="toggle = 1">Read more...</a> <article v-if="toggle" v-html="item.description"></article> <a href="#" v-if="toggle" @click.prevent="toggle = 0">Show less...</a>

It could be rewritten as

<article v-if="!toggle"> <span v-html="item.excerpt"></span> <a href="#" @click.prevent="toggle = 1">Read more...</a> </article> <article v-if="toggle"> <span v-html="item.description"></span> <a href="#" @click.prevent="toggle = 0">Show less...</a> </article>

But that would mean the excerpt/description is wrapped with a <span>. Is there a way to use the v-html directive and not output the wrapping tag?

Categories: Software

Passing Object to props of child component in Vuejs

Vuejs - Thu, 2017-08-17 11:28

I want to pass Object data to a child component in Vue, but when the computed state is invoked the type of prop is String instead of Object. However in the template i can display the first attribute.

Parent component:

<template> <catalog-search-box id="box" :title="$t('parameter')" header-icon-class="fa fa-thermometer-half" :deployed="deployed"> <parameter-search-criteria-content v-bind:model="treeData"></parameter-search-criteria-content> </aeris-catalog-search-box> </template>

The script part:

export default { props: { deployed: { type: Boolean, default: false } }, watch: { lang (value) { this.$i18n.locale = value; } }, destroyed: function() { }, created: function () { this.$i18n.locale = this.lang; }, mounted: function() { }, computed: { }, data () { return { lang: 'en', treeData : { name: 'My Tree', children: [ { name: 'hello' }, { name: 'wat' }, { name: 'child folder', children: [ { name: 'child folder', children: [ { name: 'hello' }, { name: 'world' } ] }, { name: 'hello' }, { name: 'wat' }, { name: 'child folder', children: [ { name: 'hello' }, { name: 'Word' } ] } ] } ] } } }

The child component :

<template> <li class="parameter-search-criteria-content-host"> <div :class="{bold: isFolder}" @click="toggle" @dblclick="changeType"> {{model.name}} <span v-if="isFolder">[{{open ? '-' : '+'}}]</span> </div> <ul v-show="open" v-if="isFolder"> <parameter-search-criteria-content class="item" v-for="model in model.children" :model="model"> </parameter-search-criteria-content> <li class="add" @click="addChild">+</li> </ul> </li> </template>

And in the script, when the computed state is called, it's strange convert model into [Object object] string..

computed: { isFolder: function () { return this.model.children && this.model.children.length }

}

in addition, it's a single file component structure; so components are registered in separate elements (Vue.customElement('parameter-search-criteria-content', ParameterCriteriaContent);

Categories: Software

Vue.js server side rendering for Koa2?

Vuejs - Thu, 2017-08-17 11:06

Is it possible to use Vue.js for server side rendering for Koa2?

Currently this is my setting in my package.json:

"dependencies": { "babel-cli": "^6.24.1", "babel-preset-es2015": "^6.24.1", "ect": "^0.5.9", "koa": "^2.3.0", "koa-combine-routers": "^1.0.0", "koa-router": "^7.2.1", "koa-static": "^4.0.1", "koa-views": "^6.0.2", "mongodb": "^2.2.31" }, "devDependencies": { "mocha": "^3.5.0", "supertest": "^3.0.0" }, "scripts": { "test": "mocha --harmony", "start": "nodemon --exec babel-node --presets es2015 app/index.js" },

I am using ect for rendering my templates, e.g. index template:

<html lang="en"> <head> <meta charset="UTF-8"> <title>Koa</title> <link href="/styles.css" rel="stylesheet"> </head> <body> <h1 class="text-uppercase">Koa</h1> <p><%- @message %></p> </body> </html>

index route:

const index = async(ctx, next) => { const users = ctx.mongo.collection('users') const result = await users.insert({ name: 'haha' }) const userId = result.ops[0]._id.toString() const output = await users.find().toArray() await ctx.render('index', { message: JSON.stringify(output) }); users.remove({_id: new mongo.ObjectID(userId)}) } router.get('/', index) module.exports = router

in my root app.js:

import views from 'koa-views' app.use(views(__dirname + '/views', map: { html: 'ect' // or 'handlebars' }, extension: 'ect' } ))

How can I achieve this with Vue?

Categories: Software

"Undefined" Group Label in Vue-Multiselect?

Vuejs - Thu, 2017-08-17 11:01

I am new to Vue and have improved this code from various tutorials.

However, I am faced with this "Undefined" group name issue here.

.html:

<multiselect v-model="value" :options="options" :multiple="true" track-by="name" :hide-selected="true" :custom-label="customLabel" :searchable="false" placeholder="" group-values="details" group-label="groupDivision" > </multiselect>

.js:

new Vue({ components: { Multiselect: VueMultiselect.default }, data: { value: { groupDivision: 'Government', name: 'Fish', contact: 'Fish@.com' }, options: [ { groupDivision: 'Governemnt', details:[ { name: 'Fish', contact: 'Fish@.com' }, { name: 'Police', contact: 'Police@.com' }, { name: 'Society', contact: 'Society@.com' } ] }, { groupDivision: 'Media', details:[ { name: 'BBC', contact: 'BBC@.com' }, { name: 'CNN', contact: 'CNN@.com' }, { name: 'CBC', contact: 'CBC@.com' } ] }, ] }, methods: { customLabel (option) { return `${option.name}` } } }).$mount('#app')

I've already set the "group-label" but it still shows "undefined".

Does anyone have idea what the problem? Thanks in advance!

enter image description here

Link to the code: https://codepen.io/dennis-leeyinghui/pen/VzybrR

Categories: Software

vue.js best way to update entire array

Vuejs - Thu, 2017-08-17 10:52

What is the best way to update the entire observed array and trigger a rerender in vue.js without having to iterate an push all the items?

I have read the documentation here: https://vuejs.org/v2/guide/list.html#Replacing-an-Array

But it doesn't make sense to me having to filter, concat or slice just to update the array? There must be something I missed?

Categories: Software

TypeError: Cannot read property 'toFixed' of undefined, using Vue with Nodejs

Vuejs - Thu, 2017-08-17 10:37

Steps

  • Create a method in vue, showMessage
  • Create an object message: {show : false, text: 'any text'} in the data section
  • call showMessage from an HTML element using v-on:click='showMessage'
  • In the showMessage function:
    • set the value of 'show' to true using this.message.show = true
    • print the value of 'show' using console.log(this.message.show)

What is expected?

The value of 'show' should set to true without any error/warning

What is actually happening?

I get a warning AND an error on the line:

this.message.show = true

as below:

[Vue warn]: Error in render function: "TypeError: Cannot read property 'toFixed' of undefined" TypeError: Cannot read property 'toFixed' of undefined

However, the line console.log(this.message.show) prints correctly

The issue is not re-producible, when the same button is clicked under other circumstances.

The expected behavior is as shown by the jsFiddle, but I dont see any error running it.

Vue Version: 2.4.2

JSFiddle: https://jsfiddle.net/afshanaman81/50wL7mdz/54338/

Categories: Software

Vue change width and content

Vuejs - Thu, 2017-08-17 10:27

Depending on whether the user is logged in, I need to adjust the size and content of two divs inside my topbar. So if they aren't logged in it should be like this:

<div id='search' width="400px"></div><div id="login" width="200px"><img></div>

And when they're logged in it should be like this:

<div id='search' width="200px"></div><div id="login" width="400px"><div id='somecontent></div><div id='morecontent'></div></div>

I know i can achieve this by hardcoding both of them entirely and then using v-if statements but I was wondering if there was a better way.

Categories: Software

vue.js computed property not triggered

Vuejs - Thu, 2017-08-17 10:01

Vue JS computed property is not triggered With this markup

<!-- language: lang-html --> <p>£{{plant_price}}</p> <div v-if="selected.plant.variations.length > 0 "> <select v-model="selected.plant.selected_variation" class="form-control"> <!-- inline object literal --> <option v-for="(variation, i) in selected.plant.variations" :selected="variation.id == selected.plant.selected_variation ? 'selected' : ''":value="variation.id"> {{variation.name}} </option> </select> </div> <!-- language: lang-js --> var app = new Vue({ el: '#vueApp', data: { selected: { type: {a: '' , b: ''}, vehicle: '', plant: { } }, computed: { plant_price: function() { if (this.selected.plant.variations.length > 0 ) { var variant = _.find(this.selected.plant.variations, {id: this.selected.plant.selected_variation }); return variant.price; } else { return this.selected.plant.price; } } ...

selected.plant is populated via Ajax. I have checked through the debugger, and can see that all the correct properties are available.

selected:Object type:Object vehicle: "Truck" plant:Object id:26 price:"52" regular_price:"100" selected_variation:421 variations:Array[2] 0:Object id:420 name:"small" price:52000 regular_price:52000 1:Object etc...

I have a computed property, which should update the plant_price based on the value of selected.plant.selected_variation.

I grab selected.plant.selected_variation and search through the variations to retrieve the price. If no variation exists, then the plant price is given.

When the app loads, I can see that the plant_price is updated. However, it does NOT respond when I change selected.plant.selected_variation - its as if the computed property isn't listening to selected.plant.selected_variation

I must be doing something wrong?

Categories: Software

Passing avatar link into vue js component but failed

Vuejs - Thu, 2017-08-17 06:29

I am new in vue js. Currently i am trying to passing data into vue js components. So far if i passing user name or other information is working fine. But if i passing the avatar link it will showing error in npm run watch. Any solution for this?

This is my code

<li v-for="comment in comments"> <div class="avatar"><img src="{{ comment.user.avatar }}" alt="" /></div> <div class="comment-content"><div class="arrow-comment"></div> <div class="comment-by">{{ comment.user.name }}<span class="date">22 August 2017</span> <a href="#" class="reply"><i class="fa fa-reply"></i> Reply</a> </div> <p>{{ comment.content }}</p> </div> </li>

enter image description here

This is the object i get.

Categories: Software

vue.js not working, getting a cannot read property of undefined error

Vuejs - Thu, 2017-08-17 02:54

I'm trying to v-model to an array item's property. When I load the page I see "[Vue warn]: Error in render function: 'TypeError: Cannot read property 'viewFood' of undefined' in the console and a blank page.

this is with vue.js 2.x.

https://codepen.io/jzaun/pen/YxYyJN/

html

<div id="ai-config"> <div class="info"> <div class="row"> <h1>Resource Points</h1> </div> <div class="row"> <label>Total:</label> <div class="value"> {{maxResourcePoints}} </div> </div> <div class="row"> <label>Remaining:</label> <div class="value"> {{maxResourcePoints - usedResourcePoints}} </div> </div> </div> <div> <table> <tr> <td></td> <td v-for="(option, idx) in options"> {{option.title}} </td> </tr> <tr v-for="n in directions"> <td>Direction {{n}}</td> <td v-for="option in options"> <input type="checkbox", v-model="selected[n][option.key]" /> </td> </tr> </table> </div> </div>

javascript

new Vue ({ el: '#ai-config', data: { maxResourcePoints: 10, usedResourcePoints: 0, selected: [], directions: 8, options: [{ title: 'Food', key: 'viewFood', cost: 1 }, { title: 'Water', key: 'viewWater', cost: 1 }, { title: 'Own', key: 'viewOwn', cost: 1 }, { title: 'Other', key: 'viewOther', cost: 1 }] }, methods: { }, created: function () { this.selected = []; for(i=0; i< 8; i++) { this.selected.push({}); } } });
Categories: Software

Trigger multiple methods on event and pass event variable

Vuejs - Thu, 2017-08-17 01:28

Using vue, I am trying to trigger multiple events on a click and pass 'event' variable, so that I can use event.target.

I tried this:

<element @click="onSubmit(), onChange()"></element>

And in my methods, I tried

methods: { onSubmit(e) { console.log(e) }, onChange(e) { console.log(e) } }

Cannot read property 'target' of undefined

What is the proper way of achieving this?

Categories: Software

Vue component :key context

Vuejs - Wed, 2017-08-16 23:51

In order to work with custom vue components in a v-for binding, the frameworks asks you to specify a key for each component.

The first thing that comes to my mind is using the index as key, i.e.

<MyComponent v-for="(i, data) in list" :key="i"></MyComponent>

So far so good, but how will Vue handle something like

<MyComponent v-for="(i, data) in list" :key="i"></MyComponent> <MyComponent v-for="(i, data) in list" :key="i"></MyComponent>

Do I need to keep track of making keys unique globally for all my MyComponent components? I.e. :key="i + 'scope1'", :key="i + 'scope2'" etc.

TL;DR: Will Vue mix up two components with the same key? Is it enough to make the keys unique for each loop context?

Categories: Software

How to pass data from one view to another with the vue-router

Vuejs - Wed, 2017-08-16 21:51

When using the vue-router with .vue files, there is no documented way to pass data from one view/component to another.

Let's take the following setup...

main.js:

import Vue from 'vue'; import VueRouter from 'vue-router'; Vue.use(VueRouter); let routes = [ { path: '/page1', component: require('./views/Posts.vue') }, { path: '/page2', component: require('./views/EditPost.vue') } ]; let router = new VueRouter({ routes }); new Vue({ el: '#main', router });

Posts.vue:

<template> <div> Posts.vue passing the ID to EditPost.vue: {{ postId }} </div> </template> <script> export default { data() { return { allPostsHere: // Whatever... } } } </script>

EditPost.vue:

<template> <div> EditPost.vue received ID from Posts.vue: {{ receivedId }} </div> </template> <script> export default { data() { return { receivedId: // This is where I need the ID from Posts.vue } } } </script>

Please note: It is not possible to receive the ID directly from the EditPost.vue, because it has to be selected from Posts.vue.

Question: How can I pass the ID from one view/component to the other?

Categories: Software

How to add dynamiclly VueJS component to packery?

Vuejs - Wed, 2017-08-16 21:49

Hi I got a problem with packery.

Based on this solution https://codepen.io/Monocle/pen/ZbeBGL

I have every grid-item as a component and then in app.js (main file) im initializing packery based on example given.

var pckry = new Packery(container, { itemSelector: '.grid-item', columnWidth: '.grid-sizer', });

I want now to handle turn on/off components and then making them draggabilly and bind/unbind to packery. But the problem is I cant make packery as an attrbute of vue object and just make this.pckry.getShiftPositions() (based on example: https://codepen.io/desandro/pen/PZrXVv).

pckry.on( 'dragItemPositioned', function() { // save drag positions var positions = pckry.getShiftPositions( 'data-item-id' ); localStorage.setItem( 'dragPositions', JSON.stringify( positions ) ); });

The problem is with handling instance of packery object I guess. its just not working.

this.pckry.on( 'dragItemPositioned', function() { // save drag positions var positions = this.pckry.getShiftPositions( 'data-item-id' ); localStorage.setItem( 'dragPositions', JSON.stringify( positions ) ); });

Doesnt actually work. When im making it as

this.pckry = newPackery(...);

How can I actually handle that?

Categories: Software

Pages