Separating the dependency of UI and functional data in Vue

In this post I’ll show a way to separate the dependency of UI and functional data in Vue.

Let’s say we have a dashboard that displays a user profile button.

// store.ts
const store = createStore({
  state: {
    email: ''
  }
})
<script setup lang="ts">
import { store } from '@/store'
 
const store = useStore()
 
const updateEmail = async (email: string) => {
  await fetch.put('/api/user/email', {
    method: 'PUT',
    body: {
      email: store.state.email
    }
  })
}
</script>
 
<template>
  <button @click="updateEmail">{{ store.state.email }}</button>
</template>
//action.ts
export function updateEmail(email: string) {
  store.state.email = email
}
// store.js
import { reactive } from 'vue'
 
export const uiStore = reactive({
  emailInputValue: ''
})
 
export const dataStore = reactive({
  email: ''
})
 
export function updateEmail() {
  dataStore.email = uiStore.emailInputValue
  // POST email to server
}