I know this is a very specific question but was wondering if someone could help me. So right now I am currently using a module from bootstrap located on this link right here:
https://bootstrap-vue.js.org/docs/components/pagination/
I am currently having the trouble where I am trying to dispatch an action that is reliant on the currentPage variable.
<bPagination align="right" :total-rows="100" v-model="currentPage" :per-page="10" #click.native =" updatePage(currentPage); loadParticipants()"></bPagination>
currentPage is set to 1 as of right now like so:
data() {
return {
currentPage: 1,
tag: '',
tags: [],
....
Here is a method so that I can update the page within my VueX store. So first I dispatch a method within my Vue file:
updatePage: function(page){ this.$store.dispatch('updatePage', page); console.log("Hit me") },
And then within my VueX store I use this function to commit:
updatePage({ commit }, updatePage) { commit('updatePage', updatePage); }
I then use a mutation to finally update the state data:
updatePage: (state, updatePage) => { state.page = updatePage; }
So what I want it to do is that everytime I click on a page number I get to update the page number within the vuex store immediately when you press on any of the page numbers. However, it decrements and increments a step behind everytime I click on a page number.
examples:
If I click page number 2 twice it will update the store data to page number 2
And if you click page 2 and then page 1 it will show that the store's page number is at page 2.
So it is pretty much a step behind. If anyone can push me to the right direction that would help so much. Thanks!
Never mind I solved it I pretty much used #input rather than using a click event.
<bPagination align="right" :total-rows="100" v-model="currentPage" :per-page="10" #input =" updatePage(currentPage); loadParticipants()"></bPagination>
Related
I have a vue component to delete items. function working fine.but that deleted items is remain the page until I press the reload in web browser. Following is the delete method in vue component.
deletedItem: function () {
let data = {
"_method" : 'delete',
}
axios.post('/delete-item' +this.id, data);
this.isDelete =false;
location.reload();
}
-Delete button
<button v-on:click="deletedItem" class="bg-red-500 text-gray-200 rounded hover:bg-red-400 px-6 py-2 focus:outline-none mx-1"> Delete</button>
Is there are anyway to remove deleted item once I click delete button.
Once I reload the page after the response came then it reload the page & remove deleted item. solution is as follows.
axios.post('/delete-item' +this.id, data).then( response => {
this.isDelete =false
location.reload()
});
As i understand it you have all the items stored remotely on a server somewhere else, and the way you fetch the items is by some other request. And what you are doing here is deleting the item on the server without doing anything else.
I don't see how the web-application would know that the item got deleted. Normally I solve this situation with deleting the object locally after i receive a 200 from the api.
If you want something even more simple you could just refresh the list of items after you receive a response of any kind. It all depends on what kind of features you want to have.
Please confirm the points below:
Did your api responded with a successful response?
Did you declare isDelete property in data function?
You should change the isDelete property after the ajax finished using promise or async/await because ajax is asynchoronous at the most time.And you should declare the isDelete property in data function like this:
data () {
return { isDelete: true }
}
because it makes Vue be able to collect the dependency relation and make it responsive.
I'm trying to build a mobile small application using v-expansion-panels to display a list.
The idea is that when the user adds a new item in such list it will open the new panel and scroll down to such new panel.
I found a goTo() method in the $vuetify variable, unfortunatly the v-expansion-panels transition (the "opening") take some time and the goTo() won't completely scroll down because of the scrollbar height changes.
So from my understanding I need to detect the end of the transition (enter/afterEnter hook).
Per the vuetifyjs documentation, I could hope to have a "transition" property on my component. (Which isn't the case anyway). But such property is only a string so I can't hook into it.
My other idea is to, somehow, find the transition component and hook into it. Unfortunatly I have trouble understanding el/vnode and the way vuejs is building is tree like the vue-devtool show and I can't get the transition component. When debugging (in the enter hook callback of the transition) it is like the component/el/vnode has a parent but isn't the child of anybody.
Is there a way to do what I'm looking for?
Here is a jsfiddler of what I currently do: https://jsfiddle.net/kdgn80sb/
Basically it is the method I'm defining in the Vue:
methods: {
newAlarm: function() {
const newAlarmPanelIndex = this.alarms.length - 1;
this.alarms.push({title: "New line"});
this.activePanelIndex = newAlarmPanelIndex;
// TODO:
this.$vuetify.goTo(this.$refs.alarmPanels[newAlarmPanelIndex]);
}
}
Firstly you should open manually panel and then use goTo with a timeout.
It works for me, just give some time to a panel to open.
<v-expansion-panels v-model="alarmPanels">
<v-expansion-panel>
<div id="example" />
</v-expansion-panel>
</v-expansion-panels>
this.alarmPanels.push(0); // Use index of expansion-panel
setTimeout(() => {
this.$vuetify.goTo(`#${resultId}`);
}, 500);
If I’m on a page with the URL 'http://localhost:8080/item' and I’m clicking on the same link on this page, then the page does not reload.
I need to make that if I click on the same link, the page will reload.
My link:
<nuxt-link :to="/item">
Any insight will be welcome. Thanks!
Use key, something like:
<router-view :key="$route.params.yourCustomParam"/>
Also you can use something like:
<router-link :to="{ params: { yourCustomParam: Data.now } }" replace>link</router-link>
Remember to is passed router.push() and it accept an object also. Doing that, it is more declarative and controllable. I'm using this to decide if the page of component should be rerendered since they will based on id params obtained from URL entry, and my child component can still using nesting .
I recently tried to solve a similar issue and to overcome this I used Vuex with :key (ref).
Firstly, in your store you need a state property such as:
export const state = () => ({
componentUpdates: {
item: 0,
//can add more as needed
}
})
In general, you could use only one property across the app if you prefer it that way. Just remember that later on, the key value needs to be unique - that is in the case if you used this property for two or more components within one page, for example. In this case, you could do something like this :key="$store.getters.getComponentUpdates.item+'uniqueString'"
then a getter:
export const getters = {
getComponentUpdates(state) {
return state.updateComponent;
}
}
finally a mutatation:
export const mutations = {
updateComponent(state, payload) {
return state.componentUpdates[payload.update]++
}
}
Now we can utilise the reactive :key wherever needed.
But first in your nuxt-link lets add an event to trigger the mutation, note the usage of #click.native to trigger the click event:
<nuxt-link #click.native="$store.commit('updateComponent', { update: 'item'})" :to="/item">
Now in the item page, for example. Let's imagine there is a component that needs to be updated. In this case we would add :key to it:
<my-item :key="$store.getters.getComponentUpdates.item" />
That is it. As you can see this solution utilises the benefits of nuxt-link but also allows us to selectively update only parts of our page that need updates (we could update the entire page this way as well if needed).
In case if you needed to trigger the logic from mounted or initial load in general, then you could use computed property and :key to your div container, right inside the <template> of your page.
Add :key to the div:
<template>
<div :key="$store.getters.getComponentUpdates.item"></div>
</template>
Create computed property:
computed: {
updateItemPage() {
//run your initial instructions here as if you were doing it in mounted then return the getter
this.initialLoadMethod()
return this.$store.getters.getComponentUpdates.item
}
}
The final touch, which is not crucial but can be implemented in order to reset the state property:
export const mutations = {
updateComponent(state, payload) {
return state.componentUpdates[payload.update] >= 10
? state.componentUpdates[payload.update] = 0
: state.componentUpdates[payload.update]++
}
}
I want to lazy load content when the user scrolls down to the bottom of the Bootstrap modal, sort of like an infinite scroll, using Vue.js. I'm fetching all my data from a action method on API call. The data coming from this API is stored in array of objects on mounted and is used in the application.
So far so good. But now I want to implement that in the initial state, only the first 10 items are fetched from the API. When the user scrolls down to the bottom of the page I want to fetch the next 10 results and so on. I've looked at the documentation of the API that I'm using, and it has support for offsetting the items I'm fetching. Though I'm not sure where to start from there. Does anyone know any good resources on this subject? Thanks a ton!
after a while i solved the problem
here is my sample project for you reading this question
Here is my solution if you are trying to avoid using an npm package. You can use it in any scrollable div in vue. And in the if statement below is where you would handle your api call to fetch more results.
<template>
<div class="scroll" #scroll="scroll">
</div>
</template>
<script>
export default{
name: "Scroll",
data(){
return{
bottom: false
}
},
methods:{
scroll(e){
const {target} = e;
if (Math.ceil(target.scrollTop) >=
target.scrollHeight - target.offsetHeight) {
//this code will run when the user scrolls to the bottom of this div so
//you could do an api call here to implement lazy loading
this.bottom = true;
}
}
}
</script>
I am working on a vuejs SPA.
I have a view that shows a list of items and another view that shows details for a specific Item.
when I click the item I switch views using:
this.$router.push('/item/' + event.ItemId );
The data is managed using vuex modules.
I would like to allow some temporary display while the item details are being retried (i.e. not to block the rendering of the item details view which should know on its own to indicate that it is still awaiting data).
And I would also have to consider that it should work if the URL is changed (I think I read that there is an issue with the view not being reloaded/recreated when only the item id would change in the URL.
Where would be the appropriate place (code/lifecycle) to trigger the (async) retrieval of the data required for rendering the item details view?
I would like to allow some temporary display while the item details are being retried (i.e. not to block the rendering of the item details view which should know on its own to indicate that it is still awaiting data).
One way to achieve this, is to define a state variable, named e.g. isLoading, in the data context of the Vue component. This variable would then be true while the data is retrieved asynchronously. In the template, you can use v-if to display a spinner while loading, and displaying the content after that.
If you are retrieving the data multiple times (refreshing the view), I would move the retrieving code into a method, e.g. called loadData. In the mounted section of the Vue component you then can just initially call this method once.
Here is some example code:
<template>
<div>
<button #click="loadData" :disabled="isLoading">Refresh</button>
<div class="item" v-if="!isLoading">
{{ item }}
</div>
<div class="spinner" v-else>
Loading...
</div>
</div>
</template>
<script>
import HttpService from '#/services/HttpService';
export default {
name: 'item-details',
data () {
return {
isLoading: false,
item: {}
};
},
methods: {
loadData () {
this.isLoading = true;
HttpService.loadData().then(response => {
this.item = response.data;
this.isLoading = false;
}, () => {
this.item = {};
this.isLoading = false;
});
}
},
mounted () {
this.loadData();
}
};
</script>
And I would also have to consider that it should work if the URL is changed (I think I read that there is an issue with the view not being reloaded/recreated when only the item id would change in the URL.
This issue you mentioned occurs if you are not using the HTML5 history mode, but an anchor (#) in the URL instead. If you are just changing the part after the anchor in the URL, the page is not actually refreshed by the browser. The Vue component won't be reloaded in this case and the state is still old. There are basically two ways around this:
You are switching from anchors in the URL to a real URL with the HTML5 history mode, supported by the Vue Router. This requires some back-end configuration, though. The browser then does not have this faulty behavior, because there is no anchor. It will reload the page on every manual URL change.
You can watch the $route object to get notified on every route change. Depending on if the user is changing the part after the anchor, or before, the behavior is different (it also depends where the cursor is, when you hit enter). If the part after the anchor is changed (your actual Vue route), only the component is notified. Otherwise, a full page refresh is made. Here's some example code:
// ...inside a Vue component
watch: {
'$route' (to, from) {
this.loadData();
}
}