Software

framework7 issue with a accordion

Vuejs - Wed, 2017-08-16 17:42

i am using framework7 last version , and my app hierarchy is like that :

vue router-view , vue children are loaded within router-view , one of those children is the root of framework7 app , when i navigate between "the root of framework7 which is a component" and any other component , the accordion animation start to stuck and act unexpectedly but it works good before navigation done .

i try to reset everything here with in the vue component which acts as root

export default { data() { return { appIsRdy: false } }, mounted() { this.$store.state.f7.f7Obj = new Framework7({ root: '.f7root' }); this.$store.state.f7.$$ = Dom7; this.$store.state.f7.mView = this.$store.state.f7.f7Obj.addView('.view-main', { domCache: true }); this.appIsRdy = true; }, components: { MainPage, RedditPage }, beforeDestroy() { this.$store.state.f7.f7Obj = null; this.$store.state.f7.$$ = null; this.$store.state.f7.mView = null; this.appIsRdy = false; } }
Categories: Software

How connect with server on client side with Vue.js, Socket.io, Arduino?

Vuejs - Wed, 2017-08-16 17:40

I have a problem with connection server by client application. I want to connect with my arduino board and control by client side wriiten in vue.js.

I have a server who run on node.js, and run good.

const http = require('http'); const socketIo = require('socket.io'); const port = process.env.PORT || 5000; const server = http.createServer().listen(port, () => { }); const five = require('johnny-five'); const board = new five.Board(); const pin = { 13: { led: { on: () => console.log('on'), off: () => console.log('off'), }, }, }; const io = socketIo(server); board.on('ready', () => { const led = new five.Led(13); led.off(); pin[13].led = led; }); io.sockets.on('connection', (socket) => { socket.on('message', (channel, message) => { if (channel === 'on') pin[message].led.on(); if (channel === 'off') pin[message].led.blink(500); }); });

but i have a problem with client-side. This is my code, and i don't know what can i do now.

<template> <router-view> </router-view> </template> <script> import Vue from 'vue'; import VueRouter from 'vue-router/dist/vue-router'; import LoginRoutes from 'features/login/login.routes'; import FoobarRoutes from 'features/foobar/foobar.routes'; import 'common/components'; import Jquery from 'jquery'; import BootstrapCSS from 'bootstrap/dist/css/bootstrap.css'; import Bootstrap from 'bootstrap'; Vue.use(VueRouter); io = require("socket.io/lib/socket"); var socket = io.connect("http://localhost:5000"); const routes = [ { path: '/', redirect() { return '/login'; }, }, ...LoginRoutes, ...FoobarRoutes, ]; const router = new VueRouter({ routes, }); export default { router, }; </script>

and this is my view :

<template> <div> <h1>TURN ON/OFF LED</h1> <button class="btn btn-danger" @click='on'>13: ON</button> <br><br> <button @click='off'>13: OFF</button> </div> </template> <script> export default { name: 'login-view', methods: { on: function() { socket.send('on', 13); // this.$socket.emit('on', 13); }, off: function() { socket.send('off', 13); }, }, }; </script> <style> </style>
Categories: Software

variable inside watch not reactive vuejs

Vuejs - Wed, 2017-08-16 16:27

I am watching an array and if some conditions met I want to disable / modify other elements but no luck so far, as the variable already_answered is not reactive.

<input :disabled="already_answered" type="text" /> data: function() { return { already_answered: false, somearr: [], }; }, watch: { somearr() { for (var i = 0; i < this.somearr.length; i++) { if (this.somearr[i]["id"] == 5) { this.already_answered = true break; } } }, },
Categories: Software

How insert one-to-many

Vuejs - Wed, 2017-08-16 16:22

There is a database with two tables (recipe, flavor). Between them one-to-many relationships one recipe is a lot of flavors. I add data through the put vue method

saverecipe: function(){ this.$http.put('/recipe/new', this.newrecipe).then(function (data) { console.log(this.newrecipe) }) }

Google Chrome data example with one flavor

handler

func PutRecipe(db *sql.DB) echo.HandlerFunc { return func(c echo.Context) error { var recipe models.Recipe c.Bind(&recipe) id, err := models.PutRecipe(db, recipe.RECIPENAME, recipe.BOTTLEID, recipe.BOTTLESIZE, recipe.PG, recipe.VG, recipe.NICOTINE, recipe.DATE, recipe.NOTE, recipe.FLAVORID, recipe.NAME, recipe.DROPS, recipe.RECIPEID) if err == nil { return c.JSON(http.StatusCreated, H{ "created": id, }) } else { log.Fatal(err) return err } } }

model

func PutRecipe(db *sql.DB, recipename string, bottleID int, bottlesize int, pg int, vg int, nicotine int, date string, note string, flavorid int, name string, drops int, recipeid int) (int64, error) { sql := `INSERT INTO recipe(recipename, bottleID, bottlesize, pg, vg, nicotine, date, note, flavorid) VALUES(?,?,?,?,?,?,?,?,?,?,?,?); INSERT INTO flavor(name, drops, recipeid) VALUES(?,?,?)` stmt, err := db.Prepare(sql) if err != nil { log.Fatal(err) } defer stmt.Close() result, err2 := stmt.Exec(recipename, bottleID, bottlesize, pg, vg, nicotine, date, note, flavorid, name, drops, recipeid) if err2 != nil { log.Fatal(err2) } return result.LastInsertId() }

Data must be written in two tables. One is a recipe. One - flavor. How can I do that? If you need I can lay out all the code on the github

Categories: Software

Lazy loading images in Vue/Laravel

Vuejs - Wed, 2017-08-16 16:18

I am trying to use jQuery Lazy Loading in my Laravel/Vue project but I am struggling to get an image to appear in my Vue component. I have the following img block which I thought would work:

<img v-if="vehicle.photo_path != null" :data-original="'/storage/vehicles/' + vehicle.photo_path" class="lazy" height="180" width="150"/>

I did find this other question on here - Static image src in Vue.js template - however when I try that method I get this: Interpolation inside attributes has been removed. Use v-bind or the colon shorthand instead.

So I switched back to the v-bind method but all I am getting is a white box with a grey border - no image. If I v-bind on the src attribute however I can see the image correctly.

I know I have implemented the Lazy Loading plugin correctly as I can successfully call it elsewhere on my site (such as on a blade view), but I'm not sure where I am going wrong. Thank you.

Categories: Software

Property or method "orgs" is not defined on the instance but referenced

Vuejs - Wed, 2017-08-16 16:06

I am using vue2 and I am trying to fetch an api and render the contents in my page, this is all done in my Orgs.vue file and here is the code:

<template lang="html"> <div class=""> {{ orgs | json }} </div> </template> <script> export default { data: { orgs: false }, created() { request = axios({ url: 'https://....', method: 'GET', }) .then(function(response) { this.orgs = response; }) .catch(function(error) { console.log('error getting orgs::', error); }); } }; </script> <style lang="css"> </style>

However everytime I run the page I get this error:

Property or method "orgs" is not defined on the instance but referenced during render. Make sure to declare reactive data properties in the data option. found in Orgs.vue

I tried to change

data: { orgs: false },

to

data() { return {orgs: false} },

but the error is still there

Categories: Software

Vue.js doen't render components

Vuejs - Wed, 2017-08-16 16:02

I am using Vue.js and i want to try to render components but it isn't working

main.js:

import Vue from 'vue'; import 'bulma'; import Navbar from './Navbar.vue'; Vue.component('navbar', Navbar); const MyC = Vue.component('myc', { template: '<h1>Are you working?</h1>', }); const root = new Vue({ el: '#app', components: { Navbar, MyC, }, });

index.html

<body> <div id="app"> <navbar></navbar> <myc></myc> </div> <script src="dist/build.js"></script> <!-- Webpack endpoint --> </body>

Navbar.vue

<template> <h1>HELLO FROM NAVBAR</h1> </template> <script> // Some logic here export default { name: 'navbar', }; </script>

I coded as written in guide but neither of the ways to render a component is working

I just have blank page

I am using webpack+vue-loader

Categories: Software

Vue in Laravel project doesn't appear

Vuejs - Wed, 2017-08-16 16:00

I'm starting to work with laravel and I try to use Vue. So on my resources/assets/js/app.js I have

Vue.component('example', require('./components/Example.vue')); const app = new Vue({ el: '#app' });

So my Example.vue is basicly what it's given with laravel. And in my welcome.blad I have

@extends('layouts.app') @section('content') <example> </example> @endsection <script src="{{ elixir('js/app.js') }}"></script>

in my package.json I have :

"devDependencies": { "vue": "^2.1.10", "vue-resource": "^1.0.3" }

But Nothing appear in my welcome page. I ran npm install npm run dev And change several things in my script, don't remember all but tried a lot of things and can't make it work

Categories: Software

deleting child component removes that component and all child components created after it

Vuejs - Wed, 2017-08-16 15:43

I've run into a problem when I delete a component any component created after it deleted and then recreated. Component in question gets deleted and child component created after it get deleted and then recreated.

Is there a reason why this is happening?

here is a video of it: maxniko.tinytake.com/sf/MTg3NTc2M182MDIyMzI5

Here is fiddle: jsfiddle.net/xk5yL3h8

fiddle code:

Vue.component('column-component', { props: ["columnData", "uniqueId"], mounted: function() { console.log('mounting column: ' + this.uniqueId) }, beforeDestroy: function() { console.log('removing: ' + this.uniqueId) }, template: ` <div style="float: left; padding: 10px; margin-right: 10px; border: 1px solid black;">aaa</div>` }) Vue.component('row-component', { props: ["rowData", "uniqueId"], data: function data() { return { columns: [], columnCount: 0 } }, mounted: function() { console.log('mounting row: ' + this.uniqueId) }, methods: { addColumn() { console.log var column = new Object() column.uniqueId = this.uniqueId +'.col.'+ this.columnCount this.columns.push(column) this.columnCount = this.columnCount + 1 } }, beforeDestroy: function() { console.log('removing: ' + this.uniqueId) }, template: ` <div> <div style="margin: 10px; padding: 20px; background: rgba(0,0,0, 0.5);"> row component: {{rowData.text}} <div class="column" v-for="(column, index) in columns"> <column-component column-data="abc" :uniqueId="column.uniqueId"></column-component> </div> <div style="clear: both;"></div> <div style="margin-top: 35px;"> <button @click="addColumn()">add column</button> </div> </div> </div>` }) new Vue({ el: '#app', template: ` <div> <div v-for="(row, index) in rows"> <row-component :uniqueId="row.uniqueId" :row-data="row" :key="row.uniqueId"></row-component> <button @click="deleteThisRow(index)">remove row</button> </div> <button @click="addRow()">add</button> </div> `, data: { rows: [], rowCount: 0 }, mounted: function() { this.addRow() this.addRow() this.addRow() }, methods: { addRow() { var row = new Object() row.uniqueId = 'row-' + this.rowCount row.text = 'row-'+(this.rows.length) this.rows.push(row) this.rowCount = this.rowCount + 1 }, deleteThisRow: function(index) { this.rows.splice(index, 1) console.log(this.rows) } } })
Categories: Software

Vue.js: Assigning computed result to data property at created or mounted?

Vuejs - Wed, 2017-08-16 15:27

Is it possible to do the following?

export default { props: ['parentArray'], data () { return { computedArray: null } }, computed: { computedResult: function () { var flags = [] var output = [] var l = this.parentArray.length var i for (i = 0; i < l; i++) { if (flags[this.parentArray[i].myitem]) continue flags[this.parentArray[i].myitem] = true var firstfilter = this.parentArray[i].myitem.replace('something', '') output.push(firstfilter) } return output } }, mounted () { this.computedArray = this.computedResult }

When I try, the structure of my array makes it to the data element, but none of the data (at least not in the vue dev-tools. The computed array properly shows up in computed)

Categories: Software

Perform edition with vuejs modal

Vuejs - Wed, 2017-08-16 15:08

The title is just a simple intro to what the real problem is, basicly i have a dashboard with a lot of elements (example: table, paragraph, heading) this elements are respective to a construction of a docx document.

Everytime i click one of these elements i open a new modal, where i can change some parameters in order to create the element, for example with paragraph i can change his alignment, color and text.

When i click to add this element it is added to a section in my page as a block and i should be able to change the properties of each block by clicking above the block.

I want to open a new modal(something like the modal when i open in the dashboard, with the difference instead of adding, to edit).

My problem is that i don't know what is the best way to do this without having messy spaghety code.

At the moment i am building it this way:

i have the dashboard component that is like this:

<template> <div class="navbar navbar-custom navbar-fixed-left navSize"> <form class="navbar-form margin-above" role="search"> <div class="input-group add-on"> <input class="form-control" placeholder="Search" name="srch-term" id="srch-term" type="text"> </div> </form> <h4 class="text-center">Doc Sections</h4> <div @click="changeView('appTable')" class="card card-color"> <div class="card-block"> <h4 class="card-title text-center">Table</h4> </div> </div> <div @click="changeView('appParagraph')" class="card card-color"> <div class="card-block"> <h4 class="card-title text-center">Paragraph</h4> </div> </div> <div @click="changeView('appImage')" class="card card-color"> <div class="card-block"> <h4 class="card-title text-center">Image</h4> </div> </div> <div @click="changeView('appBulletList')" class="card card-color"> <div class="card-block"> <h4 class="card-title text-center">Bullet List</h4> </div> </div> <div @click="changeView('appHeading')" class="card card-color"> <div class="card-block"> <h4 class="card-title text-center">Heading</h4> </div> </div> <div @click="changeView('appBreak')" class="card card-color"> <div class="card-block"> <h4 class="card-title text-center">Break</h4> </div> </div> </div> </template> <script> export default { data() { return { text: "", fontSize: 14, key: "Paragraph", paragraph: {}, } }, methods: { addParagraph() { this.$set(this.paragraph, 'key', this.key); this.$set(this.paragraph, 'text', this.text); this.$set(this.paragraph, 'fontSize', this.fontSize); this.$store.commit("appendToDocument", this.paragraph) }, changeView: function (view) { this.$store.commit("changeCurrentView", view); this.show(); }, show() { this.$modal.show('modalSection'); }, hide() { this.$modal.hide('modalSection'); }, hey() { console.log("HEY"); } }, } </script>

the change view sends to vuex the new component that should render the modal, i have this at vuex store:

currentView: 'appTable', changeCurrentView: (state, view) => { state.currentView = view; },

in my create file template is the place where i render the component that i click, like this:

<modal name="modalSection"> <component :is="getView"> </component> </modal> computed:{ getView(){ return this.$store.getters.getCurrentView; } },

again, i access vuex for the currentView clicked and change the component rendered. In this page i also load the components to be displayed but i think the important part about how it works is already showed, each component has its own properties inside, for example Table is 1 component with his properties inside it, like(number of rows, columns).

Do i need to pass all this properties from all my components to vuex? so i can edit them in other component. Or is there a better way?

Thank you guys

Categories: Software

Import javascript file after component is mounted

Vuejs - Wed, 2017-08-16 15:01

i am building spa using vuejs as the frontend and laravel as the backend, and i purcased some admin bootstrap template named limitless (very cool admin template by the way).

But there is the problem with this template that in the main javascript file (app.js in admin directory) there is this line

// Calculate min height function containerHeight() { var availableHeight = $(window).height() - $('.page-container').offset().top - $('.navbar-fixed-bottom').outerHeight(); $('.page-container').attr('style', 'min-height:' + availableHeight + 'px'); } // Initialize containerHeight();

and because i am using spa vuejs so i only include all js file in my admin.blade.php file like this

<!DOCTYPE Html> <Html lang="{{ config('app.locale') }}"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no' name='viewport'> <meta name="description" content=""> <meta name="author" content=""> <script> window.Laravel = <?php echo json_encode([ 'csrfToken' => csrf_token(), ]); ?> </script> <title>SIMO</title> <meta name="csrf-token" content="{{ csrf_token() }}" /> <!-- icon--> <link rel="icon" href="{{asset('images/logo.png')}}" sizes="16x16"> <link rel="icon" href="{{asset('images/logo.png')}}" sizes="32x32"> <link rel="apple-touch-icon" href="{{asset('images/logo.png')}}"/> <link rel="apple-touch-icon" href="{{asset('images/logo.png')}}" sizes="76x76" /> <link rel="apple-touch-icon" href="{{asset('images/logo.png')}}" sizes="120x120" /> <link rel="apple-touch-icon" href="{{asset('images/logo.png')}}" sizes="152x152" /> <link rel="apple-touch-icon" href="{{asset('images/logo.png')}}" sizes="180x180" /> <!-- Bootstrap Core CSS --> <link href="https://fonts.googleapis.com/css?family=Roboto:400,300,100,500,700,900" rel="stylesheet" type="text/css"> <link rel="stylesheet" type="text/css" href="{{asset('css/admin/icons/icomoon/styles.css')}}" > {{-- <link rel="stylesheet" type="text/css" href="{{asset('css/admin/icons/fontawesome/styles.min.css')}}" > --}} <link rel="stylesheet" type="text/css" href="{{asset('css/admin/bootstrap.css')}}" > <link rel="stylesheet" type="text/css" href="{{asset('css/admin/core.css')}}" > <link rel="stylesheet" type="text/css" href="{{asset('css/admin/components.css')}}" > <link rel="stylesheet" type="text/css" href="{{asset('css/admin/colors.css')}}" > @yield('css') <!-- Html5 Shim and Respond.js IE8 support of Html5 elements and media queries --> <!-- WARNING: Respond.js doesn't work if you view the page via file:// --> <!--[if lt IE 9]> <script src="https://oss.maxcdn.com/libs/Html5shiv/3.7.0/Html5shiv.js"></script> <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script> <![endif]--> </head> <body> <div id="app"></div> <script type="text/javascript" src="{{ URL::asset('js/app.js') }}"></script> <script type="text/javascript" src="{{ URL::asset('js/admin/plugins/loaders/pace.min.js') }}"></script> <script type="text/javascript" src="{{ URL::asset('js/admin/libraries/jquery.min.js') }}"></script> <script type="text/javascript" src="{{ URL::asset('js/admin/libraries/bootstrap.min.js') }}"></script> <script type="text/javascript" src="{{ URL::asset('js/admin/plugins/loaders/blockui.min.js') }}"></script> <script type="text/javascript" src="{{ URL::asset('js/admin/plugins/ui/nicescroll.min.js') }}"></script> <script type="text/javascript" src="{{ URL::asset('js/admin/plugins/ui/drilldown.js') }}"></script> <script type="text/javascript" src="{{ URL::asset('js/admin/plugins/buttons/hover_dropdown.min.js') }}"></script> <script type="text/javascript" src="{{ URL::asset('js/admin/plugins/forms/selects/bootstrap_select.min.js') }}"></script> <script type="text/javascript" src="{{ URL::asset('js/admin/plugins/ui/ripple.min.js') }}"></script> <script type="text/javascript" src="{{ URL::asset('js/admin/app.js') }}"></script> </body> </Html>

and after inspecting the code i found out that it need div with class page-container and this div is located after header part so in my index.vue page i put it like this

<template> <div> <div class="page-header"> //here is header </div> <div class="page-container"> //content </div> </div> </template>

so it will throw

Uncaught TypeError: Cannot read property 'top' of undefined

because when the page loaded it don't find any div with page-container class, since it not there yet.

And from what i read in vuejs documentation about lifecycle, this entire admin/app.js code should be run in mounted() or created() vuejs function. But from the example in documentation and around the internet it just used for run some javascript function but not include entire javascript file so it will be executed in there....

so my question is how to solve this? or for more simple way, how to add external css file and javascript file in component(this index.vue is called component right?) some people tell me to make it module and import it but i have no idea how to do that....

from what i know is i can download javascript plugin like moment from npm and it magically can be called within vue with import moment from moment but how about the local javascript files?

Categories: Software

zoom issue in dagre-d3 when use with vuejs2 with watch mode

Vuejs - Wed, 2017-08-16 14:37

I am using d3-dagre to render the data. Initially i can render the data without any problem. When i try to update the same view in watch mode, it is updating the data but still some error is thrown in the console for "g" attribute transformation. Whenever i try to rewrite the SVG elements i am removing the "g" element inside the "svg" tag. I am trying this in vuejs2 ui library.

watch: { workflowDetails: function (changes) { console.log('Update component ==> ' + changes) this.workflowName = changes.label this.workflowDetails = changes this.metricGraph = false this.drawDAGView() } }, mounted () { this.drawDAGView() }, methods: { getJobid: function (nodeId) { console.log('Function to get graph api' + nodeId) this.metricGraph = true }, drawDAGView: function (isUpdate) { /* eslint-disable */ d3.selectAll('svg > g').remove() // Create a new directed graph var g = new dagreD3.graphlib.Graph().setGraph({}) var DagNodes = this.workflowDetails.nodes var fillColor // Add states to the graph, set labels, and style Object.keys(DagNodes).forEach(function(key) { console.log("Nodes - "+ DagNodes[key].name) var value = DagNodes[key] value.label = DagNodes[key].name + " (" + DagNodes[key].exec_time + ")" value.rx = value.ry = 5 g.setNode(DagNodes[key].name, value) }) var DagEdges = this.workflowDetails.edges; // Add states to the graph, set labels, and style Object.keys(DagEdges).forEach(function(key) { g.setEdge(DagEdges[key].startEdge, DagEdges[key].endEdge, { label: ""} ) }) // Create the renderer var render = new dagreD3.render() // Set up an SVG group so that we can translate the final graph. var svg = d3.select("svg"), inner = svg.append("g") // Set up zoom support var zoom = d3.behavior.zoom().on("zoom", function() { inner.attr("transform", "translate(" + d3.event.translate + ")" + "scale(" + d3.event.scale + ")") }) svg.call(zoom) // Simple function to style the tooltip for the given node. var styleTooltip = function(name, description) { return "<p class='name'>" + name + "</p><p class='description'>" + description + "</p>" } // Run the renderer. This is what draws the final graph. render(inner, g) inner.selectAll("g.node") .attr("title", function(v) { return styleTooltip(v, "Execution Time: "+g.node(v).label + " <br /> Description: "+g.node(v).label) }) //.each(function(v) { $(this).tipsy({ gravity: "w", opacity: 1, html: true }) }) var self = this inner.selectAll("g.node") .on("click", function(v) { console.log("Nodes --> "+ v + " -- "+ g.node(v).node_id) // whatever //window.location = "../dag/"+g.node(v).job_id self.nodeId = g.node(v).node_id console.log("Node id -- "+ self.nodeId) self.getJobid(self.nodeId) }) // Center the graph var initialScale = 1.2 zoom .translate([(svg.attr("width") - g.graph().width * initialScale) / 50, 20]) .scale(initialScale) .event(svg) svg.attr('height', g.graph().height * initialScale + 40) svg.attr('width', "100%") }

Error - Due to this below error newly loaded data not able to zoom

Error: <g> attribute transform: Expected number, "translate(NaN,20)
Categories: Software

Include bootstrap features into a custom vuejs component

Vuejs - Wed, 2017-08-16 14:35

I'm asked to add a new html page to a project. This page is already fully developed and is based on and some features.

I've created a new component.

newPage.vue

<template> <div id="my-new-page"> ... </div> </template> <style src="path/to/_bootstrap.scss" lang="scss" scoped></style> <style src="path/to/font-awesome.scss" lang="scss" scoped></style> <style src="path/to/animate.css" scoped></style> <style src="path/to/custom/css.css" scoped></style> <script src="path/to/custom/js.js"></script>

js.js

import jQuery from 'jquery'; // Same error even with window.$ = window.jQuery = jQuery; import collapse from 'path/to/bootstrap/feature/collapse.js"; export default { created() { runjQuery(jQuery); }, }; function runjQuery($) { // here is how I thought integrate the jquery script of the new html page $(function () { .... $('#navbar').collapse('hide'); }); }

But this obviously does not work because collapse.js cannot access jQuery and I get this error

Uncaught ReferenceError: jQuery is not defined

How do I fix this problem?

Given that I don't want (if possible) to add bootstrap and jquery globally to my project because this will surely breaks here and there in my other components?

Categories: Software

Update array element in Vuejs

Vuejs - Wed, 2017-08-16 14:33

I'm having a data set which is by default have following:

summaries: [{client:'', type: '', mention: '', action: '', comment: '', button: true}],

I've a button which adds the same data set into summaries data:

addSummary() { this.summaryHeaders = true; this.summaries.push({ client: '', type: '', mention: '', action: '', comment:'', button: true }) },

Now I'm having other button, while being clicked I want to update button attribute as false of that particular data set. How can I achieve this?

Categories: Software

How to populate store in vuex before component renders

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

I am using vuex to save a tree structure in the state property.

The data is fetched with an ajax call.

The problem is that the page manages to render before the variable I have in the state property manages to populate.

i.e

// sth.ts file state: { map: {} }, ... actions: { axios.get(...).then(... populate map ...).catch(...) } // sthelse.vue file <template> <div> <h1>Tree structure</h1> <ul > <item v-for="child in map[root]" :key="child.id" :name="child.name" :children="child.Children"> </item> </ul> </div> </template>

I have googled but I haven't found something that works. Has anybody dealt with a similar problem?

Is there a way it can be done?

Categories: Software

deleting component from array, vuejs removes wrong component

Vuejs - Wed, 2017-08-16 12:15

I need to be able to delete specific component from the array. I do this with splice and although that component definition is removed from array, vuejs removes wrong component. It allways removes the last added component.

Here is a fiddle that provides demonstration of that:

https://jsfiddle.net/wjjonm8n/

and here is video to show what is happening:

https://maxniko.tinytake.com/sf/MTg3NTI5NF82MDIxNDAx

here is some code:

Vue.component('row-component', { props: ["rowData", "uniqueId"], mounted: function() { console.log('mounting: ' + this.uniqueId) }, beforeDestroy: function() { console.log('removing: ' + this.uniqueId) }, template: ` <div> row component: {{rowData}} <button @click="$emit('delete-row')">Delete</button> </div>` }) new Vue({ el: '#app', template: ` <div> <row-component v-for="(row, index) in rows" :row-data="row" :uniqueId="index" v-on:delete-row="deleteThisRow(index)"></row-component> <button @click="add()">add</button> </div> `, data: { rows: ["line1", "line2", "line3", "line4", "line5"], }, methods: { add() { this.rows.push('line'+(this.rows.length+1)) }, deleteThisRow: function(index) { this.rows.splice(index, 1) console.log(this.rows) } } })

this function tells me what vuejs really removes:

beforeDestroy: function() { console.log('removing: ' + this.uniqueId) }

it removes last added component if you look at what that console.log function prints. This is problem because on mount of each component I create listener for just that component:

this.$bus.$on('column-'+this.uniqueId+'-add-block', this.handlerMethod)

when vue removes last component, this event listener no longer works.

How can I solve this?

In my own application this is how I create child component:

let column = new Object() column.uniqueId = this._uid+'-column-' + this.addedColumnCount column.text = '1/2' this.columnList.push(column) this.addedColumnCount = this.addedColumnCount + 1

notice how I create uniqueId for component when I add it:

column.uniqueId = this._uid+'-column-' + this.addedColumnCount

when I try to delete a component it allways reports to me that the component with last added uniqueId is being removed.

beforeDestroy: function() { this.$bus.$off('column-'+this.uniqueId+'-add-block', this.handlerMethod) console.log('removing: ' + this.uniqueId) },
Categories: Software

How to use variables of data function on VueJS?

Vuejs - Wed, 2017-08-16 11:54

I have a stupid problem with VueJS. I'm new with VueJS. I want to access and change variables of data function. However I couldn't do it.

Here is my code:

data: function(){ return { item: 69, file: 0 }; }, methods: { toggle: (elementId = 0, type = 'item') => { console.log('element ID: ' + elementId); console.log('type: ' + type); console.log('item: ' + this.item); switch (type) { case 'item': break; case 'file': break; } } }
Categories: Software

For loop and strange Vue behaviour

Vuejs - Wed, 2017-08-16 11:33

I'm working on a project where I want to add some more input fields when clicking on a button. So I tried jQuery.append but then there was a problem with v-model not being detected. So I tried to achieve the same thing using Vue if-statement and I figured out it could be done much simpler by just adding objects to the variable deciding how many input fields listed in the first place.

But then I noticed something strange and I would like to know if this is by accident or if it's meant to work this way.

So first of all - this is the html:

<div id="app-edit" class="form-group"> <template v-if="plate.props.products !== undefined"> <div class="form-group form-row" v-for="(extra, index) in plate.props.products"> <div class="col"> <label for="productExtrasNobb0" v-if="index == 0">NOBB number</label> <input type="text" class="form-control" v-bind:id="'productExtrasNobb' + index" v-model="plate.props.products[index].nobb"> </div> <div class="col"> <label for="productExtrasAmount0" v-if="index == 0">Amount</label> <input type="text" class="form-control" v-bind:id="'productExtrasNumber' + index" v-model="plate.props.products[index].number"> </div> <div class="col-auto d-flex align-items-end"> <button type="button" class="btn btn-danger"><i class="fa fa-minus"></i></button> </div> </div> <template v-if="extraAddons > 0"></template> <button type="button" class="btn btn-info" @click="addExtra(plate.props.products.length)"><i class="fa fa-plus mr-2"></i>Add</button> </template> <template v-else> <button type="button" class="btn btn-info" @click="addExtra(plate.props.products.length)"><i class="fa fa-plus mr-2"></i>Add</button> </template> </div>

And this is the relevant Vue JS:

var app = new Vue({ el: '#app-edit', data: { extraAddons: 0, plate: { props: { products: [], } } }, methods: { addExtra: function(number) { vm = this; vm.plate.props.products[number] = {nobb:'',number:''}; vm.extraAddons++; } } });

The thing is this is working fine. When I press the button to add an extra block it is inserted. But if I remove

<template v-if="extraAddons > 0"></template>

it's not working. Why is that relevant at all? It doesn't matter what tag I use - it could be p instead of template and still the same result but it seems like the v-if statement is triggering some sort of rendering?

Could anyone please explain so I can understand better why this is happening?

Categories: Software

Vue Autocomplete component with slot instead of input

Vuejs - Wed, 2017-08-16 11:32

I have created custom autocomplete component which works as material input, but on focus or input debounces an ajax request and the reponse is a list of something which i can click and set as value of the input. The component uses labled-input component which is similar to Vuetify text input.

How ever, I would like to change to code to somehow using slots but its a problem since I have to listen for emits ( focus, blur ) from that slot.

So instead of my-labeled-input wanna change it to <slot></slot> and pass component from parent. The idea is to use the same code for selects too. Any suggestions?

<template> <div class="my-autocomplete"> <my-labeled-input :value="value" :title="title" @input="lInput" @focus="onFocus" @blur="onBlur"></my-labeled-input> <div class="list-container" v-if="focused"> <ul class="menu" v-if="list.length > 0"> <li v-for="item in list" @mousedown="itemClick(item.toponymName)">{{ item.toponymName }}</li> </ul> <template v-else> <p v-if="waiting"> Loading ...</p> <p v-else>No Data</p> </template> </div> </div> </template> <script> import debounce from 'lodash.debounce'; import myLabeledInput from '../../components/my-labeled-input/index.vue'; export default { name: 'my-autocomplete', components: { myLabeledInput, }, props: { value: { type: String, default: null, }, title: { type: String, default: null, }, apiUrl: { type: String, default: null, }, query: { type: Object, default: () => {}, }, debounceInterval: { type: Number, default: 1000, }, }, data() { return { list: [], focused: false, waiting: false, }; }, methods: { lInput(value) { this.$emit('input', value); this.waiting = true; this.getList(value); }, onFocus() { this.focused = true; this.waiting = true; this.getList(this.value); }, onBlur() { console.log('blur'); this.focused = false; }, getList: debounce(function (value) { // eslint-disable-line this.$http({ url: this.apiUrl, method: 'GET', params: { ...this.query, name_startsWith: value, }, }).then((response) => { console.log(response); this.list = response.data.geonames; this.waiting = false; }).catch(() => { this.list = []; this.waiting = false; }); }, 2000), itemClick(value) { this.$emit('input', value); }, }, }; </script>
Categories: Software

Pages