mirror of
https://github.com/tenrok/vue-select.git
synced 2026-06-22 10:30:34 +03:00
WIP: v3 – remove onSearch callback prop (#811)
* remove onSearch callback prop * update ajax docs * docs formatting * remove onSearch callback prop
This commit is contained in:
+31
-19
@@ -1,22 +1,25 @@
|
|||||||
# AJAX Remote Option Loading
|
## Loading Options with AJAX
|
||||||
|
|
||||||
<CodePen url="POMeOX" height="400"/>
|
The `search` event provides a hook to load options from a parent component
|
||||||
|
when the search text is updated. It is emitted with two parameters:
|
||||||
|
|
||||||
|
**Search Event Parameters**
|
||||||
|
- `search {String}` The current search string
|
||||||
|
- `loading {Function}` Accepts a boolean parameter to toggle the loading state
|
||||||
|
|
||||||
The `onSearch` prop allows you to load options via ajax in a parent component
|
```html
|
||||||
when the search text is updated. It is invoked with two parameters, `search` & `loading`.
|
<v-select @search="fetchOptions" />
|
||||||
|
```
|
||||||
|
|
||||||
```js
|
```js
|
||||||
/**
|
/**
|
||||||
* Accepts a callback function that will be run
|
* Triggered when the search text changes.
|
||||||
* when the search text changes. The callback
|
*
|
||||||
* will be invoked with these parameters:
|
* @param search {String} Current search text
|
||||||
*
|
* @param loading {Function} Toggle loading class
|
||||||
* @param {search} String Current search text
|
*/
|
||||||
* @param {loading} Function Toggle loading class
|
fetchOptions (search, loading) {
|
||||||
*/
|
// ... do some asynchronous stuff!
|
||||||
onSearch: {
|
|
||||||
type: Function,
|
|
||||||
default: false
|
|
||||||
},
|
},
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -25,7 +28,7 @@ to the vue-select internal `loading` property. Call `loading(true)` to set the
|
|||||||
`loading` property to `true` - toggling the loading spinner. After your
|
`loading` property to `true` - toggling the loading spinner. After your
|
||||||
asynchronous operation completes, call `loading(false)` to toggle it off.
|
asynchronous operation completes, call `loading(false)` to toggle it off.
|
||||||
|
|
||||||
#### Disabling Filtering
|
## Disabling Filtering
|
||||||
|
|
||||||
When loading server side options, it can be useful to disable the
|
When loading server side options, it can be useful to disable the
|
||||||
client side filtering. Use the `filterable` prop to disable filtering.
|
client side filtering. Use the `filterable` prop to disable filtering.
|
||||||
@@ -44,17 +47,26 @@ filterable: {
|
|||||||
},
|
},
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Loading Spinner
|
## Loading Spinner
|
||||||
|
|
||||||
Vue Select includes a default loading spinner that appears when the loading class is present. The `spinner` slot allows you to implement your own spinner.
|
Vue Select includes a default loading spinner that appears when the loading class is present. The
|
||||||
|
`spinner` slot allows you to implement your own spinner.
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<div class="spinner" v-show="spinner">Loading...</div>
|
<div class="spinner" v-show="spinner">Loading...</div>
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Library Agnostic
|
## Library Agnostic
|
||||||
|
|
||||||
Since Vue.js does not ship with ajax functionality as part of the core library, it's up to you to process the ajax requests in your parent component.
|
Since Vue.js does not ship with ajax functionality as part of the core library, it's up to you to
|
||||||
|
process the ajax requests in your parent component.
|
||||||
|
|
||||||
I recommend using [axios](https://github.com/axios/axios) for creating your applications HTTP layer,
|
I recommend using [axios](https://github.com/axios/axios) for creating your applications HTTP layer,
|
||||||
or [`fetch()`](https://github.com/github/fetch) for simple requests.
|
or [`fetch()`](https://github.com/github/fetch) for simple requests.
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
The [codepen example](https://codepen.io/sagalbot/pen/POMeOX) wraps up all the above concepts and
|
||||||
|
searches GitHub repositories. It also uses scoped slots to add some custom templating.
|
||||||
|
|
||||||
|
<CodePen url="POMeOX" height="400"/>
|
||||||
|
|||||||
@@ -2,9 +2,8 @@
|
|||||||
Install with yarn:
|
Install with yarn:
|
||||||
```bash
|
```bash
|
||||||
yarn add vue-select
|
yarn add vue-select
|
||||||
```
|
|
||||||
or, using NPM:
|
# or, using NPM
|
||||||
```
|
|
||||||
npm install vue-select
|
npm install vue-select
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -23,7 +22,7 @@ The component itself does not include any CSS. You'll need to include it separat
|
|||||||
import 'vue-select/dist/vue-select.css';
|
import 'vue-select/dist/vue-select.css';
|
||||||
```
|
```
|
||||||
|
|
||||||
You can also import the scss yourself for complete control of the component styles:
|
Alternatively, you can import the scss for complete control of the component styles:
|
||||||
|
|
||||||
```scss
|
```scss
|
||||||
@import "vue-select/src/scss/vue-select.scss";
|
@import "vue-select/src/scss/vue-select.scss";
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
# Dropdown Options
|
|
||||||
|
|
||||||
## Options Prop
|
## Options Prop
|
||||||
|
|
||||||
`vue-select` accepts arrays of primitive values or objects to use as options through the `options` prop:
|
`vue-select` accepts arrays of primitive values or objects to use as options through the `options` prop:
|
||||||
|
|||||||
+18
-31
@@ -7,51 +7,38 @@ export default {
|
|||||||
*/
|
*/
|
||||||
loading: {
|
loading: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false,
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* Accept a callback function that will be
|
|
||||||
* run when the search text changes.
|
|
||||||
*
|
|
||||||
* loading() accepts a boolean value, and can
|
|
||||||
* be used to toggle a loading class from
|
|
||||||
* the onSearch callback.
|
|
||||||
*
|
|
||||||
* @param {search} String Current search text
|
|
||||||
* @param {loading} Function(bool) Toggle loading class
|
|
||||||
*/
|
|
||||||
onSearch: {
|
|
||||||
type: Function,
|
|
||||||
default: function(search, loading) {} // eslint-disable-line no-unused-vars
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
data() {
|
data () {
|
||||||
return {
|
return {
|
||||||
mutableLoading: false
|
mutableLoading: false,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
watch: {
|
watch: {
|
||||||
/**
|
/**
|
||||||
* If a callback & search text has been provided,
|
* Anytime the search string changes, emit the
|
||||||
* invoke the onSearch callback.
|
* 'search' event. The event is passed with two
|
||||||
|
* parameters: the search string, and a function
|
||||||
|
* that accepts a boolean parameter to toggle the
|
||||||
|
* loading state.
|
||||||
|
*
|
||||||
|
* @emits search
|
||||||
*/
|
*/
|
||||||
search() {
|
search () {
|
||||||
if (this.search.length > 0) {
|
this.$emit('search', this.search, this.toggleLoading);
|
||||||
this.onSearch(this.search, this.toggleLoading);
|
|
||||||
this.$emit("search", this.search, this.toggleLoading);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sync the loading prop with the internal
|
* Sync the loading prop with the internal
|
||||||
* mutable loading value.
|
* mutable loading value.
|
||||||
* @param val
|
* @param val
|
||||||
*/
|
*/
|
||||||
loading(val) {
|
loading (val) {
|
||||||
this.mutableLoading = val;
|
this.mutableLoading = val;
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
@@ -62,11 +49,11 @@ export default {
|
|||||||
* @param toggle Boolean
|
* @param toggle Boolean
|
||||||
* @returns {*}
|
* @returns {*}
|
||||||
*/
|
*/
|
||||||
toggleLoading(toggle = null) {
|
toggleLoading (toggle = null) {
|
||||||
if (toggle == null) {
|
if (toggle == null) {
|
||||||
return (this.mutableLoading = !this.mutableLoading);
|
return (this.mutableLoading = !this.mutableLoading);
|
||||||
}
|
}
|
||||||
return (this.mutableLoading = toggle);
|
return (this.mutableLoading = toggle);
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
+14
-44
@@ -1,4 +1,6 @@
|
|||||||
import { selectWithProps } from "../helpers";
|
import { selectWithProps } from "../helpers";
|
||||||
|
import { shallowMount } from '@vue/test-utils';
|
||||||
|
import vSelect from '../../src/components/Select';
|
||||||
|
|
||||||
describe("Asynchronous Loading", () => {
|
describe("Asynchronous Loading", () => {
|
||||||
it("can toggle the loading class", () => {
|
it("can toggle the loading class", () => {
|
||||||
@@ -11,33 +13,6 @@ describe("Asynchronous Loading", () => {
|
|||||||
expect(Select.vm.mutableLoading).toEqual(true);
|
expect(Select.vm.mutableLoading).toEqual(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should trigger the onSearch callback when the search text changes", () => {
|
|
||||||
const propsData = { onSearch: () => {} };
|
|
||||||
const spy = jest.spyOn(propsData, "onSearch");
|
|
||||||
const Select = selectWithProps(propsData);
|
|
||||||
|
|
||||||
Select.vm.search = "foo";
|
|
||||||
|
|
||||||
expect(spy).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should not trigger the onSearch callback if the search text is empty", () => {
|
|
||||||
let calledWith = [];
|
|
||||||
const propsData = {
|
|
||||||
onSearch: search => {
|
|
||||||
calledWith.push(search);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const spy = jest.spyOn(propsData, "onSearch");
|
|
||||||
const Select = selectWithProps(propsData);
|
|
||||||
|
|
||||||
Select.vm.search = "foo";
|
|
||||||
Select.vm.search = "";
|
|
||||||
|
|
||||||
expect(spy).toHaveBeenCalledTimes(1);
|
|
||||||
expect(calledWith).toEqual(["foo"]);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should trigger the search event when the search text changes", () => {
|
it("should trigger the search event when the search text changes", () => {
|
||||||
const Select = selectWithProps();
|
const Select = selectWithProps();
|
||||||
|
|
||||||
@@ -49,7 +24,7 @@ describe("Asynchronous Loading", () => {
|
|||||||
expect(events.length).toEqual(1);
|
expect(events.length).toEqual(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should not trigger the search event if the search text is empty", () => {
|
it("should trigger the search event if the search text is empty", () => {
|
||||||
const Select = selectWithProps();
|
const Select = selectWithProps();
|
||||||
|
|
||||||
Select.vm.search = "foo";
|
Select.vm.search = "foo";
|
||||||
@@ -57,30 +32,25 @@ describe("Asynchronous Loading", () => {
|
|||||||
|
|
||||||
const events = Select.emitted("search");
|
const events = Select.emitted("search");
|
||||||
|
|
||||||
expect(events).toContainEqual(["foo", Select.vm.toggleLoading]);
|
expect(events).toContainEqual(["", Select.vm.toggleLoading]);
|
||||||
expect(events.length).toEqual(1);
|
expect(events.length).toEqual(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("can set loading to false from the onSearch callback", () => {
|
it("can set loading to false from the @search event callback", () => {
|
||||||
const Select = selectWithProps({
|
const Select = shallowMount(vSelect, {
|
||||||
onSearch: (search, loading) => loading(false)
|
listeners: {
|
||||||
|
search: (search, loading) => {
|
||||||
|
loading(false)
|
||||||
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
Select.vm.search = "foo";
|
Select.vm.mutableLoading = true;
|
||||||
|
Select.vm.search = 'foo';
|
||||||
|
|
||||||
expect(Select.vm.mutableLoading).toEqual(false);
|
expect(Select.vm.mutableLoading).toEqual(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("can set loading to true from the onSearch callback", () => {
|
|
||||||
const Select = selectWithProps({
|
|
||||||
onSearch: (search, loading) => loading(true)
|
|
||||||
});
|
|
||||||
|
|
||||||
Select.vm.search = "foo";
|
|
||||||
|
|
||||||
expect(Select.vm.mutableLoading).toEqual(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("will sync mutable loading with the loading prop", () => {
|
it("will sync mutable loading with the loading prop", () => {
|
||||||
const Select = selectWithProps({ loading: false });
|
const Select = selectWithProps({ loading: false });
|
||||||
Select.setProps({ loading: true });
|
Select.setProps({ loading: true });
|
||||||
|
|||||||
Reference in New Issue
Block a user