Vuejs
Bind Styles After Ajax Call
On mounted(), I make an ajax call which pulls in div-specific data such as position on the screen. The problem is that my custom method to set v-bind:style from the ajax data gets run before ajax is finished, thus no data is there to pull from. What is the best way to set my style after ajax is done?
Ajax call returns something like this: [{name: 'table1', top: 10, left: 25},{name: 'table2', top: 30, left: 100}]
$(function() { var app = new Vue({ el: '#main', data: { tables: [] }, methods: { computeOffsets() { return { top: this.tables.top + 'px', left: this.tables.left+ 'px'} } }, mounted() { $.ajax({ method: 'POST', dataType: 'json', url: base_url + 'tables/getTables/' + event_id }).done(data => { console.log(data); this.tables = data; }); } }); }); .table { position: absolute; } <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.min.js"></script> <div id="main"> <div class='table' v-for="table in tables" v-bind:style="computeOffsets()"> {{table.name}} </div> </div>
Getting element that is created with vue2, using jQuery
I have couple of inputs which I created with v-for and I have structured them like this:
<input class="form-control" type="text" :id="'info[' + client + '][' + index + '][name]'"So, id of an element is for example info[1][1][name]. I can confirm it in inspector.
Now, I am trying to change it's value. The easiest way seemed jQuery to me, because I need to get field information from another component and write on this input (and I knew the client & index so I could $() easily).
As id of our element is info[1][1][name], I tried using $('#info[1][1][name]) in the console but I couldn't get it. Also tried $('body').find('#info[1][1][name]), but no luck either.
What am I doing wrong?
How can I use the axios.interceptor in a right way?
I use vue-cli and this is part of my main.js
import Vue from 'vue' import App from './App' import axios from 'axios' import VueAxios from 'vue-axios' Vue.use(VueAxios, axios) Vue.config.productionTip = false new Vue({ el: '#app', template: '<App/>', components: { App } })In Vue's single File components' structure, I use axios to replace the ajax.
Vue.use(VueAxios, axios)It makes axios available in every SFC by referring (this.axios). But when I try to use axios.interceptor, I come across an annoying problem. I want to set axios.interceptor.request and axios.interceptor.reponse for the whole project. however, I can only use this.axios.interceptor.request in a Single File Component and it only work in this file. This is the part code of App.js.
methods: { // interceptor setAxiosInterceptor () { this.axios.interceptors.request.use(config => { this.cover = true return config }, error => Promise.reject(error) ) this.axios.interceptors.response.use(response => { this.cover = false return response }, error => { this.cover = false return Promise.reject(error) }) },I have to set this.axios.interceptor in every SFC. So how can I set the axios.interceptor for the whole project and make it available in every SFC.
Component based theming
I'm a front-end developer. I use my custom made CSS framework with sass. I have some jquery knowledge and a little javascript knowledge. I have heard a lot about angular, react, vue, ember etc. But I don't know how can I use them or how they are useful.
I try to explain my needs with some examples.
1- I use jquery ajax to upload and remove image. For this I need define input file and some javascript codes then style with css. For this I want to use something like below. And all html, css, javascript loads
<imageUpload></imageUpload>2- I have a nav section in my website. One in the header, one in the footer. They are some except some minor styles. I want to define default nav and have a option to override some values like below.
<myNav></myNav> <myNav place="footer></myNav>NOTE: All my codes are imaginary. I don't need and backend features. I'm going to use PHP for that. All I need front end things. (html, css, javascript, jquery, interaction, dom manipulation etc)
You don't have to recommend only one framework. I just need which one/ones are suitable for this job
How to pass global variable from parent to child in Vuejs?
I have a page called Profile.vue which is structured like this,
<style> </style> <template> <component-1></component-1> <component-2></component-3> <component-3></component-3> </template> <script> import component1 from '...../..' import component2 from '...../..' import component3 from '...../..' export default { name: 'profile', data(){ return{ pagename: 'Profile', mydata: 'This is my data' } } } </script>How do i make the data available in mydata, to all the components that I am importing,i.e, how can I pass data that would be available to all the components?
Update value in multidimensional array in Vue
I understand from the caveats portion of the Vue docs that updating a value in an array in the following manner will not work:
this.arr[idx] = newValand that one should use splice(). I am using a 2D array to store grid data, and I am having a difficult time updating the value when a cell in the grid is clicked.
Here is my template:
<tr v-for="(row, rowKey, index) in grid" :key="rowKey"> <th class="row-col-label" >{{rowKey+1}}</th> <td v-for="(col, colKey, index) in row" :key="colKey" @click="selectCell(rowKey, colKey)" :class="{'selected' : cellSelected(rowKey, colKey)}" > {{col}} </td> </tr>And here is the relevant code for the Vue component:
created () { this.initColHead() this.createSpreadSheet() }, data () { return { selected: '', grid: [], colHead: [' '], isSelected: false } }, methods: { initColHead () { this.colHead.push(...'ABC'.split('')) }, createSpreadSheet () { for (let i = 0; i <= 2; i++) { this.grid[i] = [] for (let j = 0; j <= 2; j++) { this.grid[i][j] = false } } }, selectCell (row, col) { this.isSelected = true console.log(`row ${row} col ${col}`) this.grid[row].splice(col, 1, true) for (let i = 0; i <= 2; i++) { for (let j = 0; j <= 2; j++) { console.log(this.grid[i][j]) } } }, cellSelected (row, col) { return (this.grid[row][col] === true) } }So I am attempting to add a true value to the cell that is click at the given row col locations provided in the my selectCell method. However, the data in my grid is not updated to reflect the newly added value. How exactly do I update values in a multidimensional array in Vue?
Adding Mutations to Vuex store as part of Vue Plugin
I'm creating a small Vue Plugin that allows a user to add a "page notification" from within any component. I've successfully implemented something like:
this.$notifications.add("a message");
And it works! But I've had to register the mutations and actions required for my plugin to work as part of the file that sets up the rest of the store for my app:
export default new Vuex.Store({...})
Is there a way to add actions and mutations to my store from within my plugin? It currently looks like this:
import vuex from './../store'; const MyPlugin = { install(Vue, options) { // 4. add an instance method Vue.prototype.$notifications = { notificationTypes: { 0: "warning", 1: "info" }, add: function (options) { let id = "page-notification-" + (vuex.state.pageNotificationsCreated + 1); let message = options.message || options || "no message"; let notificationType = this.notificationTypes[0]; if(options.notificationType && Number.isInteger(options.notificationType)){ // Map int to string type notificationType = this.notificationTypes[options.notificationType] || notificationType; }else{ // Or use string we were provided ;) notificationType = options.notificationType; } let notification = { id: id, message: message, notificationType: notificationType }; vuex.dispatch('addNotification', notification); } } } }; export default MyPlugin;Any and all help appreciated!
Build.js.map not found?
I have a web app using Webpack and Vue.js. It works perfectly on most of the browsers. However Safari can't find build.js.map, which is not in the directory, and I do not include it anywhere.
Can anyone explain why is it looking for it?
Watching vuex state change from vuejs component
I am new to both vue.js and vuex. I have a component that need to dispatch an action when a specific data is available in the state. How can I do this.
Thanks
Unknown custom element: - did you register the component correctly?
I'm new to vue.js so I know this is a repeated issue but cannot sort this out.
the project works but I cannot add a new component. Nutrition component works, profile does not
My main.js
import Nutrition from './components/nutrition/Nutrition.vue' import Profile from './components/profile/Profile.vue' var Vue = require('vue'); var NProgress = require('nprogress'); var _ = require('lodash'); // Plugins Vue.use(require('vuedraggable')); // Components Vue.component('nutrition', Nutrition); Vue.component('profile', Profile); // Partials Vue.partial('payment-fields', require('./components/forms/PaymentFields.html')); // Filters Vue.filter('round', function(value, places) { return _.round(value, places); }); Vue.filter('format', require('./filters/format.js')) // Transitions Vue.transition('slide', {enterClass: 'slideInDown', leaveClass: 'slideOutUp', type: 'animation'}) // Send csrf token Vue.http.options.headers['X-CSRF-TOKEN'] = Laravel.csrfToken; // Main Vue instance new Vue({ el: '#app', components: { }, events: { progress(progress) { if (progress === 'start') { NProgress.start(); } else if (progress === 'done') { NProgress.done(); } else { NProgress.set(progress); } }, 'flash.success': function (message) { this.$refs.flash.showMessage(message, 'success'); }, 'flash.error': function (message) { this.$refs.flash.showMessage(message, 'error'); } } });Profile.vue
<template> <div class="reddit-list"> <h3>Profile </h3> <ul> </ul> </div> </template> <script type="text/babel"> export default { name: 'profile', // this is what the Warning is talking about. components: { }, props: { model: Array, } } </script>profile.blade.php
@extends('layouts.app') @section('title', 'Profile') @section('body-class', 'profile show') @section('content') <script> window.Laravel.profileData = [] </script> <profile></profile> @endsectionWhenever I try to go to this page I get:
[Vue warn]: Unknown custom element: <profile> - did you register the component correctly? For recursive components, make sure to provide the "name" option.
I tried doing a local component such as
Vue.components('profile', { template: '<div>A custom component!</div>' });or even I tried adding the profile into the components in vue but still no luck, can anyone point me in the right direction?
Laravel validation on multiple insert
I have a db table of sport events. Each event has a year, event name and an event winner.
My admin view for this table allows the events to be grouped by year and inserted in bulk (generally 8 sports events rows at once). I have a table, written in Vue that allows up to 8 sports events rows to be added to the interface, fields populated and submitted. This works well.
The method for this is
public function storeMultiple(Request $request) { $year = $request->year; $newEvents = $request->events; foreach ($newEvents as $key => $value) { DB::table('sport_events')->insert([ 'team_id' => 1, 'sort_order' => $value['sort_order'], 'year' => $year, 'event' => $value['event'], 'winner' => $value['winner'], 'created_at' => Carbon::now(), 'updated_at' => Carbon::now() ]); } }While I know it's not a great way (the db structure limits me here rather than having year be the key and sport events within) and for such a small and infrequent use case, I'm happy with the performance trade off.
The form is submitted to my route via Axios and everything lands in the database as I'd expect.
Now I'm looking to add validation to the method, ensuring that each event has event name and the winner.
$validator = Validator::make($request->all(), [ 'year' => 'required', 'events.*' => 'required', ]); if ($validator->fails()) { return response()->json([ 'errors' => $validator ]); }It seems that my submit bypasses the validation checks that I have in place, getting a success status.
My Vue submit method does this
submit () { axios({ method: 'post', url: '/admin/sports', data: { year: this.year, sports: this.sports } }).then((response) => { window.location.href = '/admin/sports' }).catch((error) => { // error }) }Where am I going wrong in this method?
Bulma not compiling with VueJS
I'm using the vue-cli with webpack-simple and it has sass integration out of the box. In fact, I can run my own sass without any issues. For example, below works:
<style lang="sass"> #app background: red </style>The following blocks of code produce the same error:
<style lang="sass" src="bulma"></style>and
<style lang="sass"> @import 'bulma' </style>Here's the error:
Module parse failed: /Users/johnbriggs/Code/petiq-vue/node_modules/bulma/bulma.sass Unexpected character '@' (1:0)Seems like the built in parser can't handle the @ symbol setting the charset. Any thoughts? I'd like to use this through npm without copy/pasting and removing all the @ symbols.
Set same value for sibling component's select
Using v-for, I am looping through a component. The component is for each client. In this component, I have same form for each client and when a select value is selected for the first component (client 1), I want to select this value for every client.
Do I need to pass the data to the root and create a single source of truth variable?
I tried setting up a basic version:
<div id="app"> <my-comp v-for="x in 2" v-bind:val="x"></my-comp> </div> Vue.component('my-comp', { props: ['val'], template: ` <div> <div> <label>Status</label> <select :data-client="val" @change="statusChanged"> <option selected="" disabled="" value="0"></option> <option value="xxx">Xxx</option> <option value="yyy">Yyy</option> <option value="zzz">Zzz</option> </select> </div> </div> `, methods: { statusChanged(e) { var client = e.target.getAttribute('data-client') if (client == 1) { alert('set same value for client 2') } } } }) new Vue({ el: '#app', })Here is a fiddle: https://jsfiddle.net/w53164t2/
Best approach to render read only content in Vue
I have the following code that I'm using to render messages between 2 users
<template> <main> <form action="" method="post" @submit.prevent="sendMessage"> <textarea name="message" id="message" cols="30" rows="10" placeholder="Message"> </textarea> <input type="submit" value="Send"> </form> <section v-if="messages.length"> <div v-for="message in messages"> {{message.body}} <hr> </div> </section> <section v-else> No messages </section> </main> </template> <script> import ajax from './ajax'; export default { data () { return { messages: [] } }, methods: { sendMessage(e){ }, getMessages(pageNum, cb){ ajax({ url: `${window.location.pathname}?p=${pageNum}`, method: 'get', callback(res){ cb(JSON.parse(res)); } }) } }, created(){ var vm = this; vm.getMessages(1, (res) => { vm.messages = res.data; vm.loaded=true; }); } } </script>Specifically the code v-for="message in messages", the message property in my component. These messages will be read only so there will be no event listeners or anything. So it will not be the best way to keep them in array after the ajax call. However, there will be a load more button that loads 10 messages in a call and those will be appended to array.
So I want to ask how do I go about this without keeping the messages in array after rendering but still keeping them on the page? Or if you can suggest a better, efficient, way to implement this, I will appreciate it.
Thanks.
how to convert objects into array?
I am trying to manipulate data which is coming in an array like this
[ { "level_id": 1, "level_name": "1", "level_image": "", "task_name": "game" }, { "level_id": 1, "level_name": "1", "level_image": "", "task_name": "taskgame" }, { "level_id": 1, "level_name": "1", "level_image": "", "task_name": "jenga" } ]I want to convert the data into this
[ { "level_id":1, "level_name":"1", "level_image":"", task_name[ "task_name":"game", "taskgame","jenga" ] } ]Vue JS Modal doesen't wok
I've created a modal component in Vue JS. It has to display all the names typed in the form. It doesen't work. What I can do to solve this problem? I'm new in Vue JS. Also I can't use shorthands. Do you know why? PLease help me. Thank you in advance. This is my code:
<template> <div class="template_class"> <div> <b-btn v-b-modal.modal1>Launch demo modal</b-btn> <!-- Main UI --> <div class="mt-3 mb-3"> Submitted Names: <ul> <li v-for="n in names">{{n}}</li> </ul> </div> <!-- Modal Component --> <b-modal id="modal1" title="Submit your name" @ok="submit" @shown="clearName"> <form @submit.stop.prevent="submit"> <b-form-input type="text" placeholder="Enter your name" v-model="name"></b-form-input> </form> </b-modal> </div> </div> </template> <script> export default { data: { name: '', names: [] }, methods: { clearName() { this.name = ''; }, submit(e) { if (!this.name) { alert('Please enter your name'); return e.cancel(); } this.names.push(this.name); this.name = ''; } } } </script> <!-- Add "scoped" attribute to limit CSS to this component only --> <style scoped> </style>Get Vue to update view/component
I'm stuck at a crossroads with a component I am working on.
I have the following component "RecentUpdates"
Within it I am passing props down to a few other components, as you can see from the top of the file.
My problem is when adding a new post, I can not figure out how to get the correct update object array back and i also can not figure out the correct 'Vue way' to update the data prop that is being passed down to the "PostList" component.
<template> <div> <PostFilter v-on:selectedCategory="getSelectedPosts" v-on:showAllPosts="showAllPosts" :user="user" :categories="categories"/> <PostList v-if="recent_posts[0]" :categories="categories" :posts="recent_posts[0]" :user="user"/> <Pagination v-on:getPreviousPage="getPreviousPage" v-on:getNextPage="getNextPage"/> </div> </template> <script> import PostList from './PostList'; import PostFilter from './PostFilter'; import Pagination from './Pagination'; import EventBus from '../event-bus'; export default { name: 'RecentUpdates', data: () => ({ errors: [], recent_posts: [], }), props: ['categories', 'user'], components: { PostList, PostFilter, Pagination }, created() { if (this.user.meta.selected_categories[0] == 0) { this.showAllPosts(); } // do not call here, not working as expected // is switching selected category to an incorrect one // this.updateList(); this.getSelectedCategory(); }, watch: { recent_posts: function(newValue) { EventBus.$on('addPost', function(newPost) { console.log(newPost); this.$forceUpdate(); //this.recent_posts.push(newPost); //this.$set(this.recent_posts, newPost, newPost); // this.$nextTick(function () { // this.recent_posts.push(newPost); // }); }); console.log(this.recent_posts[0]); // this.$nextTick(function () { // console.log(this.recent_posts[0]) // => 'updated' // }); // if (this.user.meta.selected_categories[0] == 0) { // EventBus.$on('addPost', this.showAllPosts); // } else { // EventBus.$on('addPost', this.getSelectedCategory); // } //this.updateList(); } }, methods: { // updateList() { // if (this.user.meta.selected_categories[0] == 0) { // EventBus.$on('addPost', this.showAllPosts); // //EventBus.$emit('newPost'); // } else { // EventBus.$on('addPost', this.getSelectedCategory); // //EventBus.$emit('newPost'); // } // }, getSelectedCategory() { let categoryId = this.user.meta.selected_categories[0]; this.getSelectedPosts(categoryId); }, showAllPosts() { axios.get('/wp-json/wp/v2/posts?_embed=true&status=[publish,resolved,unresolved]', {headers: {'X-WP-Nonce': portal.nonce}}) .then(response => { this.recent_posts = []; //this.recent_posts = response.data; //console.log(response.data); this.recent_posts.push(response.data); console.log(this.recent_posts[0]); }) .catch(e => { this.errors.push(e); }); }, getSelectedPosts(categoryId) { axios.get('/wp-json/wp/v2/posts?_embed=true&status=[publish,resolved,unresolved]&categories=' + categoryId, {headers: {'X-WP-Nonce': portal.nonce}}) .then(response => { this.recent_posts = []; //console.log(response.data); this.recent_posts.push(response.data); console.log(this.recent_posts[0]); }) .catch(e => { this.errors.push(e); }); }, /** * Pagination methods * */ getPreviousPage(page) { axios.get('/wp-json/wp/v2/posts?_embed=true&status=[publish,resolved,unresolved]&page=' + page, {headers: {'X-WP-Nonce': portal.nonce}}) .then(response => { this.recent_posts = response.data; }) .catch(e => { this.errors.push(e); }); }, getNextPage(page) { axios.get('/wp-json/wp/v2/posts?_embed=true&status=[publish,resolved,unresolved]&page=' + page, {headers: {'X-WP-Nonce': portal.nonce}}) .then(response => { this.recent_posts = response.data; }) .catch(e => { this.errors.push(e); }); } }, } </script> <style> </style>Enclosing a router-link tag in to a button in vuejs
How do I wrap or enclose a router-link tag in a button tag? so when I press button it routes me to the desired page.
VueJS draggable/sortable JSON doesn't update
hey guys i am using this lib, at the moment i am trying just a simple sortable, imagine i have a array with 3 elements i want to change his positions with drags, i am able to doing it at the moment. The thing is, when i swich the places my JSON array doesn't update.
I am doing this:
my list:
<draggable v-model="getDocumentAttributes"> <div v-if="value.key != 'Document'" class="panel panel-primary" v-for="(value, key, index) in getDocumentAttributes"> <div class="panel-body quote"> <span @click="removeSection(index,key)" class="pull-right glyphicon glyphicon-remove text-info"></span> <p>{{value.key}}</p> </div> </div> </draggable>my computed prop that listen to vuex getter:
getDocumentAttributes(){ return this.$store.getters.getDocumentAttributes; }Finaly my list and my getter function at vuex side:
state: { document: { "id": "0", "atributes": [] },[...]
getDocumentAttributes: (state) => { return state.document.atributes; },Vuex state management with API calls one behind engine when updated
I am working on a vue project with VUEX state management throughout. There is actions that populate the state attributes with axios promise calls and then we call the actions in the mounted section of components so the data is populate when the component is rendered. We have an issue where things do not update dynamically or data disappears when a page is refreshed. For instance there is one function where data is added to the databases connections list but to see it on the front end you need to click in and out of the component usually twice before it updates or it also works when you add another piece of data to the database list, has anyone come across this issue and if so know how to solve it. Also we are using computed properties for the issue I have described so I don't think its there.
Code:
Vuex call:
apiTestConnection: ({ commit }, apiParameters) => { var apiMethod = '('ApiCall')' var apiUrl = apiMethod + '¶meters=' + apiParameters myHTTP.get(apiUrl) .then(response => { // console.log('me first or second'); return response.data; }) .then(data => { var passFail = data.items.testDb; var errorExists =data.error.errorMessage; var errorCode = errorExists.split(" ")[0]; var modalMessage = 'abc'; var promiseFlag = 0; } commit('setTestConnectionMessage', modalMessage); commit('setTestConnectionPromise', 1); }); }components script where the data is called and used:
computed: { ...mapGetters([ 'getConnectionTableRow', 'getConnectionList', 'getConnectionListID', 'getAnalyticHeaderList', 'getTableData' ]), // According to Max theses actions should be in methods, If I put them there the api calls arent renered in the DOM ...mapActions([ 'apiGetConnections', 'apiGetAnalyticHeaders', 'setConnectionList' ]), connectionList: { get() { this.apiGetConnections; return this.$store.getters.getConnectionList; }, set(connectionList) { this.$store.dispatch('setConnectionList', connectionList) } }, }, mounted: function () { this.apiGetConnections, this.apiGetAnalyticHeaders }