Spin the wheel: building a truly reusable composable

slides

livecoding

What problem do we want to solve?

What problem do we want to solve?

Natalia Tepluhina

Staff Frontend Engineer

Core Team Member

Google Dev Expert

If you never heard what

Vue Composition API is...

We can create a standalone reactive state and/or properties...

import { ref } from 'vue'

const login = ref('')
const password = ref('')

login.value = 'johndoe'

...and use them in the Vue components

<template>
  <form>
    <input v-model="login" type="text" placeholder="Login" />
    <input v-model="password" type="password" placeholder="Password" />
    <button type="submit">Submit</button>
  </form>
</template>

<script>
import { ref } from 'vue';

export default {
  setup() {
    const login = ref('')
    const password = ref('')

    return { login, password };
  }
};
</script>

We can abstract reactive state!

// useForm.js

import { ref } from 'vue';

export function useForm() {
  const login = ref('')
  const password = ref('')

  function submitForm() {
    console.log(`User ${login} is logging in`)
  }

  return { login, password, submitForm };
};
<!-- MyComponent.vue -->

<template>
  <form @submit.prevent="submitForm">
    <input v-model="login" type="text" placeholder="Login" />
    <input v-model="password" type="password" placeholder="Password" />
    <button type="submit">Submit</button>
  </form>
</template>

<script>
import { useForm } from './useForm.js';

export default {
  setup() {
    const { login, password, submitForm } = useForm()

    return { login, password, submitForm };
  }
};
</script>

This is still not answering why this API is useful 🤔

                  universal logic composition

Flexible

Flexible

export const formMixin = {
  data() {
    login: '',
    password: ''
  },
  methods: {
    submitForm() {
      console.log(`User ${login} is logging in`)
    }
  }
}

Flexible

export const formMixin = {
  data() {
    login: '',
    password: ''
  },
  methods: {
    submitForm() {
      console.log(
        formId,
        `User ${login} is logging in`
      )
    }
  }
}

Universal

<template
  <form-wrapper>
    <template #default="{ login, password, submitForm }">
      <form @submit.prevent="submitForm">
        <input v-model="login" type="text" placeholder="Login" />
        <input v-model="password" type="password" placeholder="Password" />
        <button type="submit">Submit</button>
      </form>
    </template>
  </form-wrapper>
</template>

Universal

<template
  <form-wrapper>
    <template #default="{ login, password, submitForm }">
      <form @submit.prevent="submitForm">
        <input v-model="login" type="text" placeholder="Login" />
        <input v-model="password" type="password" placeholder="Password" />
        <button type="submit">Submit</button>
      </form>
    </template>
  </form-wrapper>
  <div>
    {{ login }}
  </div>
</template>

Let's try to solve this with Composition API!

Final result

Thank you all for watching!

Spin the wheel: building a truly reusable composable

By Natalia Tepluhina

Spin the wheel: building a truly reusable composable

  • 1,064