概要
wsl(wsl2じゃない)で、elixirやってみた。
練習問題、やってみた。
練習問題
Phoenixで、vueでspaを実装せよ。
方針
api使う。
axios使う。
vuetify使う。
写真
手順
- lib/hello2_web/templates/layout/root.html.heexを修正
<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"/>
<meta name="csrf-token" content={csrf_token_value()}>
<%= live_title_tag assigns[:page_title] || "Hello2", suffix: " 揃 Phoenix Framework" %>
<link rel="stylesheet" href="//fonts.googleapis.com/css?family=Roboto:300,400,500,700|Material+Icons">
<link rel="stylesheet" href="//unpkg.com/vuetify@1.5.18/dist/vuetify.min.css">
<link rel="stylesheet" href="//cdn.materialdesignicons.com/3.5.95/css/materialdesignicons.min.css">
<script src="//cdn.jsdelivr.net/npm/vue@2.x/dist/vue.js"></script>
<script src="//unpkg.com/vuetify@1.5.18/dist/vuetify.min.js"></script>
<script src="//unpkg.com/axios/dist/axios.min.js"></script>
</head>
- lib/hello2_web/templates/page/index.html.heexを修正
<section class="phx-hero">
<h1><%= gettext "Welcome to %{name}!", name: "Phoenix" %></h1>
<v-app id="app">
<v-container>
<v-row>
<v-col cols="10">
<v-toolbar flat color="white">
<v-toolbar-title>Phoenix</v-toolbar-title>
<v-divider class="mx-2" inset vertical ></v-divider>
<v-spacer></v-spacer>
<v-dialog v-model="dialog" max-width="500px">
<template v-slot:activator="{ on }">
<v-btn color="primary" dark class="mb-2" v-on="on">New Item</v-btn>
</template>
<v-card>
<v-card-title>
<span class="headline">{{ formTitle }}</span>
</v-card-title>
<v-card-text>
<v-container grid-list-md>
<v-layout wrap>
<v-flex xs12 sm6 md4>
<v-text-field v-model="editedItem.title" label="title"></v-text-field>
</v-flex>
<v-flex xs12 sm6 md4>
<v-text-field v-model="editedItem.link" label="link"></v-text-field>
</v-flex>
</v-layout>
</v-container>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="blue darken-1" flat @click="close">Cancel</v-btn>
<v-btn color="blue darken-1" flat @click="save">Save</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</v-toolbar>
<v-data-table :headers="headers" :items="serverDatas">
<template slot="items" slot-scope="props">
<td class="text-xs-left">{{ props.item.id }}</td>
<td class="text-xs-left">{{ props.item.title }}</td>
<td class="text-xs-left">{{ props.item.link }}</td>
<td class="justify-center layout px-0">
<v-btn small color="aqua" @click="editItem(props.item)">
edit
</v-btn>
<v-btn small color="error" @click="deleteItem(props.item)">
delete
</v-btn>
</td>
</template>
</v-data-table>
</v-col>
</v-row>
</v-container>
</v-app>
<script>
new Vue({
el: "#app",
data() {
return {
dialog: false,
isCreate: true,
editedItem: {
id: 0,
title: '',
link: ''
},
headers: [{
text: 'ID',
value: 'id'
}, {
text: 'title',
value: 'title',
}, {
text: 'link',
value: 'link'
}, {
text: 'edit/delete',
value: 'delete',
sortable: false
}],
serverDatas: [],
}
},
computed: {
formTitle() {
return this.isCreate ? 'New Item' : 'Edit Item'
}
},
watch: {
dialog(val) {
val || this.close()
}
},
methods: {
deleteItem(item) {
confirm('delete ok') && this.deleteUser(item)
},
editItem(item) {
this.isCreate = false
this.editedItem = item
this.dialog = true
},
close() {
this.dialog = false
},
save() {
if (!this.isCreate)
{
this.update()
}
else
{
this.create()
}
this.dialog = false
},
update() {
alert("update")
axios.patch('http://localhost:4000/api/urls/' + this.editedItem.id, {
title: this.editedItem.title,
link: this.editedItem.link
}).then(response => this.users.unshift(response.data)).catch(error => conalert(error))
},
create() {
alert("create")
axios.post('http://localhost:4000/api/urls', {
title: this.editedItem.title,
link: this.editedItem.link
}).then(response => this.serverDatas.unshift(response.data)).catch(error => alert(error))
},
deleteUser(item) {
axios.delete('http://localhost:4000/api/urls/' + item.id).then(response => console.log(response)).catch(error => alert(error))
const index = this.serverDatas.indexOf(item)
this.serverDatas.splice(index, 1)
},
},
created() {
axios.get('http://localhost:4000/api/urls').then(res => {
this.serverDatas = res.data.data
}).catch(e => {
alert(e)
}).finally(() => {
//alert("ok")
})
}
})
</script>
<p>Peace of mind from prototype to production</p>
</section>
以上