weirdlooop
weirdlooop

Reputation: 1

Convert options api to composition api for vue3 - v-model binding and watch

I have the following working code for a search input using options API for component data, watch and methods, I am trying to convert that to the composition api.

I am defining props in <script setup> and also a onMounted function.

<template>
  <label for="search" class="hidden">Search</label>
  <input
    id="search"
    ref="search"
    v-model="search"
    class="border-gray-300 focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50 rounded-md shadow-sm h-9 w-1/2"
    :class="{ 'transition-border': search }"
    autocomplete="off"
    name="search"
    placeholder="Search"
    type="search"
    @keyup.esc="search = null"
  />
</template>

<script setup>

import {onMounted} from "vue";

const props = defineProps({
  routeName: String
});

onMounted(() => {
  document.getElementById('search').focus()
});

</script>

<!--TODO convert to composition api-->
<script>
import { defineComponent } from "vue";

export default defineComponent({

  data() {
    return {
      // page.props.search will come from the backend after search has returned.
      search: this.$inertia.page.props.search || null,
    };
  },

  watch: {
    search() {
      if (this.search) {
        // if you type something in the search input
        this.searchMethod();
      } else {
        // else just give us the plain ol' paginated list - route('stories.index')
        this.$inertia.get(route(this.routeName));
      }
    },
  },

  methods: {
    searchMethod: _.debounce(function () {
      this.$inertia.get(
        route(this.routeName),
        { search: this.search }
      );
    }, 500),
  },
});
</script>

What I am trying to do is convert it to the composition api. I have tried the following but I can't get it to work at all.

let search = ref(usePage().props.value.search || null);

watch(search, () => {
  if (search.value) {
    // if you type something in the search input
    searchMethod();
  } else {
    // else just give us the plain ol' paginated list - route('stories.index')
    Inertia.get(route(props.routeName));
  }
});


function searchMethod() {
  _.debounce(function () {
    Inertia.get(
      route(props.routeName),
      {search: search}
    );
  }, 500)
}

Any help or pointers in how to convert what is currently in <script> into <script setup> would be greatly appreciated thanks.

Upvotes: 0

Views: 532

Answers (1)

weirdlooop
weirdlooop

Reputation: 1

I managed to get this working with the below!

<script setup>
import {onMounted, ref} from "vue";
import {Inertia} from "@inertiajs/inertia";

const props = defineProps({
  route_name: {
    type: String,
    required: true
  },
  search: {
    type: String,
    default: null
  }
});

const search = ref(props.search);

onMounted(() => {

  search.value.focus();

  search.value.addEventListener('input', () => {
    if (search.value.value) {
      searching();
    } else {
      Inertia.get(route(props.route_name));
    }
  });
});

const searching = _.debounce(function() {
  Inertia.get(route(props.route_name), {search: search.value.value});
}, 500);

</script>

Upvotes: 0

Related Questions