Skip to content

Commit 54970a5

Browse files
committed
add count renderless data component
1 parent ce3568c commit 54970a5

File tree

3 files changed

+158
-6
lines changed

3 files changed

+158
-6
lines changed

src/FeathersVuexCount.ts

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
import { randomString } from './utils'
2+
3+
export default {
4+
props: {
5+
service: {
6+
type: String,
7+
required: true
8+
},
9+
params: {
10+
type: Object,
11+
default: () => {
12+
return {
13+
query: {}
14+
}
15+
}
16+
},
17+
queryWhen: {
18+
type: [Boolean, Function],
19+
default: true
20+
},
21+
// If separate params are desired to fetch data, use fetchParams
22+
// The watchers will automatically be updated, so you don't have to write 'fetchParams.query.propName'
23+
fetchParams: {
24+
type: Object
25+
},
26+
watch: {
27+
type: [String, Array],
28+
default: () => []
29+
},
30+
local: {
31+
type: Boolean,
32+
default: false
33+
}
34+
},
35+
data: () => ({
36+
isCountPending: false,
37+
serverTotal: null
38+
}),
39+
computed: {
40+
total() {
41+
if (!this.local) {
42+
return this.serverTotal
43+
} else {
44+
const { params, service, $store, temps } = this
45+
return params ? $store.getters[`${service}/count`](params) : 0
46+
}
47+
},
48+
scope() {
49+
const { total, isCountPending } = this
50+
51+
return { total, isCountPending }
52+
}
53+
},
54+
methods: {
55+
findData() {
56+
const params = this.fetchParams || this.params
57+
58+
if (
59+
typeof this.queryWhen === 'function'
60+
? this.queryWhen(this.params)
61+
: this.queryWhen
62+
) {
63+
this.isCountPending = true
64+
65+
if (params) {
66+
return this.$store
67+
.dispatch(`${this.service}/count`, params)
68+
.then(response => {
69+
this.isCountPending = false
70+
this.serverTotal = response
71+
})
72+
}
73+
}
74+
},
75+
fetchData() {
76+
if (!this.local) {
77+
if (this.params) {
78+
return this.findData()
79+
} else {
80+
// TODO: access debug boolean from the store config, somehow.
81+
// eslint-disable-next-line no-console
82+
console.log(
83+
`No query and no id provided, so no data will be fetched.`
84+
)
85+
}
86+
}
87+
}
88+
},
89+
created() {
90+
if (!this.$FeathersVuex) {
91+
throw new Error(
92+
`You must first Vue.use the FeathersVuex plugin before using the 'FeathersVuexFind' component.`
93+
)
94+
}
95+
if (!this.$store.state[this.service]) {
96+
throw new Error(
97+
`The '${this.service}' plugin not registered with feathers-vuex`
98+
)
99+
}
100+
101+
const watch = Array.isArray(this.watch) ? this.watch : [this.watch]
102+
103+
if (this.fetchParams || this.params) {
104+
watch.forEach(prop => {
105+
if (typeof prop !== 'string') {
106+
throw new Error(`Values in the 'watch' array must be strings.`)
107+
}
108+
if (this.fetchParams) {
109+
if (prop.startsWith('params')) {
110+
prop = prop.replace('params', 'fetchParams')
111+
}
112+
}
113+
this.$watch(prop, this.fetchData)
114+
})
115+
116+
this.fetchData()
117+
}
118+
},
119+
render() {
120+
return this.$scopedSlots.default(this.scope)
121+
}
122+
}

src/FeathersVuexFind.ts

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,22 @@ export default {
2020
fetchQuery: {
2121
type: Object
2222
},
23+
/**
24+
* Can be used in place of the `query` prop to provide more params. Only params.query is
25+
* passed to the getter.
26+
*/
27+
params: {
28+
type: Object,
29+
default: null
30+
},
31+
/**
32+
* Can be used in place of the `fetchQuery` prop to provide more params. Only params.query is
33+
* passed to the getter.
34+
*/
35+
fetchParams: {
36+
type: Object,
37+
default: null
38+
},
2339
watch: {
2440
type: [String, Array],
2541
default() {
@@ -58,7 +74,9 @@ export default {
5874
computed: {
5975
items() {
6076
const { query, service, $store, temps } = this
61-
const params = { query, temps }
77+
let { params } = this
78+
79+
params = params || { query, temps }
6280

6381
return query ? $store.getters[`${service}/find`](params).data : []
6482
},
@@ -94,16 +112,21 @@ export default {
94112
methods: {
95113
findData() {
96114
const query = this.fetchQuery || this.query
115+
let params = this.fetchParams || this.params
97116

98117
if (
99118
typeof this.queryWhen === 'function'
100-
? this.queryWhen(this.query)
119+
? this.queryWhen(this.params || this.query)
101120
: this.queryWhen
102121
) {
103122
this.isFindPending = true
104123

105-
if (query) {
106-
const params = { query, qid: this.qid || 'default' }
124+
if (params || query) {
125+
if (params) {
126+
params = Object.assign({}, params, { qid: this.qid || 'default' })
127+
} else {
128+
params = { query, qid: this.qid || 'default' }
129+
}
107130

108131
return this.$store
109132
.dispatch(`${this.service}/find`, params)
@@ -118,7 +141,7 @@ export default {
118141
},
119142
fetchData() {
120143
if (!this.local) {
121-
if (this.query) {
144+
if (this.params || this.query) {
122145
return this.findData()
123146
} else {
124147
// TODO: access debug boolean from the store config, somehow.
@@ -144,7 +167,7 @@ export default {
144167

145168
const watch = Array.isArray(this.watch) ? this.watch : [this.watch]
146169

147-
if (this.fetchQuery || this.query) {
170+
if (this.fetchQuery || this.query || this.params) {
148171
watch.forEach(prop => {
149172
if (typeof prop !== 'string') {
150173
throw new Error(`Values in the 'watch' array must be strings.`)
@@ -154,6 +177,11 @@ export default {
154177
prop = prop.replace('query', 'fetchQuery')
155178
}
156179
}
180+
if (this.fetchParams) {
181+
if (prop.startsWith('params')) {
182+
prop = prop.replace('params', 'fetchParams')
183+
}
184+
}
157185
this.$watch(prop, this.fetchData)
158186
})
159187

src/vue-plugin/vue-plugin.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import FeathersVuexGet from '../FeathersVuexGet'
88
import FeathersVuexFormWrapper from '../FeathersVuexFormWrapper'
99
import FeathersVuexInputWrapper from '../FeathersVuexInputWrapper'
1010
import FeathersVuexPagination from '../FeathersVuexPagination'
11+
import FeathersVuexCount from '../FeathersVuexCount'
1112
import { globalModels } from '../service-module/global-models'
1213

1314
export const FeathersVuex = {
@@ -23,6 +24,7 @@ export const FeathersVuex = {
2324
Vue.component('FeathersVuexFormWrapper', FeathersVuexFormWrapper)
2425
Vue.component('FeathersVuexInputWrapper', FeathersVuexInputWrapper)
2526
Vue.component('FeathersVuexPagination', FeathersVuexPagination)
27+
Vue.component('FeathersVuexCount', FeathersVuexCount)
2628
}
2729
}
2830
}

0 commit comments

Comments
 (0)