Vueプロジェクトの作成とバックエンド連携方法

Vueプロジェクトの作成

jingxi_shop_projectフォルダ内にfrontendフォルダを作成し、フロントエンドプロジェクトを格納します。

/jingxi_shop_project
    /backend
        /jingxi_shop_project
        	......
    /frontend
        /jingxi_shop_web
        	......

まずnode.jsとVue CLIをインストールし、プロジェクトディレクトリ内でプロジェクトを作成します。

vue create jingxi_shop_webコマンドを実行し、このプロジェクトではVue3、Router、Vuex、CSS Pre-processorsを基本設定として選択しました。

プロジェクトリソースの準備

まずsrcディレクトリ(通常の開発はsrcディレクトリで行います)

CSS

src配下のassetsディレクトリにcssフォルダを作成し、CSSの基本設定を格納します(CSSスタイルコードは直接利用可能です)

assets/css/base.js:

@charset "utf-8"
@import "./base/.css";

/* グローバルリセットと基本スタイル */
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed, 
figure, figcaption, footer, header, hgroup, 
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
  margin: 0;
  padding: 0;
  outline: none;
}

* {
  margin: 0;
  padding: 0;
  outline: none;
}

body {
  font-size: 12px !important;
  font-family: '微软雅黑', Helvetica, Arial, sans-serif, '宋体', Verdana;
  background-color: #fff;
  color: #333;
}

li{
	list-style: none;
}

img{
	border: 0 none;
	vertical-align: middle;
}

a {
  color: #333;
  text-decoration: none !important;
  outline: none;
  cursor: pointer;
}

a:focus{
	outline: none;
}

.clearfix::after{
	visibility: hidden;
	clear: both;
	height: 0px;
	display: block;
	content: "";
}

input{
	vertical-align: middle;
	border: none;
	background-color: none;
}

select{
	vertical-align: middle;
	border: none;
	background-color: none;
}

button{
	text-align: center;
	border: 0;
	cursor: pointer;
}

h1,
h2,
h3,
h4,
h5,
h6 {
	font-weight: normal;
	font-size: 12px;
}

textarea,
input {
	word-wrap: break-word;
	word-break: break-all;
	padding: 0px;
	background: none;
}

label{
	cursor: pointer;
}

input[type="button"]::-moz-focus-inner,
input[type="submit"]::-moz-focus-inner{
	border: none;
}

input[type="button"],
input[type="submit"]{
	cursor: pointer;
}

input:focus {
	outline: none;
}

.fl{
	float: left;
}

.fr{
	float: right;
}

.cs{
	cursor: pointer;
}

/* 1行を超える内容は...に変換 */
.dian1{
	text-overflow: -o-ellipsis-lastline;
	overflow: hidden;
	text-overflow: ellipsis;
	display: -webkit-box;
	-webkit-line-clamp: 1;
	-webkit-box-orient: vertical;
}

/* 2行を超える内容は...に変換 */
.dian2{
	text-overflow: -o-ellipsis-lastline;
	overflow: hidden;
	text-overflow: ellipsis;
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
}

/* 3行を超える内容は...に変換 */
.dian3{
	text-overflow: -o-ellipsis-lastline;
	overflow: hidden;
	text-overflow: ellipsis;
	display: -webkit-box;
	-webkit-line-clamp: 3;
	-webkit-box-orient: vertical;
}

assets/css/config.js:

@import './base.css';

/* グローバル変数の定義 */

:root {
    --font-red: #ef0115;
    --font-gray: #999;
    --content-width: 1200px;
	--el-color-danger: #e2231a !important;
}

iconfont

Iconfontは、アイコンをフォント形式でウェブページに埋め込む技術です。開発者は簡単なCSSクラスでアイコンを利用・制御でき、プラットフォーム間の一貫性、拡張性、スタイルの一貫性を提供します。同時にHTTPリクエストとアイコンファイルのサイズを削減し、ウェブパフォーマンスと開発効率を最適化します。

iconfont公式サイトで必要なアイコンスタイルを選択し、プロジェクトにダウンロードして使用できます。

element-Plus

今後element-Plusも使用するため、事前にインストールします:npm install element-Plus

main.jsへのインポート

main.jsエントリーファイルに先ほどダウンロードしたリソースをインポートすることで、プロジェクト内で使用できるようになります。

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
// CSSスタイルのインポート
import '@/assets/css/config.css'
// iconfontスタイルのインポート
import '@/iconfont/iconfont.css'
// ElementPlusのインポート
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'

createApp(App).use(store).use(router).use(ElementPlus).mount('#app')

フロントエンドとバックエンドの連携

srcディレクトリ下にnetworkフォルダを作成し、ネットワークリクエストを処理します。

axiosリクエストを2つのファイルに分割してパッケージ化できます。共通部分をaxiosの基本設定(ベースURL、タイムアウト、リクエストとレスポンスインターセプターなど)としてパッケージ化し、実際のリクエスト関数を含むファイルを定義します。

src/network/requestConfig.js:

import axios from 'axios';

export function apiRequest(config){
	const service = axios.create({
		baseURL: "http://localhost:8000",
		timeout: 5000
	})
	
	// リクエストインターセプター
	service.interceptors.request.use(config=>{
		console.log('リクエスト送信中:', config.url);
		return config;
	}, error=>{
		console.error('リクエストエラー:', error);
	})
	
	// レスポンスインターセプター
	service.interceptors.response.use(response=>{
		console.log('レスポンス受信:', response.config.url);
		return response.data ? response.data : response;
	}, error=>{
		console.error('レスポンスエラー:', error);
	})
	
	return service(config);
}

src/network/home.js:

import { apiRequest } from './requestConfig.js'

export function fetchMainMenu(){
	return apiRequest({
		url: "/menu/main_menu",
		method: "GET"
	})
}

フロントエンドとバックエンドの接続確認

ページコンポーネントで上記でパッケージ化したリクエスト関数を呼び出します。

<script setup>
	import { fetchMainMenu } from "@/network/home.js"
	import { onMounted, ref } from "vue"
	const leftMenuData = ref([])
	
	onMounted(()=>{
		fetchMainMenu().then(response=>{
			console.log(response);
		}).catch(error=>{
			console.error('データ取得エラー:', error);
		})
	})
</script>

クロスドメイン問題の解決

Access to XMLHttpRequest at 'http://localhost:8000/menu/main_menu/' (redirected from 'http://localhost:8000/menu/main_menu') from origin 'http://localhost:8080' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

この時点でフロントエンドとバックエンドを実行すると、コンソールにクロスドメイン問題が表示されます。これはポート番号が異なるためリクエストが失敗したためです。バックエンドプロジェクトのsettings.pyでCORSを設定し、異なるソース(ドメイン、プロトコル、ポート)からのウェブページがサーバーリソースにアクセスできるようにする必要があります。

  1. django-cors-headerをインストール
  2. INSTALLED_APPSに'corsheaders'を追加
  3. MIDDLEWAREに'corsheaders.middleware.CorsMiddleware'を追加
  4. settingsの下部で異なるソースからのアクセスを許可する設定を追加
settings.py
...
ALLOWED_HOSTS = ['*']
CORS_ALLOW_CREDENTIALS = True
CORS_ALLOW_ALL_ORIGINS = True
CORS_ALLOW_HEADERS = ('*')

これでコンソールにバックエンドのデータが正常に表示されます。

ソースコードリポジトリ

https://gitee.com/duan-peitong/jignxi_shop_project

タグ: Vue3 Axios ElementPlus CORS Django

5月22日 06:20 投稿