Software
Vue.js - Accessing global variable in external class and component
I've written a basic form class in JS which I am using alongside vue.js. When the form submit button is clicked I want to toggle a class using vue (which I have done) to make the button show a loading icon.
I have had this working when I had my vue instance and component within the same file, but since I've extracted the form HTML into a separate vue component I can't access the 'isLoading' within the component to listen for it being updated to false. Hopefully this makes sense. Here's my code:
SignUpForm.vue
<template> <form method="post" class="columns signup-form is-multiline" @submit.prevent="onSubmit" @keydown="form.errors.clear($event.target.name)"> <section class="column is-6"> <div class="box"> <h3 class="title is-4">Provide your details</h3> <div class="field"> <div class="control"> <input type="text" class="input" name="name" id="name" placeholder="Full Name" autofocus="true" v-model="form.name"> <span class="help is-danger" v-if="form.errors.has('name')" v-text="form.errors.get('name')"></span> </div> </div> <div class="field"> <div class="control"> <input type="email" class="input" name="email" id="email" placeholder="Email Address" v-model="form.email"> <span class="help is-danger" v-if="form.errors.has('email')" v-text="form.errors.get('email')"></span> </div> </div> <div class="field"> <div class="control"> <input type="password" class="input" name="password" id="password" placeholder="Choose a Password" v-model="form.password"> <span class="help is-danger" v-if="form.errors.has('password')" v-text="form.errors.get('password')"></span> </div> </div> <div class="field"> <div class="control"> <input type="password" class="input" name="password_confirmation" id="password_confirmation" placeholder="Repeat Password" v-model="form.password_confirmation"> <span class="help is-danger" v-if="form.errors.has('password_confirmation')" v-text="form.errors.get('password_confirmation')"></span> </div> </div> <div class="control"> <button type="submit" class="button is-primary is-fullwidth" :class="{ 'is-loading': isLoading }">Sign up</button> </div> </div> </section> </form> </template> <script type="text/ecmascript-6"> export default { data: function () { return { form: new Form({ name: '', email: '', password: '', password_confirmation: '' }), isLoading: false } }, methods: { onSubmit() { this.form.submit('post', '/register'); } } } </script>app.js (main vue instance)
require('./bootstrap'); import axios from 'axios'; import Form from './classes/Form'; import SignUpForm from './components/SignUpForm.vue'; window.Vue = require('vue'); window.Form = Form; window.axios = axios; window.axios.defaults.headers.common = { 'X-Requested-With': 'XMLHttpRequest' }; window.app = new Vue({ el: '#root', data: { isLoading: false }, components: { SignUpForm } });Form.js (custom form class) - this class updates the app.isLoading when necessary
import Errors from './Errors'; class Form { /** * Form constructor accepting data object equals * fields. * * @param {object} data * @return {null} */ constructor(data) { this.originalData = data; for (let field in data) { this[field] = data[field]; } this.errors = new Errors(); } /** * Returns form data for submission. * * @return {object} data */ data() { let data = Object.assign({}, this); delete data.originalData; delete data.errors; return data; } /** * Resets the form * * @return {null} */ reset() { for (let field in this.originalData) { this[field] = ''; } if (app.isLoading) app.isLoading = false; } /** * Submits the form then delegates to onSuccess or * onFail methods. * * @param {string} requestType * @param {string} URL to target * @return {null} */ submit(requestType, url) { app.isLoading = true; axios[requestType](url, this.data()) .then(this.onSuccess.bind(this)) .catch(this.onFail.bind(this)); } /** * Handle a successful form submission. * * @param {object} response * @return {[type]} */ onSuccess(response) { alert(response.data); this.errors.clear(); this.reset(); } /** * Handle a failed form submission. * * @param {object} error * @return {[type]} */ onFail(error) { app.isLoading = false; this.errors.record(error.response.data.errors); } } export default Form;Hopefully what I'm trying to do, and the problem I am experiencing makes sense.
Thanks in advance for any help.
Vue.js, How to get tag in directive?
...
methods: { frameShow: function () { //id = a1 or a2 return (id === "a1") ? true : false; }, }How get value id ("a1" and "a2") in method frameShow, when the directive is executed. Or html element?
VueJS combine data sources
I have two data sources, one that I created inside my Vue instance and another that I am importing from an api. How do I match the data that I get from the api and combine it with the data I created to display in one table?
HTML:
<div class="ui container" id="app"> <br> <div class="ui two column divided grid"> <div class="row"> <div class="ten wide column"> <table class="ui unstackable green table"> <thead> <tr> <th>Instrument</th> <th class="right aligned">Position</th> <th class="right aligned">Price</th> <th class="right aligned">Total</th> <th class="right aligned">%</th> </tr> </thead> <tbody> <tr v-for="item in watchlist"> <td>{{ item.instrument }}</td> <td class="right aligned">{{ item.position }}</td> <td class="right aligned"></td> <td class="right aligned"></td> <td class="right aligned"></td> </tr> </tbody> </table> </div> <div class="six wide column" :attribute="priceData"> <table class="ui unstackable red table"> <thead> <tr> <th class="center aligned">Coin</th> <th class="center aligned">Price</th> </tr> </thead> <tbody> <tr v-for="coin in prices"> <td>{{ coin.name }}</td> <td class="center aligned">{{ coin.price_usd }}</td> </tr> </tbody> </table> </div> </div> </div> </div>Currently I have two tables that each displays the data that I would like to combine into one table.
Vue:
new Vue({ el: '#app', data: { watchlist: [ { instrument: 'Artbyte', position: 10000 }, { instrument: 'Civic (CVC)', position: 1000 }, { instrument: 'IOTA', position: 600 }, { instrument: 'Basic Attention Token', position: 600 }, { instrument: 'Sentiment (SAN)', position: 500 }, { instrument: 'TenX', position: 400 }, { instrument: 'OmiseGo', position: 100 }, { instrument: 'EOS', position: 200 }, { instrument: 'Litecoin', position: 30 }, { instrument: 'Ethereum', position: 10 }, { instrument: 'Bitcoin', position: 2 }, { instrument: 'District0x', position: 2000 }, { instrument: 'Aragon', position: 60 }, { instrument: 'LBRY Credits', position: 200 } ], prices: [] }, computed: { priceData: function () { var t = this axios.get('https://api.coinmarketcap.com/v1/ticker/') .then(function (response) { t.prices = response.data }) .catch(function (error) { console.log(error) }) }, getPrices: function () { return this.price } } })heres a jsfiddle https://jsfiddle.net/brklyn8900/83y53b2k/12/
Call method from other componet vue js & laravel
I made a small social network, I need that when following a user the list of friends is updated backend in laravel and frontend in vuejs
Clicking on following a user updates the list of possible friends and updates the list of friends that is in another component
blade
<div class="col-md-2"><amigos></amigos></div> <div class="col-md-8"><post-list></post-list></div> <div class="col-md-2"><no-amigos></no-amigos></div>app.js
Vue.component('post-list', require('./components/Posts.vue')); Vue.component('amigos', require('./components/Amigos.vue')); Vue.component('no-amigos', require('./components/noamigos.vue')); const app = new Vue({ el: '#app' });noamigos.vue (component)
<template> <div class="panel panel-default"> <div class="panel-heading">Amigos sugeridos</div> <div class="panel-body"> <div class="list-group" v-for="item in noamigos"> <a href="#" class="list-group-item"> <h4 class="list-group-item-heading">{{item.name}}</h4> <button class="label label-success btn" v-on:click="seguir(item)"><b>+</b> Seguir</button> </a> </div> </div> </div> </template> <script> export default{ data:()=>({ noamigos: [], }), methods:{ listarNO:function(){ axios.get('noamigos').then(response =>{ this.noamigos = response.data; }) }, seguir:function(codigo){ axios({ method: 'POST', url: 'noamigos', data: { codigo: codigo.id_, }, }).then((response) => { this.listarNO(); //do somethig to call method listarSi() on Amigos component }).catch((error) => { console.log(error); }); } }, created(){ this.listarNO(); } }Amigos.vue (componet)
<template> <div class="panel panel-default"> <div class="panel-heading">Mis Amigos</div> <div class="panel-body"> <div class="list-group" v-for="item in siamigos"> <a href="#" class="list-group-item"> <h4 class="list-group-item-heading">{{item.name}}</h4> </a> </div> </div> </div> </template> <script> export default { data:()=>({ siamigos: [], }), methods:{ listarSI:function(){ axios.get('amigos').then(response =>{ this.siamigos = response.data; }) }, }, created(){ this.listarSI(); } }different ways to render Vue template from a variable without vue router
I am currently using Vue JS and I am not using any router. I am not using stand-alone build and would like to implement with webpack and use it with .vue extension. Looking for better way to render a Vue template using a variable. For example :
// App.Vue var Loading = { template: `<div>Loading...</div>` } // main.js var currentView = Loading; new Vue({ el: "#app", render(h) { return h(currentView); } });The above example perfectly works fine without any issues. Would like to understand if there is a better way to handle.
Let's say if currentView contains a string like
currentView = "Loading" render(h) { return h(eval(currentView)); // works return h([currentView]); // template not found or mount error }How can we replace the value to the template before its passed to render function ?
Thanks in advance.
How to redirect to a different url inside the vue-router beforeRouteEnter hook?
I am building an admin page with Vue.js 2 and I want to prevent unauthenticated users from accessing the /admin route and redirect them to /login. For that I have used the In-Component Guard beforeRouteEnter in the Admin component like follows
... beforeRouteEnter(to, from, next) { if(userNotLogedIn) { this.$router.push('/login'); } }The problem here is that this is not defined in beforeRouteEnter hook. So what's the proper way to access $router and redirect to a different url in this case ?
I'm not geting data form database
I'm using vue.js in my Laravel chat project in that i'm using this to print messages in console:
<script> export default { date(){ return{ messages:[] } }, mounted () { axios.get('/chat/messages').then((response) => { console.log(response); //this.messages = response.data }); } } </script>but i'm not getting my messages in my browser's console.
sw.js forcing page to reload
My auth page will load, and then after a second or two, it will reload itself again.
I've not been able to figure out how to reproduce, but think it's being caused by sw.js reloading fresh assets.
Every time it happens I see the same service worker items in the console.
Why is sw.js forcing the page to reload and how can I prevent it from happening?
Prevent on click on parent when clicking button inside div
Is it possible to prevent the function on the <div> element from running when clicking the button inside the div?
When clicking the button element, the function: toggleSystemDetails should not be triggered? Is this possible in Vue?
<div v-on:click="toggleSystemDetails($event, system.id);" class="grid-tile__list-item" v-for="(system, index) in organization.systems" :key="system.id" :class="{'in-viewport fully-in-viewport': system.inview, 'is-xsmall': system.layout === 'xsmall', 'is-small': system.layout === 'small', 'is-medium': system.layout === 'medium', 'is-large': system.layout === 'large'}"> <div class="grid-tile__list-item--overlay"> <button v-on:click="toggleTileOptionsMode($event, system.id, system.name, system.layout)"> Layout Settings </button> </div>Vue.js: best practice with managing JS for other components
I have a simple website set up with Vue.js. I have a component for each page (About us, Contact us, etc). Each component fetches the markup for the page via ajax then injects it using <vue-router>.
So far so good.
My question is: what should I do with all the JS that's only used for specific components? My home page might have ~100 lines of JS just for setting up image sliders, hover events, etc. Once I load the About Us component, all that JS for the home page still exists in the browser but it's no longer relevant. Should I manually be nullifying my variables?
What about this case: User visits the Home page, then the About page, then back to Home. On the 2nd visit of the home page, all my old variables still exist, but aren't necessarily in the correct state anymore. I'll want to move sliders back to slide 1, reset any hovers... basically just reset the page.
I guess I'm asking for a very high level overview on how to best manage the JS for multiple components and how it all ties in with document.ready and window.load callbacks once they've already fired and won't fire again. Thanks.
How to filter data from each filter value in Vuejs2?
I am trying to create filters with dynamic parameters for a datatable in vuejs2 . the grid data come from an Api rest in Laravel. I have a computed function which filters data and all filters are in different inputs. I have an object that has the values of the filters. i have the filter in a computed function but i am filtering with conditions. how can i filter for each filter value in each item property?, how can i make my code works for each item in the filters and every property of the data object without write all the conditions?
my data is :
data:function(){ gridFields:{gridfilters:{fname:'',fdescription:''}}, gridApiData: [ { "id": 10057, "name": "10053", "description": "10053" }, { "id": 10058, "name": "10054", "description": "10054" }, { "id": 10059, "name": "10055", "description": "10055" } ] }The fname and fdescription are the values of the input filters.
my computed function is :
computed:{ //I need to filter the data array with all the filters from the filter object gridFields.gridfilter dataList:function(){ var vm = this; return this.gridApiData.filter(function (item) { if(vm.gridFields.gridfilters.fname && !vm.gridFields.gridfilters.fdescription){ return (item.name.toLowerCase().indexOf(vm.gridFields.gridfilters.fname.toLowerCase()) !== -1); } if(!vm.gridFields.gridfilters.fname && vm.gridFields.gridfilters.fdescription){ return (item.description.toLowerCase().indexOf(vm.gridFields.gridfilters.fdescription.toLowerCase()) !== -1); } if(vm.gridFields.gridfilters.fname && vm.gridFields.gridfilters.fdescription){ return ((item.name.toLowerCase().indexOf(vm.gridFields.gridfilters.fname.toLowerCase()) !== -1) && (item.description.toLowerCase().indexOf(vm.gridFields.gridfilters.fdescription.toLowerCase()) !== -1)); } return item;}); } },thank you for all the suggestions.
How to make a 'most common time of day' chart javascript?
Google Analytics has a great chart in the section "When do your users visit?"
The title is "Users by Time of Day"
The X Axis (bottom of chart) shows "Sun Mon Tues Wed Thurs Fri Sat"
The Y Axis (right side of chart) shows "12am 2am 4am 6am ..."
In the chart are boxes colored dark blue for busy times, lighter blue for less busy times.
Hovering shows the number the box represents
I cannot find a chart anywhere to do this, unfortunately not even Google Charts offers a chart like this
I want to visually represent the most common times users play an online game, that way it will be clearly represent that "9pm on a Sunday" is the best time to play for example.
Anyone know of a javascript library to make a chart like this??
Vue not setting <select> value by v-model in IE
This seems to work in Chrome, but not IE. Do you have any ideas why?
<select v-model="selected"> <option v-for="option in options" :value="option">{{ option.foo }}</option> </select> var data = [{ foo: 1 }, { foo: 2 }] var demo = new Vue({ el: '#demo', data: { selected: null, options: data }, mounted: function() { this.selected = data[1] } })Invalid expression passing props in vue.js template - IE11
I'm new to vue.js and I'm trying to create a vue component.
Vue.component('sales-report', { data: function(){ return {products: products, seasons: seasons}} template: '<course-details-menu :dropdown-data="{ products, outlineClassifications, seasons, years }"></course-details-menu>' });This is a simplified example of my app, and it works in Chrome, but in IE, I get this error from vue:
Error compiling template:: - invalid expression: :dropdown-data="{ products, seasons }" found in --->
VueJS - When input value change, display in another div
I would like, to capture the value of my input and display on another div.
Look my code :
If you look the code, I save the value in function msgFunc, and after that I would apply this result in my variable msg, but I don't understand.
Thanks !
export default { data () { return { msg: '' } }, computed: { msgFunc: () => { return this.value } } } .flex { display: flex; flex-flow: row wrap; justify-content: center; align-items: center; height: 90%; } .input-container { width: 410px; background-color: #fff; padding: 2px 15px 20px 15px; box-shadow: 0 16px 24px 2px rgba(0,0,0,0.14), 0 6px 30px 5px rgba(0,0,0,0.12), 0 8px 10px -5px rgba(0,0,0,0.3); transition: transform .1s ease-in-out; } .input-container input { margin-top: 10px; width: 100%; border-bottom: 1px solid #25A3FF; padding: 10px 0; font-size: 16px; color: #929292; } input:focus { outline: none; } <div class="flex"> <section class="input-container"> <input type="text" v-model="msg" @change="msgFunc" placeholder="Type your HEX color"> <h3>{{msg}}</h3> </section> </div>
Vue js toggle class of individual element
While there are many examples of toggling classes in Vuejs, I am yet to find one that toggles a class narrowing down the scope of the element. If I define a global variable like this:
data { toggle: false }I will run into a problem when I have an element, like this navigation bar:
<ul class="menu"> <li class="has-dropdown" v-bind:class="{ 'is-open': toggle }" @click="toggle = !toggle"> Foo <ul class="dropdown"> <li>Dropdown Item 1</li> <li>Dropdown Item 2</li> </ul> </li> <li class="has-dropdown" v-bind:class="{ 'is-open': toggle }" @click="toggle = !toggle"> Bar <ul class="dropdown"> <li>Dropdown Item 1</li> <li>Dropdown Item 2</li> </ul> </li> </ul>See what happens here? If I click in one of these two elements, both are going to toggle the class, because it's changing a global variable. Now, how would I toggle the class of only the element that is clicked?
How to make a condition to add/remove data param in Vue?
e.g.:
<div :data-some="someData ? okay : bad" :data-someother="someOtherData ? okay : bad"> </div>I want not to specify any data-params if there's "bad" in the result.
How can I do that?
Add row to table with vue.js in a v-for tag
I need to add rows in table #dynamic but table static shouldn't be affected. If i hit button with the code below, of cause both tables will be updated, because they have the same v-for. And if I put a v-for in a v-for my datas wont be fetched. I can't figured it out how to "unique" the first table.
vue/html <template> <table id="dynamic"> <tr v-for="rows in list"> <td>Content of row {{ rows.item1 }}</td> <td>Content of row {{ rows.item2 }}</td> </tr> </table> <div @click="block = !block">click</div> <table id="static"> <tr v-for="rows in list"> <td>Content of row: {{ rows.item3 }}</td> <td>Content of row: {{ rows.item4 }}</td> </tr> </table> </template> js export default { data: function () { return { list: [], }; }, props: ['channelId'], mounted() { }, created() { this.fetchChannel(this.channelId); }, methods: { fetchChannel: function (channelId) { $.getJSON('/api/channel/' + channelId, function (data) { this.list = data; }.bind(this)); }, } }I found some examples for help like this codepen or fiddle but I am not successful with it.
Hope somebody can help me in my case.
Vuejs display a value within an object returned by a method
I want to display the 'name' value only, within the object returned from the method.
What is currently displayed is: [ { "city": "Ottawa", "name": "Senators", "province": "Ontario", ".key": "-Kp00XARET2EDFRZVMks" } ]
I want displayed is "Senators".
Here's snippets of my code:
... in the template <td>{{props.item.away}} {{ teamDetail(props.item.away) }}</td> ... in the script methods: { teamDetail(inpt) { return this.teams.filter((team) => { return team['.key'] == inpt; }) },props.item.away is the .key sent to teamDetail to retrieve the object for a specific team, the object returned in this case is [ { "city": "Ottawa", "name": "Senators", "province": "Ontario", ".key": "-Kp00XARET2EDFRZVMks" } ]
to display the 'name' only, I tried within the template {{ teamDetail(props.item.away).name }} and within the filter in the method
Can't load images from assets folder in nested components (Vue.js 2.0 / Webpack)
I'm new to webpack and Vue.js. I'm facing issues when trying to load images/videos in my nested components, it gives me "not found" error. I have project structure like that: Project structure image
Let's say in Signup.Vue I want to load an image from the assets folder, how can I do that? Because ".../assets/my-img.jpg" didn't work out, "assets/my-img.jpg" neither. In css I figured out that using require with "~" works (ex. '~assets/my-img.jpg" ). I don't undestand how paths work.
Placing my images in the same component's folder would be an option, but I want to use the main assets folder where I can fetch media from.
Using: webpack 2.7.0 / vue 2.0
Thank you in advance