Software
Vue - component props not watching object changes properly
I have two objects in my root - obj and newObj. I watch changes on my obj object with deep: true, and on changes I update newObj accordingly.
In my vue debugger, the newObj seems updated as expected, however the component doesn't perform the for loop count. Or if I try to {{ newObj }}, it logs only the first update.
I tried to re-create the issue on this Fiddle.
my html:
<div id="app"> <button @click="appendTo">Append</button> <my-comp v-bind:new-obj="newObj"></my-comp> </div>and vue:
new Vue({ el: '#app', data: { obj: {}, newObj: {} }, methods: { appendTo() { if (typeof this.obj[1] === 'undefined') { this.$set(this.obj, 1, {}) } var randLetter = String.fromCharCode(Math.floor(Math.random() * (122 - 97)) + 97); this.$set(this.obj[1], randLetter, [ [] ]) } }, watch: { obj: { handler(obj) { var oldKeys = Object.keys(obj) var newKeys = Object.keys(this.newObj); var removedIndex = newKeys.filter(x => oldKeys.indexOf(x) < 0 ); for (var i = 0, len = removedIndex.length; i < len; i++) { delete this.newObj[removedIndex[i]] } oldKeys.map((key) => { if (this.newObj.hasOwnProperty(key)) { var newInnerKeys = Object.keys(this.newObj[key]); var oldInnerKeys = Object.keys(obj[key]); var additions = oldInnerKeys.filter(x => newInnerKeys.indexOf(x) < 0); for (var i = 0, len = additions.length; i < len; i++) { // here this.$set(this.newObj[key], additions[i], [ [] ]); } var deletions = newInnerKeys.filter(x => oldInnerKeys.indexOf(x) < 0); for (var i = 0, len = deletions.length; i < len; i++) { delete this.newObj[key][deletions[i]] } } else { this.newObj[key] = {} for (var innerKey in obj[key]) { this.$set(this.newObj, key, { [innerKey]: [ [] ] }); } } console.log(obj); console.log(this.newObj) }); }, deep: true } } }) Vue.component('my-comp', { props: ['newObj'], template: ` <div> <div v-for="item in newObj"> test </div> </div> ` })How to access assets with webpacker gem
Could you explain me how to access assets from webpacker gem within vue.js components? For example - how to create div with background image. I've tried use both sprockets assets and putting image files to /app/javascripts/assets folder but images is only available in template section, but not in style section :( could you show me code example?
Vue sortable now working properly
I am working with vue-sortable and dragable and at the moment i can drag a item above and change its position, but my json doesn't get refreshed, so i have this list:
<draggable v-model="this.$store.getters.getDocument.getDocumentAttributes"> <div class="panel panel-primary" v-for="(value, key, index) in this.$store.getters.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>i get the list from vuex store, i can swap the elements but the json doesn't refresh, how can i do it?
Thank you!
Vue.js / vuedraggable : using :list and :move, draggables are no more draggable
Here is the template I have :
<draggable element="ul" :options="{group:'track'}" :list="jsonObject.tracks" :move="onMove" @end="onMoveTrackFinished"> [..................] </draggable>the onMove and onMoveTrackFinished are defined like so :
onMove ({relatedContext, draggedContext}) { console.log("onMove"); return true; }, onMoveTrackFinished() { console.log("finished move"); return true; }I can drag the items of the draggable, but they are not dropping where I want them to be : they just go back to were there were before...
VuexFire: how to combine computed: and computed()
I am using VuexFire in an app and as in https://github.com/posva/vuexfire in my components I have lines like
computed: Vuex.mapGetters(['todos']), created() { this.$store.dispatch('setTodosRef', todosRef) },This works fine except when I also have some computed methods in which case I don't know what to do. I have tried things like:
computed: Vuex.mapGetters(['todos']), computed() { amethod: { return 1 } }, created() { this.$store.dispatch('setTodosRef', todosRef) },and
computed() { amethod: { return 1 } }, created() { ...Vuex.mapGetters(['todos']) this.$store.dispatch('setTodosRef', todosRef) },but these, and the other things that I have tried, are clearly misguided because they don't work (i.e. the data from firebase is not available to the method.
What's the correct approach?
how to render vuejs components in dynamically added html from jquery
I have a vuejs component in a html that is returned from jquery ajax call but it doesn't render the component. so how to make vuejs render this component from jquery?
<test-component></test-component>that is what the ajax call returns and its displayed like this without rendering it.
VueJS - Render dynamically passed template in component
I am using VueJS 2 to build a drag-and-drop layout builder. One of the requirements of that project is to be able to have some components that will allow for custom content to live inside (they will be just a wrapper around that content). And to be really concrete, I am trying to pass in and render another drag-and-drop zone which is implemented in a draggable component.
Basically, I want to pass a VueJS template to the component via a prop and have that template rendered inside of the component. This is necessary because I do not want the UI to limit the needs of the developer and therefore need this to be really extensible.
In the following trivial example I would like the "ui-element" to render the content prop inside of it and use the other prop as a data input.
<ui-element :content="<draggable :name="contentData"></draggable>" contentData="col1" > </ui-element>Since just outputting the template will escape it, and v-html directive will treat it as regular HTML and not a template I am lost, not really sure how to get this done.
I spent about an hour or more googling but no luck. Which leaves me to three options:
1) I'm the first one to need this complex use case (unlikely)
2) Doing this is stupid on so many levels that no-one even bothered (if so, please let me know how to get this result in a smarter way)
3) There is a special uber-cool JS term for this which I simply do not know and that made my search attempts futile
Upload a file using vuejs and laravel without a form
I'm using vue.js 2.1 and Laravel 5.4 to upload a file from a component without a form.
Problem: On the server side, this statement return $request->file('my_file'); returns null. Why?
This is how the vue component looks like:
<template> <input id="my_file" type="file" @change="fileChanged($event)"> <button v-if="my_file" @click="update">Upload</button> </template> <script> export default { data () { return { my_file: null, } }, methods: { fileChanged(e) { var files = e.target.files || e.dataTransfer.files; if (!files.length) return; this.createImage(files[0]); }, createImage(file) { var image = new Image(); var reader = new FileReader(); var vm = this; reader.onload = (e) => { vm.my_file = e.target.result; }; reader.readAsDataURL(file); }, update() { axios.put('/api/update/', { my_file: this.my_file, }) .then(response => { console.log(response.data); }) .catch(error => { console.log(error); }); } } } </script>On the server side, I have the following method:
public function update(Request $request) { return $request->file('my_file'); // $request->file('my_file')->store(); }What am I missing? So I can use the function $request->file('my_file')->store(); provided by Laravel to upload the file.
Fetching data in vue.js without changing the store state?
I have a vue.js SPA with a vuex store. Inside my application I have a view for my user. This user comes from the database and is loaded via the vuex store. All fine.
Now my problem is, that I need to load another user into the same view - this second user is related to my first user. When I am loading this second user via the vuex store, the first user gets overwritten.
Is there a good practice to load another user without overwriting the vuex-store user?
My current solution - the first snippet is the vuex-stored first user:
[actions.LOAD_USER](context, id) { return UserRepository.load(id) .then((user) => { context.commit(mutations.SET_USER, user.data); }) .catch((error) => { throw new Error(error); }); }And the second snippet is how i load my second user:
[actions.GET_USER](context, id) { return UserRepository.load(id); }This is working, but I am asking you if you have a better solution?
Passing JSON array to list prop : type check failed for prop "list". Expected Array, got String
I have a json object, called jsonObject, which contains an array called tracks. I am using this.jsonObject.tracks as an array in my methods and my template (using v-for) and Vue does not complain about that. But I have an issue with this part of my vue template :
<draggable element="ul" :options="{group:'track'}" list="jsonObject.tracks" :move="onMove" @end="onMoveTrackFinished"> [......] </draggable>I am getting the error, which is due to the list prop :
Invalid prop: type check failed for prop "list". Expected Array, got String.What's the problem here?
how to add filters and search in tables in vuejs?
I am learning vue js and building a SPA i want to know how do I add filters and search using an input tag. I also want to add a feature that when i click on a particular name on the table it should open the profile of that person also a select all functionality
<template> <div class="animated fadeIn"> <input type="text" placeholder="Enter Name" v-model="searchText"> <table class="table table-striped"> <thead> <tr> <th>Name</th> <th>College Name</th> <th>College City</th> <th>Level Name</th> <th>Submitted</th> <th>Pending</th> <th>Completed</th> <th>Approved</th> <th>Rejected</th> </tr> </thead> <tbody> <tr v-for="profile in profilesdata"> <td>{{profile.first_name}}</td> <td>{{profile.college_name}}</td> <td>{{profile.college_city}}</td> <td>{{profile.level_name}}</td> <td>{{profile.submitted}}</td> <td>{{profile.pending}}</td> <td>{{profile.complete}}</td> <td>{{profile.approve}}</td> <td>{{profile.rejected}}</td> </tr> </tbody> </table> </div> </template> <script> export default{ name: 'profiles', data () { return{ profilesdata: [] } }, created:function(){ this.loadlike() }, methods:{ loadlike:function(){ this.$http.get('/api/profiles').then(function (res) { this.profilesdata = res.body console.log(53+this.profiles) })}}} </script>How to load external script with same context as module doing the import?
I am trying to write an architecture that will allow people to add their own javascript without having to perform any build steps.
The context in this case is a dashboard UI, where each widget in the dashboard can be a plugin written by someone else.
The dashboard application is a VueJS-based app that is built by webpack and uses python on the backend. The idea is, using a tool like $script or some other script loader, the script that is loaded will have access to all the modules available in the UI. I expect to have Vue, axios, and D3 at the minimum. D3 especially is quite big so it'd be better not to force plugin authors to include their own copy of D3. The project is still in its infancy so Vue and webpack are not tools written in stone for me.
The only solution I can think up is defining a globally available function that calls a plugin function with dependencies as an argument, eg:
In the web app itself:
import * as d3 from 'd3'; import Vue from 'vue'; import axios from 'axios'; function plugin_loader(plugin_cb) { plugin_cb(d3, Vue, axios); }In a plugin:
plugin_loader(function(d3, Vue, axios) { // now the plugin can use those modules });But what I'm hoping is a possible solution, is simply for someone to write a plugin in a more "natural" way, using their own imports/requires() and using their bundler of choice to externalise away dependencies that the webapp already ships with.
So essentially, I want to include a third party js file at runtime, and that JS file can have access to all dependencies that the webapp itself has.
thanks in advance for any advice.
Can you implement Vue Unit tests without a component using purely the Vue Instance?
I briefly looked at the documentation on Vue Unit Testing
It said:
Anything compatible with a module-based build system will work
The documentation describes ways to test components
In my case I am not using a component. I am adding the vue.js to the page and I create a new Vue Instance.
new Vue({ el: '#app', data: { .... } });How to bind console.log to "l" in vue.js?
main.js has this code
window.l = function () { } try { window.l = console.log.bind(console) } catch (e) { }which works in non-Vue apps. However, when calling
l("test")from a Vue action/method, it complains it isn't defined.
How can that work?
Reasoning: need to output some debugging data, with as less typing as possible.
Vue JS Keep all imports in different file
Iam learning vuejs, i have hundreds of json file i want to load in to my Vue project , in my script, Simply i can do this loading all json files directly in main file as below
//Index.vue <script> import data1 from 'assets/json/data1.json'; import data2 from 'assets/json/data2.json'; ...above works fine, but now im planning to keep all imports into different file as below
//assets/imports.js import data1 from 'assets/json/data1.json'; import data2 from 'assets/json/data2.json';and refer imports.js as
//Index.vue <script> import alldata from 'assets/imports'is it possible to do like this, in not good in webpack too
How to call a function after element-ui table rows are rendered in Vue?
I have created a Vue component which contains a table from element-ui library. In a created() lifecycle hook, I am requesting table data and assigning the response as a table data.
What I need is to call a function after rows are rendered in a DOM. I have tried 3 approaches ...
1) nextTick() ... works bad
created() { this.isLoading = true; // Get all rows DataProvider.GetRows().then((returnedRowsData) => { this.tableData = returnedRowsData; this.isLoading = false; Vue.nextTick(() => { this.needToCallThisAfterTableDomIsCreated(); }); }); }2) mounted() lifecycle hook - works bad
mounted() { this.needToCallThisAfterTableDomIsCreated(); }3) Interval delay - this works, but is is not called immediately after table dom is rendered
created() { this.isLoading = true; // Get all rows DataProvider.GetRows().then((returnedRowsData) => { this.tableData = returnedRowsData; this.isLoading = false; setTimeout(() => { this.needToCallThisAfterTableDomIsCreated(); }, 2000); }); }How to access methods between components?
I have an application with two sibling components:
I would like, upon a specific action in Component1 to trigger a method in Component2. Is there a way to do this directly?
Currently, I use an over-engineered solution:
- upon the specific change in Component1, it $emit a signal to the parent
- ... who, through a handler, modifies a flag in its data
- ... which is passed as prop to Component2
- ... which watch this prop and triggers the appropriate method upon chnage.
This composition of flags, handlers and watchers is too complex so i am hoping for a more direct solution.
vue.js error : vue.common.js?e881:2888 'Uncaught TypeError: undefined is not iterable!'
In my vue project,I used vue-devtools. But when I clicked the 'vue' button,these is an error in console.I haven't any clue yet ,so I need some clue or solution, Please help me,Thank you very much if you can give me some help.
How to preload variables in a component style
So I successfully configure webpack for loading scss style that is in my components.
I use a <style lang="scss"></style> and it goes well.
But I would need to call some of my scss variables from there, so I guess I would need a kind of preload?
Is there a way to do it without having to @import in each component?
Stop referencing object with vuejs
I know that the default behaviour of a object when we create new atributes for the same instance is that it reference the old, changing the properties.
I have something like this on my vue data:
export default { data() { return { paragraph: { text: "", fontSize: 14, key: "Paragraph", align: "left" } } }, methods: { addParagraph() { this.$set(this.paragraph, 'key', this.paragraph.key); this.$set(this.paragraph, 'text', this.paragraph.text); this.$set(this.paragraph, 'fontSize', this.paragraph.fontSize); this.$set(this.paragraph, 'align', this.paragraph.align); this.$store.commit("appendToDocument", this.paragraph) }, alignment(option) { this.paragraph.align = option; } }everytime i click a button the data inside the paragraph changes and i want to pas the data to vuex store to add it to a json, so i can have a tree of paragraphs, the problem is, that everttime i create a new paragrapg it changes the values of my other paragraphs created before, is there a way to change it?