[Vue.js] Using the KAKAO Postal Code Address API
[Vue.js] Using the KAKAO Postal Code Address API
Use the postal code API provided by Kakao in the vue.js project.
1. Set up the project
omit
2. Test the library
Refer to the postcode (and address search) API page provided by Kakao and write the related module.
2.1. Import the library
To use the API, you need to import the js file below.
JAVASCRIPThttps://t1.daumcdn.net/mapjsapi/bundle/postcode/prod/postcode.v2.js
there are two ways to import libraries.
- import with a
<script>
tag in your HTML file - dynamically generate
<script>
tags to import JS files
in this example, we'll import the JavaScript for the Postcode API into an html file for ease of implementation.
if you created a vue project using the vue cli, the html for the template exists by default under the public
directory.
TXT[PROJECT ROOT]
+- public
+- index.html (!)
+- src
+- App.vue
+- main.js
open the index.html
file and import the js file provided by the document inside head
.
HTML<!DOCTYPE html>
<html lang=""><!
<head> <!
...
<script src="//t1.daumcdn.net/mapjsapi/bundle/postcode/prod/postcode.v2.js"></script>
</head>
<body>
...
</body>
</html>
when imported as above, the library installs the required library code into the window built-in object.
TXTwindow.daum.Postcode
2.2. Test
to check how to use it, open the address search bar in a new window.
create the top-level component file PostCodeApp.vue
for the test.
TXT[PROJECT ROOT]
+- public
+- index.html
+- src
+- App.vue
+- PostCodeApp.vue (+)
+- main.js
replace the top-level component in main.js
with PostCodeApp.vue
.
JAVASCRIPTimport Vue from "vue";
// import App from './App.vue' (-)
import PostCodeApp from "./PostCodeApp.vue"; (+)
Vue.config.productionTip = false;
new Vue({
// render: (h) => h(App), // (-)
render: (h) => h(PostCodeApp), // (+)
}).$mount("#app");
fill in the contents of the PostCodeApp.vue
file as shown below.
PostCodeApp.vue<template> <div class="postcode-demo
<div class="postcode-demo">
<button @click="showPopup()">Test button</button>
</div>
</template>
<script> </script
export default {
data() {
return {
};
},
mounted() {},
methods: {
showPopup() {
alert('Open the address search bar here')
}
},
};
</script>
<style></style>
- if you type the string
vue
in the newly created vue file and press tab, the default template is automatically generated.
verify that the test button comes out correctly on the browser screen. an alert window should pop up when the button is pressed.
now, write the code below to display the address search box when the button is pressed.
PostCodeApp.vueexport default {
data() {
return {
};
},
mounted() {},
methods: {
showPopup() {
// alert('Open address search box here')
new window.daum.Postcode({
oncomplete: function(data) {
// This is the part where we write the code that will be executed when the search result item is clicked in the popup.
// Check out the example to see how it can be utilized.
}
}).open();
}
},
};
- new window.daum.Postcode({..}) - creates an instance of the address bar
- .open() - opens the address bar as a popup window
go back to the browser and press the button to open the popup window.
oncomplete callback
when you search for an address in the address search box and click on any address in the list that is displayed, you can get the information of the clicked address through the oncomplete
callback.
PostCodeApp.vueexport default {
...
methods: {
showPopup() {
...
new window.daum.Postcode({
oncomplete: function(data) {
console.log(data) // console output
}
}).open();
}
},
};
- method argument data is the clicked address information.
the important fields of the address information are as follows
JAVASCRIPT{
..,
jibunAddress: "275-2, Macheon-dong, Songpa-gu, Seoul, Korea",
jibunAddressEnglish: "275-2, Macheon-dong, Songpa-gu, Seoul, Korea",
..,
roadAddress: "6-3, Gaminam-ro, Songpa-gu, Seoul, Korea",
roadAddressEnglish: "6-3, Gaminam-ro, Songpa-gu, Seoul, Korea",
..,
zonecode: "05762"
}
- jibunAddress - existing address (with English)
- roadAddress - street address (with English)
use the address information passed to the oncomplete
method to populate the necessary forms in the context of your application.
3. Build the component
in mobile environments, it is often inappropriate to display a popup window. The Kakao Postcode Search API provides the ability to embed the address bar in a specific element.
3.1. embedding mode
in this case, we will create the address search box as a separate component and embed it wherever we need it.
create a file called PostCode.vue
under the components
directory like this The address bar that pops up will be located in this file.
TXT[PROJECT ROOT]
+- public
+- index.html
+- src
+- components
+- PostCode.vue (+)
+- App.vue
+- PostCodeApp.vue
+- main.js
create a PostCode.vue
file like the one below.
PostCode.vue<template> <div class="postcode-wrapper
<div class="postcode-wrapper"> <div class="body" ref="postarea
<div class="body" ref="postarea"> <!-- Here is the address bar
<!-- We want to put the address bar here -->
</div>
</div>
</template>
<script> <!
export default {
mounted() {
console.log("[SHOULD NOT NULL]", this.$refs.postarea);
new window.daum.Postcode({
oncomplete: (data) => {
console.log("[Selected address]", data);
},
}).embed(this.$refs.postarea);
},
};
</script>
<style></style>
the postcode (address) search API requires you to specify a dom element to embed the address search bar.
in a VUE-based project, you can use REF to access a specific DOM element.
in the code above, we've defined the ref attribute value postarea
on an element with class value ".body" (the name of the attribute value is arbitrary for context)
and in the javascript area, we can get a reference to the dom element, like this.$refs.postarea
.
finally, if you call embed(..)
immediately after creating the address bar instance, the address bar will be created inside ".body".
3.2. Using Components
in PostCodeApp.vue
, we use the PostCode.vue
component.
PostCodeApp.vue<template> <div class="postcode-demo
<div class="postcode-demo">
<button @click="showPopup()">Test button</button>
<PostCode /> <!-- (3) Enable -->
</div>
</template>
<script>
import PostCode from './components/PostCode.vue' // (1) import component
export default {
components: {
PostCode, // (2) register as a local component
},
data() {
return {
};
},
methods: {
showPopup() {
alert('Open address search bar here')
}
},
};
</script>
<style></style>
to add a component, you need to do three things
- import the component you want to use
- register it as a local component
- use it inside <template>...</template>
for now, PostCode.vue
will appear right on the screen.
3.3. Conditional Rendering (v-if
)
i want a popup to appear only when a button is pressed.
to do this, define the visible variable in PostCodeApp.vue as shown below.
PostCodeApp.vue<template> <div class="postcode-demo
<div class="postcode-demo"> <button @click="showPopup()
<button @click="showPopup()">Test button</button>
<PostCode v-if="visible"/> <!-- (2) Only when visible is true -->
</div>
</template>
<script>
import PostCode from "./components/PostCode.vue";
export default {
components: {
PostCode,
},
data() {
return {
visible: false // (+) false, start PostCode invisible
};
},
methods: {
showPopup() {
// Changing visible to true will render the PostCode component
this.visible = true
}
},
};
</script>
- calling the
showPopup()
method when the button is clicked - in
showPopup()
, we change the visible variable to true - component
PostCode
rendered on screen only when visible variable is true
3.4. Passing the address $emit(..)
in the child component PostCode.vue
, we are printing the selected address to the console.
PostCode.vueexport default {
mounted() {
console.log("[SHOULD NOT NULL]", this.$refs.postarea);
new window.daum.Postcode({
oncomplete: (data) => {
console.log("[Selected address]", data);
},
}).embed(this.$refs.postarea);
},
};
create an event to pass the address the user clicked to the parent component, PostCodeApp.vue
.
PostCode.vueexport default {
mounted() {
console.log("[SHOULD NOT NULL]", this.$refs.postarea);
new window.daum.Postcode({
oncomplete: (data) => {
// console.log("[selected address]", data); (-)
this.$emit("address", data); // (+)
},
}).embed(this.$refs.postarea);
},
};
- we've defined the event name as
adress
. $emit('eventname', 'value to pass')
- The first argument is the eventname, and the second argument is the value to pass to the parent component.
to catch the address event thrown by the child component PostCode.vue
, the parent component defines a listener as shown below.
PostCode.vue<template> <div class="postcode-demo
<div class="postcode-demo">
<button @click="showPopup()">Test button</button>
<PostCode v-if="visible" @address="addrSelected"/> <!-- (1) Connect the listener -->
</div>
</template>
<script>
import PostCode from "./components/PostCode.vue";
export default {
components: {
PostCode,
},
data() {
return {
visible: false
};
},
methods: {
showPopup() {
// Changing visible to true will render the PostCode component
this.visible = true
},
addrSelected(detail) { // (2) check the address
console.log("Selected address", detail);
this.visible = false; // (3) Remove the component
},
},
};
</script>
- @address="addrSelected" - attaches the method
addrSelected
to handle the eventaddress
- addrSelected(..) - The second argument data of the code
this.$emit("address", data);
that we deployed when raising the event inPostCode.vue
is passed to the first argument detail of the listeneraddrSelected
. - this.visible = false - Remove
PostCode.vue
from the parent component as well, since the window closes when an address is selected in the address search bar.
3.5. styling
if you want to configure PostCode.vue
as a layer popup, style it like below.
PostCode.vue<template> <div class="postcode-wrap
<div class="postcode-wrapper"> <!
<!-- (1) Paste class "body" -->
<div ref="postarea" class="body"></div>
</div>
</template>
<script> </script
export default {
mounted() {
new window.daum.Postcode({
width: "100%", // (2) Specify 100% width
oncomplete: (data) => {
this.$emit("address", data); // emit to parent
},
}).embed(this.$refs.postarea);
},
};
</script> </script
<style
.postcode-wrapper {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #0000004d;
}
.postcode-wrapper .body {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: calc(100% - 20px);
max-width: 500px;
}
</style>
- fill the entire area of the
.postcode-wrapper
with fixed. specify a slightly opaque background color (#0000004d) - make the address bar 100% wide when it appears.
- make the
.body
that wraps the address bar no more than 500px wide (on large screens). on smaller screens, allow 10px left and right margins (calc(100% - 20px)
)
4. Result
index.html<!DOCTYPE html>
<html lang=""><!
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<link rel="icon" href="<%= BASE_URL %>favicon.ico" />
<title><%= htmlWebpackPlugin.options.title %></title>
<script src="//t1.daumcdn.net/mapjsapi/bundle/postcode/prod/postcode.v2.js"></script>
</head>
<body> <noscript>
<noscript>
<strong
>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work
properly without JavaScript enabled. Please enable it to
continue.</strong
>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
main.jsimport Vue from "vue";
import PostCodeApp from "./PostCodeApp.vue";
Vue.config.productionTip = false;
new Vue({
render: (h) => h(PostCodeApp),
}).$mount("#app");
PostCodeApp.vue<template> <div class="postcode-demo
<div class="postcode-demo"> <div class="postcode-demo">
<button @click="showPopup()">Test button</button>
<PostCode v-if="visible" @address="addrSelected" />
<!-- (1) Connect the listener -->
</div>
</template>
<script>
import PostCode from "./components/PostCode.vue";
export default {
components: {
PostCode,
},
data() {
return {
visible: false, // (+) false, start PostCode invisible
};
},
methods: {
showPopup() {
// Changing visible to true will render the PostCode component
this.visible = true;
},
addrSelected(detail) {
console.log("Selected address", detail);
this.visible = false;
},
},
};
</script>
PostCode.vue<template> <div class="postcode-wrapper
<div class="postcode-wrapper">
<div ref="postarea" class="body"></div>
</div>
</template>
<script> </script
export default {
mounted() {
console.log("[SHOULD NOT NULL]", this.$refs.postarea);
new window.daum.Postcode({
width: "100%",
oncomplete: (data) => {
// context problem this!
this.$emit("address", data); // emit to parent
// console.log("[address]", data);
},
}).embed(this.$refs.postarea);
},
};
</script>
<style
.postcode-wrapper {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #0000004d;
}
.postcode-wrapper .body {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: calc(100% - 20px);
max-width: 500px;
}
</style>