algolia / vue-instantsearch

👀 Algolia components for building search UIs with Vue.js
https://www.algolia.com/doc/guides/building-search-ui/what-is-instantsearch/vue
MIT License
854 stars 157 forks source link

Support Composition API #1051

Closed eunjae-lee closed 1 year ago

eunjae-lee commented 3 years ago

Summary

Hello, Vue InstantSearch users!

Can you let us know if you're interested to have composition APIs as part of Vue InstantSearch? We'd like to learn what kind of APIs you've wished to have in which use-case.

Feel free to react to this issue, drop any idea as comments, or try the following code if you're very adventurous.

import { inject, ref } from 'vue';
import { connectSearchBox } from 'instantsearch.js/es/connectors';

const noop = () => {};

export function useConnect(connector, props, initialState) {
  const instantSearchInstance = inject('$_ais_instantSearchInstance');
  const getParentIndex = inject('$_ais_getParentIndex');
  const indexWidget = getParentIndex && getParentIndex();
  const parent = indexWidget || instantSearchInstance;
  const state = ref(initialState);
  let widget = ref(null);

  const addWidget = () => {
    if (widget.value) {
      parent.removeWidgets([widget.value]);
    }
    const createWidget = connector(newState => {
      state.value = newState;
    });
    widget.value = createWidget(props);
    parent.addWidgets([widget.value]);
  };

  addWidget();
  // watch(connector, addWidget);
  // watch(props, addWidget);

  return state;
}

export function useSearchBox(props) {
  return useConnect(connectSearchBox, props, {
    query: '',
    refine: noop,
    clear: noop,
    isSearchStalled: false,
  });
}
<template>
  <div>
    <!-- <pre>{{ searchBoxState }}</pre> -->
    <input
      :value="searchBoxState.query"
      @input="event => searchBoxState.refine(event.target.value)"
    />
  </div>
</template>

<script>
import { useSearchBox } from '../compositions';

export default {
  setup() {
    const searchBoxState = useSearchBox();
    console.log('# searchBoxState: ', searchBoxState);
    return { searchBoxState };
  },
};
</script>

↑ This is not tested much, and definitely not recommended for production.

nobitagit commented 2 years ago

This would be a great addition, so here's my 👍 .

I reckon that exposing logic via functions (useSearchBox) vs only via pre-made components (ais-search-box) would allow people to have a much more fine grained control of how to render results.

For instance, a situation like building a very custom layout when doing multi-index search (see this question for instance) would be easier to manage in user-land by going through fewer hoops.

Haroenv commented 2 years ago

In the mean time, you can already check out https://github.com/algolia/vue-instantsearch/pull/1052 (and the version released by codesandbox) there @nobitagit, the code works completely (vue 2 & vue 3), but we still have to make a final decision with the team on how to expose it

szymon-ucinski commented 2 years ago

Would love to use it. Is it going to be released soon?

Haroenv commented 2 years ago

For the time being I would recommend that you take a look at useConnector and introduce that in your own code base, before we finalise that pull request. If you have any returns on experience after that, I'd love to hear your opinions @szymon-ucinski