雖然前面可能已經提過 但現在要同樣的東西搬到專案裡面
一個好的代碼架構 是可以經得起ctrl+C與ctrl+V的考驗這就是我抄隔壁同學作業的理由
一些自以常用的css 改成用scss寫
路徑: 專案/resources/sass
_variables.scss 引入scss常用參數
當然也可以在這裡overwrite顏色
// Body
$body-bg: #f8fafc;
$primary: #4b5563;
$danger: #dc3545;
$info:#5899b9;
例如 body的底色, 文字基本屬性
共用的class或標籤 可以統一管理
如果沒有可以跳過此步驟
路徑: 專案/resources/sass/app.scss
基於遠本的預設 我們多import 自訂的theme 來管理style
// Fonts
@import url('https://fonts.bunny.net/css?family=Nunito');
// Variables
@import 'variables';
// Theme
@import 'theme.scss';
// Bootstrap
@import 'bootstrap/scss/bootstrap';
新增檔案 路徑: 專案/resources/sass/theme.scss
之後共用的class或標籤style都可以統一寫在這裡
這部分的解法非常多我們可以用
我們用Larael處理參數
比較嚴謹的方式是先建立處理參數的php檔案,然後再讓Laravel幫我們引用處理
新建檔案(也可沿用已有參數檔案)
兩步驟
一、專案/.env 建立對應參數
我定義 環境常數 "MY_DEFINED_DATA" 他的值是 'qwer'。
...略
MY_DEFINED_DATA='qwer'
二、專案/config/frontend.php 定義引用
<?php
return [
//此行為備註 '參數名稱' => env('env內紀錄參數名','forge')
my_defined_data => env('MY_DEFINED_DATA','forge'),
];
之後引用就
{config('定義參數的檔案.參數名稱','預設值(option)')}
之後引用就{config('frontend.my_defined_data')}
但這個語法跟我們react引用太容易搞混,所以我們在jsx通常不太用
但是在app.blade.php (等同於react專案 public底下的index.html)
可以用來載入頁面基本名稱
另外補充
在js檔直接引用.env 會需要呼叫 "${import.meta.env"
const API_URL = `${import.meta.env.VITE_API_BASE_URL}/api`;//這裡我直接引用.env檔的值
我不太確定這是vite node interia誰家的語法
這方法我自己覺得很方便,不過受限於公司coding規範,不是每次都能過codereview
三步驟:
一、新建目錄Constant與檔案consts.js
專案/resources/Constant/consts.js
import { createContext, useContext, useState } from "react";
import { router } from '@inertiajs/react';
/*引用區塊*/
const StateContext = createContext({
user: null,
token: null,
notification: null,
setUser: () => { },
setToken: () => { },
setNotification: () => { },
setLoading: () => { }
env_data:'常數數值' //定義一個常數叫做'env_data'他的值是'常數數值'
});
/*引用區塊 end*/
export const ContextProvider = ({ children }) => {
const [user, _setUser] = useState(localStorage.getItem('user') ? JSON.parse(localStorage.getItem('user')) : {});
const [token, _setToken] = useState(localStorage.getItem('ACCESS_TOKEN'));
const [notification, _setNotification] = useState('');
const [isLoading, _setLoading] = useState(true);
const setUser = (user) => {
if (user && typeof user==='object' && user['id']) {
_setUser(user);
localStorage.setItem('user', JSON.stringify(user));
} else if(user === 'logout'){
_setUser(null);
localStorage.removeItem('user');
setToken(null);
return router.visit('/')
}else{
_setUser(null);
localStorage.removeItem('user');
setToken(null);
return router.visit('/login', {
onFinish: () => setNotification('登入逾期失效')
})
}
}
const setToken = (token) => {
if (token) {
_setToken(token);
localStorage.setItem('ACCESS_TOKEN', token);
} else {
_setToken(null);
localStorage.removeItem('ACCESS_TOKEN');
}
}
const setNotification = (message) => {
_setNotification(message);
setTimeout(() => {
_setNotification('');
}, 5000)
}
const setLoading = (isLoading) => {
if (isLoading) {
_setLoading(true);
} else {
_setLoading(false);
}
}
return (
<StateContext.Provider value={{
user,
setUser,
token,
setToken,
notification,
setNotification,
setLoading
}}>
{isLoading &&
<div id="loading" className="d-flex justify-content-center align-items-center">
<div className="spinner-border text-primary" role="status">
<span className="visually-hidden">Loading...</span>
</div>
</div>
}
{notification && <div className="alert alert-box alert-success">{notification}</div>}
{children}
</StateContext.Provider>
)
}
export const userStateContext = () => useContext(StateContext)
二、引用該檔案至全域
專案/resources/app.jsx
...
import { ContextProvider } from './Constant/ContextProvider';
/*註 import要放在開頭區塊,不要放在中間才引用然後說沒用,謝謝*/
...
...
/*用ContestProvider 包住底下的 App*/
<ContextProvider>
<App {...props} />
</ContextProvider>
...
三、各別檔案使用方法
要使用環境參數的頁面 某個.jsx
開頭import userStateContext
然後在function裡面引用
...
import { userStateContext } from "@/Constant/ContextProvider";
... function ...{
//可以挑選 引用區塊內的任何函數或環境參數
const { env_data } = userStateContext()
...
我通常是在API文件使用,因為像是header常常是固定的開頭
新建檔案
一、新建目錄API與檔案consts.js
專案/resources/API/consts.js
import axios from 'axios';
export const getHeaders = (isUseToken = true) => {
//我的api不是每支都要用token 會寫篩選動作
var token = '';
if (isUseToken) {
try {
token = localStorage.getItem('ACCESS_TOKEN');
//這是基於我的專案資料放在localStorage,你的放在哪就去哪裡抓
if (!token) {
token = ''
}
} catch (e) {
token = '';
}
}
return {
'Content-Type': 'application/json;chartset=utf-8',
'Access-Control-Allow-Origin': '*',
'Accept': 'application/json',
//'Accept-Encoding':"gzip, deflate, br",
'Authorization': isUseToken ? `bearer ${token}` : null, //我的案件是用bearerToken
}
}
const API_URL = `${import.meta.env.VITE_API_BASE_URL}/api`;//這裡我直接引用.env檔的值
const baseRequest = axios.create({
baseURL: API_URL,
timeout: 10000
});
//登入
export const API_POST_Login = data => baseRequest.post('/login', JSON.stringify(data), { data: data, headers: getHeaders(false) });
各別.jsx檔案引用
import { API_POST_Login } from "@/API/constants";
//直接當作function使用
API_POST_Login(連線body)
//這裡可以用axios promise接收語法替換掉 看你的需求
.then((response)=>{
//成功
}).catch(err=>{
//失敗
}).finally(()=>{
//不論如何都要
})
這邊還有一點可以優化的是"ACCESS_TOKEN"本身也要改成用環境名稱引用。
你如果專案是保持預設,原本是引用bootstrap.js檔案去處理axios,我覺得命名跟我用的bootsrap套件重複命名,所以就不用他,所以新建檔案複製其功能