Unexpected behaviour removing a child component (row) - vue.js

Description:
I have a table with some products, each row is a custom vue <row> component.
Each element has a closing (removing) button that triggers the custom "remove" event. The main app listens to this event and removes the children (by index)
The row a part from some static text it contains an input with a number.
The problem:
The parent (Vue app) removes the row, but the value of the input is then moved (and replaces its previous value) to the input in the next row.
Expected behaviour:
I want to simply remove the item I do not care about the value of the text input once it's removed. It should not move its value to the next sibling.
I attach an example.
let row = Vue.component('row', {
name: 'row',
props: ['number', 'name', 'sq'],
data: () => ({
quantity: 0
}),
template: '<tr>' +
'<td>{{number}}</td>' +
'<td>{{name}}</td>' +
'<td><button v-on:click="quantity--">-</button><input type="text" :value="quantity"><button v-on:click="quantity++">+</button></td>' +
'<td><button v-on:click="remove">×</button></td>' +
'</tr>',
methods: {
remove: function() {
this.$emit('remove', this.quantity)
}
},
beforeMount() {
this.quantity = this.sq
}
})
new Vue({
el: "#app",
data: {
out: [],
rows: [{
name: "Icecream",
sq: 0
},
{
name: "Sugar cube",
sq: 50
},
{
name: "Peanut butter",
sq: 0
},
{
name: "Heavy cream",
sq: 0
},
{
name: "Cramberry juice",
sq: 0
}
]
},
methods: {
removeRow: function(index, quantity) {
this.out.push(`Removing row ${index} (${this.rows[index].name} | ${quantity} units)`)
this.rows.splice(index, 1)
}
},
computed: {
log: function() {
return this.out.join("\r\n")
}
}
})
body {
background: #20262E;
padding: 20px;
font-family: Helvetica;
}
h2 {
font-weight: bold;
margin-bottom: 10px;
}
#app {
background: #fff;
border-radius: 4px;
padding: 20px;
transition: all 0.2s;
}
td {
padding: 4px 5px;
}
input {
width: 40px;
text-align: center;
}
h4 {
margin-top: 20px;
margin-bottom: 5px;
}
#log {
padding: 10px;
background: #20262E;
color: #fff;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>
<div id="app">
<h2>Cart:</h2>
<table>
<row v-for="(row, index) in rows" :number="index" :name="row.name" :sq="row.sq" v-on:remove="removeRow(index, $event)"></row>
</table>
<h4>Log</h4>
<pre id="log" v-html="log"></pre>
</div>

As #Bert mentioned in the comments.
The problem was that I was missing a key.
https://v2.vuejs.org/v2/api/#key
Adding it solved the problem
Thanks

Related

how to set a trey of letters`style differently in a v-for loop?

It is similar to the question of whose URL I`ll put below but with one difference, I want not one letter or word style conditionally presented but a trey of letters, I wish all the letters to be in
a different color, is there any solution to it?
the tricky thing is the v-for loop based on an array whose length is not constant.
Change the style of a substring in a v-for loop
example:
I want this input tag letters full of different random colored letters
here is the full code:
<template>
<div
class="nice-input"
:class="{'nice-input--shaked': animated, 'nice-input--caret': !caret}"
>
<input
:id="id !== undefined ? id : 'input-'+name"
v-model="value"
type="text"
:name="name"
autocomplete="off"
>
<label :for="id !== undefined ? id : 'input-'+name">
<span v-for="word in arr" :key="word.sa" class="nice-input__animate"
:style="randomColor">{{ word }}</span>
</label>
</div>
</template>
<script>
export default {
name: 'weirdInput',
props: ['name', 'id'],
data () {
return {
animated: false,
caret: true,
value: '',
randomColor: '#000000',
}
},
computed: {
arr: function () {
return this.value.split('')
},
},
watch: {
value: {
handler: function (after, before) {
const self = this
this.caret = false
if (after.length > before.length) {
if (this.value.slice(-1) === ' ') return false
setTimeout(function () {
self.animated = true
setTimeout(function () {
self.animated = false
self.caret = true
}, 300)
}, 750)
}
this.randomColor = 'color: #' + Math.floor(Math.random() * 16777215).toString(16)
},
},
},
}
</script>
<style scoped>
.nice-input {
position: relative;
}
.nice-input input {
border:none;
border-radius:4px;
padding:7px 10px;
font-family: 'Lato', sans-serif;
font-size:14px;
box-shadow: rgba(0,0,0,.05) 0 5px 20px;
letter-spacing:0;
width:1000px;
color: transparent;
font-weight:900;
caret-color: #555;
}
.nice-input input:focus {
outline:none;
box-shadow: rgba(0,0,0,.1) 0 5px 20px;
}
.nice-input label {
position: absolute;
top: 6px;
left: 10px;
letter-spacing:0;
font-size:0;
}
.nice-input span {
font-family: 'Lato', sans-serif;
font-size:14px;
font-weight:900;
}
.nice-input__animate {
animation: print .75s 1 ease-in-out;
}
.nice-input--shaked {
animation: shake .2s 1 ease-in-out;
}
.nice-input--caret {
caret-color: transparent;
}
#keyframes print {
from{
position:absolute;
transform: scale(100);
}
99% {
position:absolute;
}
to {
position:relative;
}
}
#keyframes shake {
from,
to {
}
50% {
transform:scale(0.97);
}
}
</style>

Vue 3 cli-service app: "Slot "default" invoked outside of the render function" warning when component with slots is imported from other component

MCVE
I have a Tabpane component that takes slots as input. When imported from the template it works as expected.
<Tabpane>
<div caption="I am div 1">Div 1</div>
<div caption="I am div 2">Div 2</div>
</Tabpane>
However when imported from an other component ( Composite in the example ), then it triggers the following warning:
Slot "default" invoked outside of the render function:
this will not track dependencies used in the slot. Invoke the slot function inside the render function instead.
// src/components/Composite.js
import { defineComponent, h } from "vue";
import Tabpane from "./Tabpane.vue";
export default defineComponent({
name: "Composite",
setup() {
const slots = [
h("div", { caption: "I am div 1" }, ["Div 1"]),
h("div", { caption: "I am div 2" }, ["Div 2"])
];
return () => h(Tabpane, {}, () => slots);
}
});
Solved.
The problem was that I called slots.default() from within setup, but not within the returned render function.
Also this component reflected a very beginner approach to reactivity. By now I know better. The old problematic solution is still there in src/components/Tabpane.vue.
The right solution that triggers no warning is:
// src/components/Tabpane2.vue
<script>
import { defineComponent, h, reactive } from "vue";
export default defineComponent({
name: "Tabpane2",
props: {
width: {
type: Number,
default: 400,
},
height: {
type: Number,
default: 200,
},
},
setup(props, { slots }) {
const react = reactive({
selectedTab: 0,
});
return () =>
h("div", { class: ["vertcont"] }, [
h(
"div",
{
class: ["tabs"],
},
slots.default().map((tab, i) =>
h(
"div",
{
class: {
tab: true,
selected: i === react.selectedTab,
},
onClick: () => {
react.selectedTab = i;
},
},
[tab.props.caption]
)
)
),
h(
"div",
{
class: ["slotscont"],
style: {
width: `${props.width}px`,
height: `${props.height}px`,
},
},
slots.default().map((slot, i) =>
h(
"div",
{
class: {
slot: true,
active: react.selectedTab === i,
},
},
[slot]
)
)
),
]);
},
});
</script>
<style>
.tab.selected {
background-color: #efe;
border: solid 2px #afa !important;
border-bottom: transparent !important;
}
.tab {
background-color: #eee;
}
.tabs .tab {
padding: 5px;
margin: 2px;
border: solid 2px #aaa;
border-radius: 8px;
border-bottom: transparent;
cursor: pointer;
user-select: none;
transition: all 0.5s;
color: #007;
}
.tabs {
display: flex;
align-items: center;
margin-left: 5px;
}
.vertcont {
display: flex;
flex-direction: column;
margin: 3px;
}
.slotscont {
position: relative;
overflow: scroll;
padding: 5px;
border: solid 1px #777;
}
.slot {
visibility: hidden;
position: absolute;
}
.slot.active {
visibility: visible;
}
</style>
Slots need to be invoked within the render function and or the <template> box to ensure they keep their reactivity.
A full explanation can be found in this post: https://zelig880.com/how-to-fix-slot-invoked-outside-of-the-render-function-in-vue-3

Self built Timepicker Vue JS Component functionality

I was wondering if anyone knows how to detect when the user hovers on the time selected, the time slot selected will ease scroll upwards to be vertically center aligned.
this is my first time building a complex timepicker. i would also need to have options such as time ranges (min - max)and have it as dynamic as possible. Just looking for ideas at the moment, not expecting a complex answer!
Please look at my fiddle to show you what i mean
new Vue({
el: "#app",
data: {
current: null,
testList:
[
{
id: 1,
time: '11.00'
},
{
id: 2,
time: '11.15'
},
{
id: 3,
time: '11.30'
},
{
id: 4,
time: '11.45'
},
{
id: 5,
time: '12.00'
},
{
id: 6,
time: '12.15'
},
{
id: 7,
time: '12.30'
},
{
id: 8,
time: '13.00'
},
{
id: 9,
time: '13.15'
},
{
id: 10,
time: '13.30'
},
{
id: 11,
time: '13.45'
},
]
},
methods: {
setCurrent(key)
{
this.current = key;
}
},
beforeMount() {
this.current = 3;
},
})
body {
background: #20262E;
padding: 20px;
font-family: Helvetica;
}
#app {
background: #fff;
border-radius: 4px;
padding: 20px;
transition: all 0.2s;
}
.selectTime2 {
height: 136px;
overflow-y: auto;
list-style: none;
padding: 0;
max-width: 172px;
width: 100%;
margin: 50px auto;
}
.selectTime2::-webkit-scrollbar {
width: 0;
}
.timeSlot {
text-align: center;
color: #ECF1F2;
font-size: 14px;
font-weight: bold;
margin-bottom: 10px;
}
.selected {
color: #679198;
font-size: 24px;
font-weight: bolder;
position: relative;
}
.light {
color: #ACC6CB;
font-size: 18px;
}
.lighter {
color: #ECF1F2;
font-size: 14px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<h1>
On hover select time component
</h1>
<ul class="selectTime2">
<li v-for="test in testList"
#mouseover="setCurrent(test.id)"
class="timeSlot"
:class="{'selected': current === test.id, 'light': current === test.id+1 || current === test.id-1, 'lighter': current === test.id+2 || current === test.id-2}"
>{{ test.time }}
</li>
</ul>
</div>

Nuxt / Vuex / Vue Reactivity Issue Increment

Hi everyone I am I having some difficulty when working with Nuxt and Vuex.
I am trying to run through the example Vuex / Nuxt Classic Mode.
https://nuxtjs.org/guide/vuex-store/
After clicking my increment button I dont see the number go up. My page just stays at 0, I can see within the console that the state knows the number is no longer 0 but not on the screen, as if it doesnt know to be reactive.
My assumption is that I have miss configured something somewhere and my 0 is not the actual state, but I created some copy of it somehow.
Here is my button within my template.
<button #click="inc">{{ counter }}</button>
Here is my inc function within my methods.
inc () {
this.$store.commit('increment')
},
Here is my computed
computed: {
counter () {
return this.$store.getters.counter
}
}
Here is my Vuex/index.js file contained within the store folder.
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const createStore = () => {
return new Vuex.Store({
state: () => ({
counter: 0
}),
getters: {
counter: state => state.counter
},
mutations: {
increment (state) {
state.counter++
}
}
})
}
export default createStore
Update: Included more code snippets, and replied to existing comments.
#Boussadjra Brahim #xaviert, thank you both for weighing in, I appreciate the assistance.
#Boussadjra Brahim - Yes, I had tried using an action that called the mutation, that didnt seem to get me there either. I also tried adjusting the state via the action alone, and wasnt able to make any changes, however that seems correct, as I am under the impression that actions call mutations to make state changes and do not themselves do so, please correct me if you know more. I am 100% open to the idea that I did not attempt it correctly. Below is that action that didnt do anything and the one that called the mutation
actions: {
increment (state) {
state.counter++
}
},
And here is the version with the action calling the mutation.
actions: {
incrementCounterUp () {
this.commit('increment')
}
},
#xaviert - I have tried starting the server over, and have also tried to see if an nuxt build followed by a firebase serve, to see if maybe that helped. It did not. My normal server start is 'npm run dev'. In hopes that you/anyone else may be able to find my mistake below is my full _id.vue component and also my nuxt.config.js file as maybe that's it. Its still pretty raw and could use a lot of refactoring so hope you can sort through it well enough.
_.id.vue
<template>
<div class="product">
<div class="product-image">
<div class="product-image-img">
<img v-bind:src="product.image_file" width="450px;"/>
</div>
</div>
<div class="product-details-wrapper">
<div class="product-details">
<h1>
<div v-if="this.$route.query.editPage">
<textarea #input="updateTextArea" ref="textarea2" v-model="product.item_name" type="text" />
</div>
<div v-else>{{product.item_name}}</div>
</h1>
<div class="product-description">
<div class="product-description-text" v-if="this.$route.query.editPage">
<textarea #input="updateTextArea" ref="textarea" v-model="product.description" type="text" />
</div>
<div class="product-description-text" v-else v-html="product.description"></div>
</div>
<p class="product-brand"><strong>Brand - </strong> {{product.brand_name}}</p>
<hr />
<div class="product-price">
<div v-if="this.$route.query.editPage">
<strong>Original Price - </strong>
<input v-model="product.msrp" type="text" />
</div>
<div v-else class="product-msrp">
<strong>Original Price - </strong>
<span class="strike">${{product.msrp}}</span>
</div>
<div v-if="this.$route.query.editPage">
<strong>Sale Price - </strong>
<input v-model="product.price" type="text" />
</div>
<div v-else class="product-sale-price">
<strong>Sale Price - </strong>
<span class="">${{product.price}}</span>
</div>
<div class="product-price">
Quantity x
<input #input="updateQuantity" v-model="quantity" min="1" class="" type="number" value="1" />
</div>
<button #click="inc">{{ counter }}</button>
</div>
</div>
</div>
<div v-if="this.$route.query.editPage" class="update-product"> <button #click="updateProduct(product)">Update</button></div>
<div class="footer">
<router-link to="/privacy-policy" target="_blank">Privacy</router-link> |
<router-link to="/terms" target="_blank">Terms</router-link>
</div>
</div>
</template>
<script>
// # is an alias to /src
import firebase from '#/services/fireinit'
import foo from '#/components/foo'
const db = firebase.firestore()
export default {
name: 'ProductPage',
head () {
return {
title: this.product.item_name
}
},
components: {
foo
},
data: function () {
return {
product: {},
image: '',
name: 'Checkout',
description: '',
currency: 'USD',
amount: '',
msrp: '',
quantity: 1
}
},
methods: {
inc () {
this.$store.dispatch('incrementCounterUp', true)
},
updateProduct: function (product) {
db.collection('products').doc(product.item_id).set(product)
.then(function () {
console.log('Document successfully written!')
})
.catch(function (error) {
console.error('Error writing document: ', error)
})
},
updateQuantity () {
this.product.msrp = (this.quantity * this.product.orgMsrp)
this.product.msrp = Math.round(100 * this.product.msrp) / 100
this.product.price = this.quantity * this.product.orgPrice
this.product.price = Math.round(100 * this.product.price) / 100
},
updateTextArea () {
this.$refs.textarea.style.minHeight = this.$refs.textarea.scrollHeight + 'px'
this.$refs.textarea2.style.minHeight = this.$refs.textarea2.scrollHeight + 'px'
}
},
async asyncData({app, params, error}) {
const ref = db.collection("products").doc(params.id)
let snap
let thisProduct = {}
try {
snap = await ref.get()
thisProduct = snap.data()
thisProduct.orgMsrp = thisProduct.msrp
thisProduct.orgPrice = thisProduct.price
} catch (e) {
// TODO: error handling
console.error(e)
}
return {
product: thisProduct
}
},
mounted () {
if(this.$refs.textarea) {
this.$refs.textarea.style.minHeight = this.$refs.textarea.scrollHeight + 'px'
this.$refs.textarea2.style.minHeight = this.$refs.textarea2.scrollHeight + 'px'
}
},
computed: {
counter () {
return this.$store.getters.counter
}
}
}
</script>
<style lang="less">
body {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
color: #2c3e50;
margin: 0
}
p{
margin-top: 1em;
margin-bottom: 1em;
}
html, body, #__nuxt, #__layout, .default, .product{
height: 100%;
}
.product {
justify-content: center;
display: flex;
max-width: 1150px;
margin: 0 auto;
flex-wrap: wrap;
align-items: center;
padding: 0 24px;
&-price{
input {
border: 1px solid;
padding: 0 .3em;
text-align: center;
width: 50px;
}
}
}
.product-details{
width: 100%;
textarea {
width: 100%;
font-size: inherit;
color: inherit;
font-family: inherit;
font-weight: inherit;
height: initial;
resize: none;
background-color: transparent;
border: none;
}
h1{
font-size: 1.9rem;
margin: 15px 0 20px;
}
hr{
width: 50%;
margin: .5rem 0px;
}
p{
}
}
.product-description-text{
margin: 10px 0;
}
.product-image, .product-details-wrapper{
align-items: center;
display: flex;
justify-content: center;
}
.product-details-wrapper{
flex: 0 1 535px;
}
.product-image{
flex: 0 1 535px;
img{
width: 100%;
}
}
.product-price{
.strike{
text-decoration: line-through;
}
button{
display: flex;
width: 150px;
height: 50px;
border-radius: 5px;
justify-content: center;
font-size: 24px;
margin-top: 20px;
&:hover{
cursor: pointer;
background-color: #f1f1f1;
box-shadow: 3px 3px 11px -1px rgba(0, 0, 0, 0.48);
}
}
}
.product-sale-price{
color: #f30000;
}
.footer {
flex: 1 1 100%;
text-align: center;
color: #ccc;
margin-top: 25px;
padding: 15px;
a {
color: #ccc;
text-decoration: none;
&:hover{
text-decoration: underline;
}
}
}
.update-product{
position: absolute;
top: 0;
text-align: center;
}
</style>
nuxt.confgs.js
const pkg = require('./package')
const { STRIPE_TOKEN } = process.env;
module.exports = {
vue: {
config: {
productionTip: false,
devtools: true
}
},
buildDir: './functions/nuxt',
mode: 'universal',
/*
** Headers of the page
*/
head: {
title: pkg.name,
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ hid: 'description', name: 'description', content: pkg.description }
],
link: [
{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
]
},
/*
** Customize the progress-bar color
*/
loading: { color: '#fff' },
/*
** Global CSS
*/
css: [
],
/*
** Plugins to load before mounting the App
*/
/*
** Nuxt.js modules
*/
modules: [
// Doc: https://github.com/nuxt-community/axios-module#usage
'#nuxtjs/axios',
'nuxt-stripe-module'
],
stripe: {
version: 'v3',
publishableKey: 'pk_test_XXX',
},
/*
** Axios module configuration
*/
axios: {
// See https://github.com/nuxt-community/axios-module#options
},
/*
** Build configuration
*/
build: {
/*
** You can extend webpack config here
*/
publicPath: '/public/',
vendor: [],
extractCSS: true,
bable: {
presets: [
'es2015',
'stage-8'
],
plugins: [
['transform-runtime', {
'polyfill': true,
'regenerator': true
}]
]
},
extend (config, { isDev }) {
if (isDev && process.client) {
config.module.rules.push({
enforce: 'pre',
test: /\.(js|vue)$/,
loader: 'eslint-loader',
exclude: /(node_modules)/
})
}
},
router: {
middleware: 'router-auth'
}
},
plugins: [
{ src: '~/plugins/fireauth', ssr: true }
]
}
store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const createStore = () => {
return new Vuex.Store({
state: () => ({
counter: 0
}),
actions: {
incrementCounterUp () {
this.commit('increment')
}
},
getters: {
counter: state => state.counter
},
mutations: {
increment (state) {
state.counter++
}
}
})
}
export default createStore
At the end of the day, I was not able to identify exactly what in my application was the error.
I assume that my during my initialization, configuration or development I touched something that should not have been touched, installed something that should not have be installed, messed with a package I should not have or was to bold in my nuxt.config.js changes.
I created a new nuxt app following the same install instructions. https://nuxtjs.org/guide/installation/
Moved the above _id.vue component exactly as it is and once I got dependencies updated it worked perfectly as seen in the image below.
Thank you very much #Boussadjra Brahim, #xaviert, #Andrew1325 for you assistance.

vuejs2 event listening not working

I am following this tutorial https://github.com/ratiw/vuetable-2-tutorial and trying to develop my laravel admin panel using vuejs.
Filter in the list vue is not working
This is my list.vue
<template>
<div>
<filter-bar></filter-bar>
<vuetable ref="vuetable"
api-url="/api/category/list"
:fields="fields"
pagination-path=""
:css="css.table"
:sort-order="sortOrder"
:multi-sort="true"
detail-row-component="my-detail-row"
:append-params="moreParams"
#vuetable:cell-clicked="onCellClicked"
#vuetable:pagination-data="onPaginationData"
></vuetable>
<div class="vuetable-pagination">
<vuetable-pagination-info ref="paginationInfo"
info-class="pagination-info"
></vuetable-pagination-info>
<vuetable-pagination ref="pagination"
:css="css.pagination"
:icons="css.icons"
#vuetable-pagination:change-page="onChangePage"
></vuetable-pagination>
</div>
</div>
</template>
<script>
import VueEvents from 'vue-events'
Vue.use(VueEvents)
var Vuetable = require('vuetable-2/src/components/Vuetable.vue');
Vue.use(Vuetable);
var VuetablePagination = require('vuetable-2/src/components/VuetablePagination.vue');
var VuetablePaginationInfo = require('vuetable-2/src/components/VuetablePaginationInfo.vue');
Vue.component('custom-actions', require('../CustomActions.vue'))
Vue.component('filter-bar', require('../FilterBar.vue'))
export default {
components: {
Vuetable,
VuetablePagination,
VuetablePaginationInfo,
},
data () {
return {
fields: [
{
name: 'id',
sortField: 'id',
},
{
name: 'name',
sortField: 'name',
},
{
name: '__component:custom-actions',
title: 'Actions',
titleClass: 'text-center',
dataClass: 'text-center'
}
],
css: {
table: {
tableClass: 'table table-bordered table-striped table-hover',
ascendingIcon: 'glyphicon glyphicon-chevron-up',
descendingIcon: 'glyphicon glyphicon-chevron-down'
},
pagination: {
wrapperClass: 'pagination',
activeClass: 'active',
disabledClass: 'disabled',
pageClass: 'page',
linkClass: 'link',
},
icons: {
first: 'glyphicon glyphicon-step-backward',
prev: 'glyphicon glyphicon-chevron-left',
next: 'glyphicon glyphicon-chevron-right',
last: 'glyphicon glyphicon-step-forward',
},
},
sortOrder: [
{ field: 'id', sortField: 'id', direction: 'asc'}
],
moreParams: {}
}
},
methods: {
onPaginationData (paginationData) {
this.$refs.pagination.setPaginationData(paginationData)
this.$refs.paginationInfo.setPaginationData(paginationData)
},
onChangePage (page) {
this.$refs.vuetable.changePage(page)
},
onCellClicked (data, field, event) {
console.log('cellClicked: ', field.name)
this.$refs.vuetable.toggleDetailRow(data.id)
},
onFilterSet (filterText) {
this.moreParams = {
'filter': filterText.trim()
}
Vue.nextTick( () => this.$refs.vuetable.refresh())
},
onFilterReset () {
this.moreParams = {}
Vue.nextTick( () => this.$refs.vuetable.refresh())
}
},
mounted() {
this.$events.$on('filter-set', eventData => this.onFilterSet(eventData))
this.$events.$on('filter-reset', e => this.onFilterReset())
}
}
</script>
<style>
.pagination {
margin: 0;
float: right;
}
.pagination a.page {
border: 1px solid lightgray;
border-radius: 3px;
padding: 5px 10px;
margin-right: 2px;
}
.pagination a.page.active {
color: white;
background-color: #337ab7;
border: 1px solid lightgray;
border-radius: 3px;
padding: 5px 10px;
margin-right: 2px;
}
.pagination a.btn-nav {
border: 1px solid lightgray;
border-radius: 3px;
padding: 5px 7px;
margin-right: 2px;
}
.pagination a.btn-nav.disabled {
color: lightgray;
border: 1px solid lightgray;
border-radius: 3px;
padding: 5px 7px;
margin-right: 2px;
cursor: not-allowed;
}
.pagination-info {
float: left;
}
</style>
Filter in the list vue is not working
This is my FilterBar.vue
<template>
<div class="filter-bar ui basic segment grid">
<div class="ui form">
<div class="inline field">
<label>Search for:</label>
<input type="text" v-model="filterText" class="three wide column" #keyup.enter="doFilter" placeholder="name, nickname, or email">
<button class="ui primary button" #click="doFilter">Go</button>
<button class="ui button" #click="resetFilter">Reset</button>
</div>
</div>
</div>
</template>
<script>
export default {
data () {
return {
filterText: ''
}
},
methods: {
doFilter () {
this.$events.fire('filter-set', this.filterText)
},
resetFilter () {
this.filterText = ''
this.$events.fire('filter-reset')
}
}
}
</script>
Event is being fired in the filterbar vue component, but listener in list.vue component doesn't pick it up
I tried the fix in the issues tab
1.using method and mounted
2.using created