Created
December 19, 2022 14:53
-
-
Save gabrielheinrich/ca6df751a68aec6e41ce12606f9adac7 to your computer and use it in GitHub Desktop.
BookEdit vue in Options and Composition API
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<template> | |
<form v-if="book" @submit.prevent="onSubmit"> | |
<label for="title">Title: </label> | |
<input type="text" name="title" id="title" v-model="book.title" /> | |
<div v-if="errors.title"> | |
{{ errors.title }} | |
</div> | |
<button type="submit">Save</button> | |
</form> | |
</template> | |
<script lang="ts"> | |
import { | |
defineComponent, | |
ref, | |
reactive, | |
computed, | |
watch, | |
watchEffect, | |
} from "vue"; | |
import { useRouter } from "vue-router"; | |
import type { Book } from "@/Book"; | |
export default defineComponent({ | |
props: { | |
isbn: { | |
type: String, | |
required: true, | |
}, | |
}, | |
setup(props) { | |
console.log("setup", props.isbn); | |
// const isbn = props.isbn; // !!!! | |
// const book = ref(null as null | Book); | |
const book = ref<null | Book>(null); | |
const errors = reactive({ | |
title: "", | |
}); | |
const router = useRouter(); | |
const onSubmit = async () => { | |
if (!isValid.value) return; | |
await fetch("http://localhost:4730/books/" + props.isbn, { | |
method: "PUT", | |
headers: { | |
"Content-Type": "application/json", | |
}, | |
body: JSON.stringify(book.value), | |
}); | |
router.push({ path: "/books", params: { isbn: props.isbn } }); | |
}; | |
const validateTitle = () => { | |
if (!book.value) return; | |
if (book.value.title.length < 5) { | |
errors.title = "Title has to be at least 5 chars long"; | |
} else { | |
errors.title = ""; | |
} | |
}; | |
watch(() => book.value?.title, validateTitle, { immediate: true }); | |
watchEffect(async () => { | |
const response = await fetch("http://localhost:4730/books/" + props.isbn); | |
book.value = await response.json(); | |
}); | |
const isValid = computed(() => { | |
return errors.title == ""; | |
}); | |
return { | |
book, | |
errors, | |
msg: "Hello World", | |
validateTitle, | |
isValid, | |
onSubmit, | |
}; | |
}, | |
}); | |
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<template> | |
<form v-if="book" @submit.prevent="onSubmit"> | |
<label for="title">Title: </label> | |
<input type="text" name="title" id="title" v-model="book.title" /> | |
<div v-if="errors.title"> | |
{{ errors.title }} | |
</div> | |
<button type="submit">Save</button> | |
</form> | |
</template> | |
<script lang="ts"> | |
import { defineComponent } from "vue"; | |
import type { Book } from "@/Book"; | |
interface ComponentData { | |
book: null | Book; | |
errors: { | |
[key in keyof Book]?: string; | |
}; | |
} | |
export default defineComponent({ | |
props: { | |
isbn: { | |
type: String, | |
required: true, | |
}, | |
}, | |
data(): ComponentData { | |
return { | |
book: null as null | Book, // check | |
errors: { | |
title: "", | |
}, // check | |
}; | |
}, | |
computed: { | |
isValid() { | |
// check | |
return this.errors.title == ""; | |
}, | |
}, | |
methods: { | |
async onSubmit() { | |
if (!this.isValid) return; | |
await fetch("http://localhost:4730/books/" + this.isbn, { | |
method: "PUT", | |
headers: { | |
"Content-Type": "application/json", | |
}, | |
body: JSON.stringify(this.book), | |
}); | |
this.$router.push({ path: "/books", params: { isbn: this.isbn } }); | |
}, | |
validateTitle() { | |
if (!this.book) return; | |
if (this.book.title.length < 5) { | |
this.errors.title = "Title has to be at least 5 chars long"; | |
} else { | |
this.errors.title = ""; | |
} | |
}, | |
}, | |
watch: { | |
isbn: { | |
async handler(newValue, oldValue) { | |
const response = await fetch( | |
"http://localhost:4730/books/" + this.isbn | |
); | |
this.book = await response.json(); | |
}, | |
immediate: true, | |
}, | |
"book.title"() { | |
this.validateTitle(); | |
}, | |
}, | |
}); | |
</script> | |
<style scoped></style> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment