前回の下記の記事を参考にして、記事を書いていきます。
ディレクトリ構成
.
└── NuxtDjangoProject/
├── backend/
│ ├── adminuser
│ ├── api/
│ │ ├── migrations/
│ │ │ └── 0001_initial.py
│ │ ├── serializer.py
│ │ ├── urls.py
│ │ └── views.py
│ └── todoproject/
│ ├── settings.py
│ └── urls.py
└── frontend/
├── components/
│ ├── footer/
│ │ └── footer.vue
│ └── navbar/
│ └── navbar.vue
├── pages/
│ ├── adminUsers/
│ │ ├── login/
│ │ │ └── login.vue
│ │ ├── registration/
│ │ │ └── registration.vue
│ │ ├── updateProfile/
│ │ │ └── updateProfile.vue
│ │ └── uploadImageFile/
│ │ └── uploadImageFile.vue
│ ├── login/
│ │ └── login.vue
│ ├── registration/
│ │ └── registration.vue
│ └── index.vue
├── .env
├── server/
│ └── uploadthing.ts
├── app.vue
├── nuxtconfig.ts/
│ └── package.json
└── tsxconfig.json
URLクエリ文字列の値を取得する方法
Nuxt 3でURLクエリ文字列からパラメータを取得する方法は、Vue Router
を利用して簡単に実現できます。useRoute
というフックを使用して、現在のルートに関連する情報を取得することができます。
具体的には、$route.query
ではなく、useRoute
を使って、クエリパラメータを取得します。
useRoute
を使ってURLクエリ文字列を取得する方法
Nuxt 3では、useRoute
フックを使って、現在のルート情報(パス、クエリパラメータなど)を簡単に取得できます。
例: クエリパラメータを取得する
<script setup lang="ts">
import { useRoute } from 'vue-router'
const route = useRoute()
const imageUrl = route.query.image as string // クエリパラメータ 'image' を取得
</script>
<template>
<v-app>
<!-- 画像URLを表示 -->
<img :src="imageUrl" alt="Image from query"/>
<p>Image URL: {{ imageUrl }}</p>
</v-app>
</template>
コードの解説
useRouteフック
useRouteは、現在のルート情報を提供します。これを使ってクエリパラメータを取得できます。
route.query
route.queryは、クエリパラメータをオブジェクト形式で取得します。例えば、URLがhttp://localhost:3000/?image=https://example.com/path/to/image.jpg
の場合、route.query.imageで"https://example.com/path/to/image.jpg"
というURLを取得できます。
as string
TypeScriptを使っている場合、route.query.imageの型はstring | undefinedなので、as stringで型キャストして、imageUrlに格納しています。もしクエリパラメータがない場合、undefinedになることを考慮して、適切なエラーハンドリングを追加することができます。
クエリパラメータがない場合の処理
クエリパラメータが存在しない場合に備えて、デフォルト値を設定することもできます。
<script setup lang="ts">
import { useRoute } from 'vue-router'
const route = useRoute()
const imageUrl = route.query.image as string | undefined || 'default_image_url.jpg' // デフォルト値を設定
</script>
<template>
<v-app>
<!-- クエリパラメータがなければデフォルト画像を表示 -->
<img :src="imageUrl" alt="Image from query"/>
<p>Image URL: {{ imageUrl }}</p>
</v-app>
</template>
URLクエリパラメータが変更されたときに自動で反映する
クエリパラメータが変更されるたびに自動で更新されるようにするには、watch
を使って監視することもできます。
例えば、image
パラメータが変更されたときに新しいURLを取得する場合は次のように書けます。
<script setup lang="ts">
import { useRoute } from 'vue-router'
import { watch } from 'vue'
const route = useRoute()
let imageUrl = route.query.image as string | undefined
// クエリパラメータが変わるたびにimageUrlを更新
watch(() => route.query.image, (newValue) => {
imageUrl = newValue as string | undefined
})
</script>
<template>
<v-app>
<img :src="imageUrl" alt="Image from query"/>
<p>Image URL: {{ imageUrl }}</p>
</v-app>
</template>
ちなみに、UIフレームワークVuetify
を使うと下記のように書けます。
<script setup lang="ts">
import { useRoute } from 'vue-router'
import { watch } from 'vue'
import { ref } from 'vue';
import axios from 'axios';
const formRef = ref(null);
const route = useRoute();
let imageUrl = route.query.image as string | undefined
// クエリパラメータが変わるたびにimageUrlを更新
watch(() => route.query.image, (newValue) => {
imageUrl = newValue as string | undefined
})
const onSubmit = async()=>{
try{
const formData = new FormData();
//ユーザIDや、E-mailも追加する。
formData.append('image',Image.value);
const response = await axios.post('http://localhost:8000/adminuser/',formData);
if(response.request.status === 200){
alert('Success to update iamge.');
console.log(response.data);
}
}catch(error){
alert('Fail to upload image.');
console.log('Faile to upload image:',error);
}
}
</script>
<template>
<v-app>
<v-main>
<v-form @submit.prevent="onSubmit" ref="formRef">
<img
:src="imageUrl"
alt="Image from query"
width="200px"
/>
<v-img
v-model="image"
:width="300"
aspect-ratio="16/9"
cover
:src="imageUrl"
></v-img>
<v-item-group>
<v-btn
type="button"
color="success"
class="mr-4"
@click="$router.push('/adminUsers/uploadImageFile/uploadImageFile')">
Back to PrePage
</v-btn>
<v-btn
type="submit"
color="primary"
@click="aa">
Update Image
</v-btn>
</v-item-group>
</v-form>
</v-main>
</v-app>
</template>
以上です。
サイト