Software
How do I hide results on an empty query in Laravel + Vue?
Running Laravel Scout + Algolia with Vue. Got it all working and the searching is nice and fast. However I want to hide the results on an empty query instead of displaying the whole index.
Algolia provides this solution:
var search = instantsearch({ [...], searchFunction: function(helper) { var searchResults = $('.search-results'); if (helper.state.query === '') { searchResults.hide(); return; } helper.search(); searchResults.show(); } }Here is my search:
//search.blade.php <ais-index app-id="{{ config('scout.algolia.id') }}" api-key="{{ env('ALGOLIA_SEARCH') }}" index-name="dev_users"> <ais-search-box placeholder="Zoek een gebruiker" :autofocus="true"></ais-search-box> <ais-results></ais-results> <script> new Vue({ el: "#search", }) </script>And here is my app.js
import InstantSearch from 'vue-instantsearch'; Vue.use(InstantSearch);I can't figure out how to implement the code from the Algolia manual. Can you guys point me in the right direction?
Thanks in advance.
Vue.js 2 + Firebase getting data to item inner view
I'm trying to build a little simple content management system.
I'm using Vue.js V2 + Google Firebase + Vue Fire + Vue Router.
What I'm failing to understand how should I pass params to the inner view from home view. I want to click on one of the items on homepage, then open inner view for it. What I tried so far is passing the ['.key'] param through vue-router, then reading it in views/inner.vue like this :
let textRef = database.ref('apps/'+ this.$route.params.appid +'/text') firebase: { paragraphs: textRef } <tbody> <tr v-for="paragraph in paragraphs"> <td>{{paragraph.content}}</td> <td>{{paragraph.time}}</td> <td><span class="glyphicon glyphicon-trash iconClick" aria-hidden="true" v-on:click="removeText(paragraph)"></span></td> </tr> </tbody>but then it creates undefined new item in the Home view.
What am I doing wrong? I'm fairly new to vue.js/firebase.
Here's my code below.
main.js
import Vue from 'vue' import VueFire from 'vuefire' import router from './router' import App from './App' Vue.config.productionTip = false Vue.use(VueFire) /* eslint-disable no-new */ new Vue({ el: '#app', router, template: '<App/>', components: { App } })App.vue
<template> <div id="app"> <div class="container"> <h1>{{titleMain}}</h1> <router-view></router-view> </div> </div> </template> <script> export default { name: 'app', data () { return { titleMain: 'LiveText v1.0 for lrytas.lt' } } } </script> <style> #app { font-family: 'Avenir', Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; color: #2c3e50; margin-top: 60px; } h1 { margin-bottom: 60px; } .iconClick, .appsList { cursor: pointer; } </style>views/inner.vue
<template> <div> <h2>{{msg}}</h2> <h3>{{$route.params.app['.key']}}</h3> <h5>{{$route.params.app.created}}</h5> <div class="panel panel-default"> <div class="panel-heading"> <h3 class="panel-title">{{$route.params.app.name}}</h3> </div> <div class="panel-body"> <table class="table table-hover"> <thead> <tr> <th>Paragrafas</th> <th>Laikas</th> <th></th> </tr> </thead> <tbody> <tr v-for="paragraph in paragraphs"> <td>{{paragraph.content}}</td> <td>{{paragraph.time}}</td> <td><span class="glyphicon glyphicon-trash iconClick" aria-hidden="true" v-on:click="removeText(paragraph)"></span></td> </tr> </tbody> </table> </div> </div> <div class="panel panel-default"> <div class="panel-heading"> <h3 class="panel-title">Pridėti paragrafą</h3> </div> <div class="panel-body"> <form id="form" class="form-inline" v-on:submit.prevent="addText"> <div class="form-group"> <label for="appTitle">Pavadinimas:</label> <textarea type="text" id="appTitle" class="form-control" v-model="newParagraph.content"></textarea> <input type="submit" class="btn btn-primary" value="Kurti"> </div> </form> </div> </div> </div> </template> <script> import Firebase from 'firebase' import toastr from 'toastr' let database = Firebase.database() let textRef = database.ref('apps/-KsEMtgKSeVtA9_rSgWD/text') export default { name: 'hello', data () { return { msg: 'Inner page!', newParagraph: { content: '', time: this.getTime() } } }, methods: { addText: function () { textRef.push(this.newParagraph) this.newParagraph.content = '' toastr.success('Paragrafas sėkmingai pridėtas!') }, removeText: function (paragraph) { console.log(paragraph) textRef.child(paragraph['.key']).remove() toastr.success('Paragrafas sėkmingai pašalintas!') }, getTime: function () { var date = new Date() var dateFormated = date.toLocaleDateString('lt') var timeFormated = date.toLocaleTimeString('lt', {hour12: false, hour: '2-digit', minute: '2-digit'}) var current = dateFormated + ' ' + timeFormated return current } }, firebase: { paragraphs: textRef } } </script> <!-- Add "scoped" attribute to limit CSS to this component only --> <style scoped> h1, h2 { font-weight: normal; } ul { list-style-type: none; padding: 0; } li { display: inline-block; margin: 0 10px; } a { color: #42b983; } label { display: block; } textarea { display: block; } .btn { display: block; margin-top: 15px; } </style>views/home.vue
<template> <div> <div class="panel panel-default"> <div class="panel-heading"> <h3 class="panel-title">{{titleList}}</h3> </div> <div class="panel-body"> <table class="table table-hover"> <thead> <tr> <th>Pavadinimas</th> <th>ID</th> <th>Sukūrta</th> <th></th> </tr> </thead> <tbody> <tr class="appsList" v-for="app in apps" v-on:click="goInner(app)"> <td>{{app.name}}</td> <td>{{app['.key']}}</td> <td>{{app.created}}</td> <td><span class="glyphicon glyphicon-trash iconClick" aria-hidden="true" v-on:click="removeApp(app)"></span></td> </tr> </tbody> </table> </div> </div> <div class="panel panel-default"> <div class="panel-heading"> <h3 class="panel-title">{{titleAdd}}</h3> </div> <div class="panel-body"> <form id="form" class="form-inline" v-on:submit.prevent="addApp"> <div class="form-group"> <label for="appTitle">Pavadinimas:</label> <input type="text" id="appTitle" class="form-control" v-model="newApp.name"> <input type="submit" class="btn btn-primary" value="Kurti"> </div> </form> </div> </div> </div> </template> <script> import Firebase from 'firebase' import firebaseconfig from '../firebase/config' import toastr from 'toastr' // Firebase Stuff let firebase = Firebase.initializeApp(firebaseconfig) let database = firebase.database() let appRef = database.ref('apps') export default { name: 'home', data () { return { titleMain: 'LiveText v1.0 for lrytas.lt', titleList: 'Aplikacijos', titleAdd: 'Sukurti naują aplikaciją', newApp: { name: '', created: this.getTime() } } }, methods: { getTime: function () { var date = new Date() var dateFormated = date.toLocaleDateString('lt') var timeFormated = date.toLocaleTimeString('lt', {hour12: false, hour: '2-digit', minute: '2-digit'}) var current = dateFormated + ' ' + timeFormated return current }, addApp: function () { appRef.push(this.newApp) this.newApp.name = '' toastr.success('Aplikacija sėkmingai sukurta!') }, removeApp: function (app) { appRef.child(app['.key']).remove() toastr.success('Aplikacija sėkmingai pašalinta!') }, say: function (id) { alert('Your app id is' + id) }, goInner: function (app) { this.$router.push({ name: 'inner', params: { appid: app['.key'], app: app } }) } }, firebase: { apps: appRef } } </script> <!-- Add "scoped" attribute to limit CSS to this component only --> <style scoped> label { display: block; } .btn { display: block; margin-top: 15px; width: 100%; } </style>router/index.js
import Vue from 'vue' import Router from 'vue-router' import Home from '../views/Home' import Inner from '../views/Inner' Vue.use(Router) export default new Router({ routes: [ { path: '/', name: 'home', component: Home }, { path: '/app/:appid', name: 'inner', component: Inner } ] })Vue js not updating view with files data but able to console log
I am working on an image upload using vue.js but can't figure out this odd issue.
In my view:
{{ form.image }}My data in the vue file:
data: function() { return { form: new SparkForm({ id: null, name: null, image: null }), imagePreview: null } },And the method called when the file input is changed:
imageChanged: function(e) { var $this = this; let files = e.target.files || e.dataTransfer.file; if (!files.length) { return; } else { $this.form.image = files[0]; console.log($this.form.image); } },This will console log the files information correctly, but in the view I just get an empty object.
Can't see anything obvious...
NUXT build does not build
It seems that nuxt build does not build at all.
My package.json:
{ "name": "my-app", "description": "nuxt + express", "repository": "https://github.com/xxx.git", "scripts": { "dev": "node server.js", "build": "nuxt build", "start": "cross-env NODE_ENV=production node build/main.js" }, "dependencies": { "axios": "^0.16.2", "cross-env": "^5.0.5", "express": "^4.15.4", "nuxt": "^1.0.0-rc5" }, "license": "MIT" }I run:
npm run buildI get:
> my-app@ build /var/www/html/nuxt-express-basic > nuxt build nuxt:build Building... +0ms nuxt:build App root: /var/www/html/nuxt-express-basic +0ms nuxt:build Generating /var/www/html/nuxt-express-basic/.nuxt files... +1ms nuxt:build Generating files... +6ms nuxt:build Generating routes... +1ms nuxt:build Building files... +20ms build [====== ] 30%Hash: 5efd1cf979d356684e6b Version: webpack 3.5.5 Time: 2993ms Asset Size Chunks Chunk Names server-bundle.json 265 kB [emitted] Build completed in 14.796s Hash: 26afaacb93db8fb758f5 Version: webpack 3.5.5 Time: 14801ms Asset Size Chunks Chunk Names pages/index.ff1f52e2a9108fcd63b0.js 14.7 kB 0 [emitted] pages/index layouts/default.9c90bfab32add26a98a2.js 322 bytes 1 [emitted] layouts/default common.db2b22db39e453c5d232.js 134 kB 2 [emitted] common app.8d0391f3c1da4ba9a797.js 20.4 kB 3 [emitted] app manifest.26afaacb93db8fb758f5.js 1.59 kB 4 [emitted] manifest LICENSES 138 bytes [emitted] + 8 hidden assets nuxt:build Building done +15sBut I don't see any build dir in my root dir.
Any ideas?
Active a item inside a v-for loop when clicked
I am a bit stuck at the moment trying to figure out how to active the current clicked element inside a loop. Basically I just want to change some CSS to that item, for example opacity, and know where I actually clicking inside the loop (this one I can handle with onclick I think).
So basically I tried this:
<div class="panel panel-default"> <ul class="list-group"> <li :style="panel.color" v-for="(panel,key,index)in getPanels" :class="{active: panel === activeItem}" class="list-group-item" > A section {{panel.section}} was {{panel.action}} </li> </ul> </div> data() { return { activeItem: null } }, .active { opacity: 0.7; }The active class is not getting applied to the specific clicked item. What is wrong – can anyone help?
How to filter a list in VueJS with multiple watchers
This is my first time using VueJS. I am trying to build a page which displays data on the right and has several controls (checkboxes, drop downs, input text) on the left. The data on the right will be filtered when the controls on the left are selected/entered.
I'm trying to prepare a small demo for this on JSBin with dummy data: http://jsbin.com/qujaraf/edit?html,js,console,output
I have some data and I have two watchers codesearch and typesearch.
Questions
- I would like the list to be filtered when I type stuff in them.
- How can I make it so that when data is entered in both watchers then the filter takes both inputs in account. For example, in this demo, if user enters actor in type and three in code then only one list item should show.
How to bind radio buttons to a vuex store?
I want to one-way bind the value of a set of radio buttons to my model and update the vuex store on change. Unfortunately this does not seem to be documented anywhere. Any help will be appreciated.
Two-way binding works as documented:
<input type="radio" name="info-source" value="1" id="info-source-1" v-model="infoSource"> <label for="info-source-1">TV</label> <input type="radio" name="info-source" value="2" id="info-source-2" v-model="infoSource"> <label for="info-source-2">Social media</label>However vuex starts complaining in this case Do not mutate vuex store state outside mutation handlers
vue jQuery - passing data from input to vue's function
Hello I want to pass data from input (I added only necessary code) :
<input id="txtName" v-on:keyup.enter="addMessage(/* THIS FIELD VALUE */)" type="text">
to method:
` ...
methods: {
addMessage(name){ //stuff },...
`
I tryed to use as parameter this or this.value but it is no reacting.
I guess its very easy,but unfortunately I get stuck with this..
How should I solve this?
Why is that poor practice to use Axios in components?
In this article, it is said:
While it’s generally poor practice, you can use Axios directly in your components to fetch data from a method, lifecycle hook, or whenever.
I am wondering why? I usually use lifecycle hooks a lot to fetch data (especially from created()). Where should we write the request calls?
Inject or Initialize Vue components in generated HTML
I use a an WYSIWYG article editor that generates some HTML for articles that I save in the database and later show to the user.
The problem is I need to insert Vue components into this auto generated HTML for showing dynamic products. I can make a custom block in the editor that adds in HTML but I want it to work as a Vue component that updates the product description directly from the database.
What Im thinking now is to add a button that adds a div with a data property of the products ID. I can then replace that div in the code with a Vue component with the same ID by injecting a component.
Another idea I had was to simply add in components like <product id="1031"/> as plain html and then try to compile the whole article HTML with Vue but I read that the v-html directive only compile code as plain HTML.
Is this possible? Or is there any better ideas?
How to integrate custom meta tags with Rails 5 + webpacker + Vue.js
Just like in title: What is the proper way to integrate SEO stuff like Facebook OpenGraph tags in apps that use rails backend API (installed with webpacker) with a framework like Vue?
This is how part of my config/routes.rb looks like:
namespace :api, defaults: { format: :json } do namespace :v1 do resources :posts, only: [:index, :show] end end get '/', to: 'front#index', format: false get '/*path', to: 'front#index', format: falseFor now app is designed in the way, where all requests on front-end part are handled by vue-router.
My layouts/application.html looks almost, like on the attached snippet:
<html> <head> <%= javascript_pack_tag 'front' %> <%= stylesheet_pack_tag 'front' %> </head> <body> <div id="app"> <%= yield %> </div> </body> </html>My question is, what is the proper way to manage stuff like Facebook Open Graph when there is no straight forward access to <head> section?
I can't use fairly default rails stuff like content_for because everything happens inside script.
Or maybe am I wrong? Missing something fancy, important here?
It would be grateful to get any advice, thanks.
Trying to use v-on:blur for making disappear a context menu...but it doesn't work
I am coding a simple context menu in vue.js. When I do a right click on a peculiar element, it opens the menu (using @contextmenu.prevent).This works.
But when I click outside of the menu I want it to disappear. This doesn't work... I am using v-on:blur for this, also tried @blur . None of them doesn't work. Here is my html :
<!-- my context menu --> <ul class="context-menu" ref="contextMenuTrack" v-if="openedMenu === 'contextMenuTrack'" v-bind:style="{top: top, left: left}" v-on:blur="closeMenu()"> <li v-on:click="removeTrack(project.structure.tracks.indexOf(targetOfMenu));closeMenu()">delete track</li> </ul> <div> [ ...... stuff here ......] <!-- Where the menu is called--> <li class="track" v-for="track in project.structure.tracks"> <div class="track-name-row"> <li @contextmenu.prevent="openContextMenuTrack(track,$event)" v-on:click="expandTrack(project.structure.tracks.indexOf(track))" class="track-color-viewer"></li> [ .... other li tags .....] </div> </li> [ ...... stuff here ......] </div>Here is the datas used for the menu of my Vue component:
data() { return { //the kind of menu which is opened openedMenu: undefined, //the coordinate of the menu top: "0px", left: "0px", //the element which is targeted by the menu targetOfMenu: undefined }; },And here are the methods used for the menu in my Vue.js component :
methods: { setMenu(top, left) { this.top = top - 170 + "px"; this.left = left + "px"; }, // opening menu : calling set menu whith x and y openContextMenuTrack(track, event) { this.openedMenu = "contextMenuTrack"; this.targetOfMenu = track; this.$nextTick((() => { this.$refs.contextMenuTrack.focus(); this.setMenu(event.y, event.x); }).bind(this)); }, closeMenu() { this.openedMenu = undefined; this.targetOfMenu = undefined; } }Charts.js with vue not drawing charts after fetching data
This is how json response looks like [[61,57,34],[1,1,3]] I want to use the first array for labels and the second for data.
If I set labels and data inside app manually it works though.
eg labels: ["q", "w", "e"] data: [1, 5, 10]
Vue.component('chart', { props: ['labels', 'data', 'type'], template: ` <canvas style="width: 512px; height: 256px"></canvas> `, mounted: function () { new Chart(this.$el, { type: this.type, data: { labels: this.labels, datasets: [{ label: '# of Votes', data: this.data, borderWidth: 1 }] }, options: { scales: { yAxes: [{ ticks: { beginAtZero:true } }] } } }) } }); new Vue({ el: '#app', data: { message: "test", labels: [], data: [] }, methods: { fetchData: function() { this.$http.get('/admin/fetch_data').then(res => { this.labels = res.body[0]; this.data = res.body[1]; }) } }, beforeMount() { this.fetchData() } });component on page
<div id="app"> {{message}} <chart :labels="labels" :data="data" type="bar"></chart> </div>The data seems to be loaded but there're no chart bars on page.
`npm --version` takes a long time when called within nodejs program
Within vue.js empty project created with vue CLI I have a script build/dev-server.js that starts the app.
Its first line is require('./check-versions')() which blocks my system for couple of minutes. I identified that this part blocks it:
function exec (cmd) { return require('child_process').execSync(cmd).toString().trim() }and in this case cmd argument is npm --version. execSync seems to be a problem here which invokes var result = spawn_sync.spawn(options); from child_process.js with the following options:
length:5 __proto__:Array(0) [, …] 0:"C:\Windows\system32\cmd.exe" 1:"/d" 2:"/s" 3:"/c" 4:""npm --version"" envPairs:Array(63) ["ALLUSERSPROFILE=C:\ProgramData", "APPDATA=C:\Users\mmilic\AppData\Roaming", "ChocolateyInstall=C:\ProgramData\chocolatey", …] file:"C:\Windows\system32\cmd.exe" killSignal:undefined shell:true stdio:Array(3) [Object, Object, Object] windowsVerbatimArguments:trueInvoking npm --version on command line returns ASAP. Also, on one computer switching from corporate to wireless network connection resolves the problem.
Any ideas ?
vue.js jquery - access to global function from jQuery method
I am making a simple SPA application in vue.js and I use some jQuery methods. Problem is, I can't use vue's methods inside of jQuery statement. For example: I implemented easyAutocomplete pack for auto completing my input field and need 4 events:
- v-on:click="addReceiver"(on button 'add') - done
- v-on:enter="addReceiver" (on input field) - done
- click on list item - done
- enter on list item - done
For now my code (without unnecessary things) looks like this:
export default { data() { return { contacts: [], receivers: [] } }, mounted() { this.fetchMessages(); }, methods: { fetchMessages() { axios.get('api/messages').then(response => { this.contacts = response.data.contacts; var options = { data: this.contacts, getValue: "name", list: { match: { enabled: true }, onClickEvent: function() { var name = $("#to").getSelectedItemData().name; $("#list_of_receivers").append("<tr><td>"+name+"</td></tr>"); //this.receivers.push(name); CANT DO THAT ALSO!!! }, onKeyEnterEvent: function() { var name = $("#to").getSelectedItemData().name; $("#list_of_receivers").append("<tr><td>"+name+"</td></tr>"); } } }; $("#to").easyAutocomplete(options); }); }, addReceiver(){ var name = $("#to").val(); $("#list_of_receivers").append("<tr><td>"+name+"</td></tr>"); } } }As you can see I need to duplicate my code in many places, because I cant use function addReceiver() inside for example onClickEvent: jquery list function.
Thank you for any help!
Accessing and filtering child components defined in a Vue.js component's <slot>
I'm in the process of implementing a combined select dropdown and searchbox component for a UI library I'm writing, using Vue.js to drive interactions, but I'm running into a problem with how Vue.js seems to handle communication between parent and child components.
Basically, what I'm aiming to achieve is to allow users of the library to define search-select elements in HTML using something like this:
<search-select> <search-option value="foo">Foo</search-option> <search-option value="bar">Bar</search-option> <search-option value="baz">Baz</search-option> <search-option value="foobar">Foobar</search-option> </search-select>My template for the search-select component looks like this:
<template> <div class="search-select"> <div class="placeholder" ref="placeholder"></div> <ul class="dropdown"> <input type="text" placeholder="Type to filter..." v-on:input="updateFilter" > <slot></slot> </ul> </div> </template>The idea is that the search-select component will add a text input box above the specified inputs, which the user can type in to filter the options that can be selected. The finished component would look something like this.
However, from what I can tell in the documentation, Vue.js doesn't provide any direct way for me to access the properties of the child components from within the parent, nor any way to listen for click events or similar from children within a parent's <slot>.
This means that I don't have a way to filter visibility of the children based on the user's input, or to update the value of the search-select component when a user clicks on one of the children.
The Vue.js documentation mentions ways to pass events from child components to parents, but none seem applicable to elements defined within slots - it appears that parents can only listen for events from components explicitly defined within them.
How would one implement the type of two-way communication between parent and child components required for this use case, without violating any Vue.js best practices related to sharing information between components?
Spotify Track Clone
I am trying to clone the Web Spotify, my project is in Github. The framework that I've been using is Vue.js.
Now I am trying to clone this page, where user can click on the track and the corresponding track in the playlist will be played. Now I can get an object for each track, and there is a preview url, e.g. "preview_url" : "https://p.scdn.co/mp3-preview/4839b070015ab7d6de9fec1756e1f3096d908fba", and I can used the audio tag to play the preview of the music.
The problem is that I don't know how to play the given track when the corresponding play button is clicked.
<track-display v-for="track in tracks" :track-title="TITLE" :artist="artist" :album="ALBUM"></track-display>track-display is an component that I created which is suppose to contain track title, artists and album, which looks like:
Now, I have an array tracks which stores all the track-objects. How am I going to detect which track element is clicked and play the corresponding track?
v-if doesn't recognize value from array of object
I'm working on a vueJS file and have a component :
<div class="panel-heading" v-on:click="displayValue(feature.id)"> {{ feature.nom }} </div> <div class="panel-body" v-if="getDisplay(feature.id)"> foo </div>my function displayValue(id) :
displayValue(id){ for(let i =0; i<this.product_site.displayFeatures.length;i++){ if (this.product_site.displayFeatures[i].idFeature === id){ this.product_site.displayFeatures[i].show = !this.product_site.displayFeatures[i].show } } console.log(this.product_site.displayFeatures) },First I am not very happy with that. I trie to do a .find but it didn't work :
this.product_site.displayFeatures.find(function(a){ a.idFeature === id }).show = trueBut I had an error telling me can not read 'show' of undefined
and my function getDisplay(id)
getDisplay(id){ this.product_site.displayFeatures.forEach(function(a){ if(a.idFeature === id){ return a.show } }) }same as before if I try with a find.
Anyway, I thought it would work with that, but when I do console.log(this.product_sites.displayFeatures) I have the array with the modified value but foo is not shown
filter object by key and its items
I have an object that I would like to filter it's keys..
Im trying to filter the object by an ID, like so:
let myKeys = Object.keys(data).filter(function(key) { //console.log(data[key]); if(parseInt(key) === parseInt(vm.system_id)) { return data[key]; } }); console.log(myKeys);This works, partialy - im getting the key, however, im not getting all the data/items under this item im filtering out
The object im filtering is one similar to this one:
{ "646": [{ "id": 52144, "timestamp": "2017-08-17T14:10:23Z", "type": "alarm", "code": 210, "title": "", "description": "", "remedy": "", "appeared": "2017-08-17T14:10:09Z", "disappeared": null, "acknowlegded": null, "solved": null, "system_name": "CG-MX19D7K5C1", "system_id": 646, "system_device_id": 458, "stream": "cu351.alarm_code" } ], "693": [{ "id": 51675, "timestamp": "2017-08-16T13:59:55Z", "type": "alarm", "code": 215, "title": "", "description": "", "remedy": "", "appeared": "2017-08-16T13:59:57Z", "disappeared": null, "acknowlegded": null, "solved": null, "system_name": "Demo 07122016", "system_id": 693, "system_device_id": 371, "stream": "cu351.alarm_code" }, { "id": 51677, "timestamp": "2017-08-16T13:59:57Z", "type": "alarm", "code": 214, "title": "", "description": "", "remedy": "", "appeared": "2017-08-16T13:59:59Z", "disappeared": null, "acknowlegded": null, "solved": null, "system_name": "Demo 07122016", "system_id": 693, "system_device_id": 371, "stream": "cu351.alarm_code" } ]}
Gulp + Browserify + Vueify ERROR: "Failed to mount component: template or render function not defined"
I am using Gulp, Browserify and Vueify and I am getting this error in console.
You can see it on my Github page
Here is my gulpfile.js:
"use strict" import gulp from 'gulp'; import bower from 'main-bower-files'; import path from 'path'; import { $, isDev, browserSync, getData, reload, orderJSVendor, browserSyncConfig, jadeConfig, root, svgSpriteConfig, imageminConfig } from './config'; import browserify from 'browserify'; import vueify from 'vueify'; import babelify from 'babelify'; import source from 'vinyl-source-stream'; gulp.task("plugins", () => { console.log(getData()) }) gulp.task("build:css", () => { return gulp.src(root.styles.src) .pipe($.plumber()) .pipe($.if(isDev, $.sourcemaps.init())) .pipe($.sass()) .pipe($.autoprefixer({browsers: ['> 1%', 'last 5 versions', 'Firefox ESR','ie 8', 'ie 7']})) .pipe($.if(!isDev, $.csso())) .pipe($.rename({suffix: ".min"})) .pipe($.if(isDev, $.sourcemaps.write('.'))) .pipe(gulp.dest(root.styles.dist)) }); gulp.task("build:html", () => { return gulp.src(root.views.src) .pipe($.plumber()) .pipe($.data(getData)) .pipe($.jade(jadeConfig)) .pipe($.versionAppend(['html', 'js', 'css'])) .pipe($.if(!isDev, $.htmlmin({collapseWhitespace: true}))) .pipe(gulp.dest(root.views.dist)) }); gulp.task("build:js", () => { return browserify({ entries: 'app/scripts/main.js'}) .transform(babelify) .transform(vueify) .bundle() .pipe(source('build.js')) .pipe(gulp.dest(root.scripts.dist)) .pipe(reload({stream: true})) }); gulp.task("build:vendor", () => { let filterJS = $.filter(['**/*.js', '!**/html5shiv/**/*.js', '!**/respond/**/*.js'], { restore: true }), filterLib = $.filter(['**/html5shiv/**/*.js', '**/respond/**/*.js'], { restore: true }), filterCSS = $.filter('**/*.css', { restore: true }), options = { output: { comments: "some" }, nameCache: null, toplevel: false, ie8: false, }; return gulp.src(bower()) .pipe($.plumber()) .pipe(filterJS) .pipe($.order(orderJSVendor)) .pipe($.concat('vendor.min.js')) .pipe($.if(!isDev, $.uglify(options))) .pipe(gulp.dest(root.scripts.dist)) .pipe(filterJS.restore) .pipe(filterLib) .pipe($.concat('ie.min.js')) .pipe($.if(!isDev, $.uglify(options))) .pipe(gulp.dest(root.scripts.dist)) .pipe(filterLib.restore) .pipe(filterCSS) .pipe($.concat('vendor.min.css')) .pipe($.if(!isDev, $.csso())) .pipe(gulp.dest(root.styles.dist)) .pipe(filterCSS.restore) }); gulp.task("build:sprite", () => { return gulp.src(root.sprite.svg) .pipe($.plumber()) .pipe($.cache($.imagemin(imageminConfig.icons))) .pipe($.svgSprite(svgSpriteConfig)) .pipe(gulp.dest(root.sprite.dist)) .pipe(reload({stream: true})) }) gulp.task("copy:images", () => { return gulp.src(root.images.src) .pipe($.plumber()) .pipe($.changed(root.images.dist)) .pipe($.cache($.imagemin(imageminConfig.images))) .pipe(gulp.dest(root.images.dist)) .pipe(reload({stream: true})) }); gulp.task("copy:files", () => { return gulp.src(root.files.src) .pipe(gulp.dest(root.files.dist)) }); gulp.task("copy:fonts", () => { return gulp.src(root.fonts.src) .pipe(gulp.dest(root.fonts.dist)) }); gulp.task("run:server", () => { global.isWatching = true; browserSync.init(browserSyncConfig); gulp.watch( root.watch.styles, ['build:css', reload] ) gulp.watch( root.watch.views, ['build:html', reload] ) gulp.watch( root.watch.scripts, ['build:js']) gulp.watch( root.watch.bower, ['build:vendor', reload]) $.watch( root.watch.svg , $.batch((event, done) => { gulp.start('build:sprite', done); })); $.watch( root.watch.images , $.batch((event, done) => { gulp.start('copy:images', done); })).on('unlink', imgpath => { let srcIMG = path.relative(path.resolve(root.images.basedir), imgpath), distIMG = path.resolve(root.images.dist, srcIMG); return gulp.src(distIMG).pipe($.clean()) }); }); gulp.task("build:clean", () => { return gulp.src(root.clean) .pipe($.clean()) }); gulp.task("build", () => { $.runSequence("build:clean", "build:css", "build:html", "build:js", "build:vendor", "build:sprite", "copy:images", "copy:fonts", "copy:files"); }); gulp.task("default", ["run:server"]);
And this is my app.js:
var Vue = require('vue') var hello = require('../views/components/hello.vue') new Vue({ el: '#wrapper', components: { hello: hello } })
And finally this is screenshot of my project structure:
Why am I getting this error? I will appriciate any help. Thank you.