1. 程式人生 > 實用技巧 >laravel vue 專案結構搭建

laravel vue 專案結構搭建

laravel vue 專案結構搭建

0、簡介

剛接觸vue,本篇只是初步搭建 laravel + vue 專案結構和處理了 vue 路由定義的問題,僅達到了能夠顯示輸入url 能顯示vue頁面的功能而已,希望後續學習,能搭建一個完整的 laravel + vue 專案,未完待續...

1、安裝laravel

composer create-project --prefer-dist laravel/laravel blog "5.6.*"

2、npm 安裝 yarn

//安裝yarn
npm install -g yarn --registry=https://registry.npm.taobao.org

//配置源
yarn config set registry https://registry.npm.taobao.org -g
yarn config set sass_binary_site http://cdn.npm.taobao.org/dist/node-sass -g

3、yarn install

4、修改 webpack.mix.js

let mix = require('laravel-mix');

//const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;

mix.js('resources/assets/js/home.js', 'public/backend/js').version().webpackConfig({
    plugins: [
        //new BundleAnalyzerPlugin()
    ],
    output: {
        chunkFilename: 'backend/js/chunk/[name].js?v=[chunkHash]'
    },
    resolve: {
        alias: {
            Helper: path.resolve(__dirname, 'resources/assets/js/helper'),
            Css: path.resolve(__dirname, 'resources/assets/css'),
            Sass: path.resolve(__dirname, 'resources/assets/sass'),
            components: path.resolve(__dirname, 'resources/assets/js/views/home/components')
        }
    },
    externals: {
        'element-ui': 'ELEMENT',
        'axios': 'axios',
        'vue': 'Vue',
        'vue-router': 'VueRouter',
        'lodash': '_'
    }
});

5、刪除目錄和檔案

app/Http/Controllers/Auth
resources/assets/js/components

resources/assets/js/app.js
resources/views/welcome.blade.php

6、新建vue目錄和檔案

home.http.js

import axios from 'axios';
//import { backendApi } from '../config/backend/config';
//import { notificationError } from './helps';

/**
 * Create Axios
 */
export const http = axios.create();

/**
 * We'll load the axios HTTP library which allows us to easily issue requests
 * to our Laravel back-end. This library automatically handles sending the
 * CSRF token as a header based on the value of the "XSRF" token cookie.
 */
http.defaults.headers.common = {
    'X-CSRF-TOKEN': window.csrf_token,
    'X-Requested-With': 'XMLHttpRequest'
};

http.interceptors.request.use(function (config) {
    if (config.url.indexOf('components') === -1) {
        config.url = '/home-api' + config.url;
    }
    if (config.method === 'post') {
        if (!config.data) {
            config.data = {};
        }
        config.data.sid = window.sid
    } else if (config.method === 'get') {
        if (!config.params) {
            config.params = {};
        }
        config.params.sid = window.sid
    }
    return config;
}, function (error) {
    return Promise.reject(error);
});

/**
 * Handle all error messages.
 */
http.interceptors.response.use(function (response) {
    if (response.data.code === -1) {
        window.location = '/home';
    } else {
        return response;
    }
}, function (error) {
    const {response} = error;

    if ([401].indexOf(response.status) >= 0) {
        if (response.status === 401 && response.data.error.message !== 'Unauthorized') {
            return Promise.reject(response);
        }
        window.location = '/home';
    }

    /*if([422].indexOf(response.status) >= 0){
        let message = response.message;
        for(var i in response.data.errors){
            message = response.data.errors[i][0];
        }
        notificationError(message);
    }*/

    return Promise.reject(error);
});

export default function install(Vue) {
    Object.defineProperty(Vue.prototype, '$http', {
        get() {
            return http
        }
    })
}

article.js

export default [
    {
      path: '/home/article',
        component: require('../views/home/article/List')
    }
];

article/List.vue

<template>
    <el-row>
        <span>this is article-list !!!</span>
    </el-row>
</template>

Aside.vue

<template>
    <el-row class="main">
       <span>this is aside !!!</span>
    </el-row>
</template>

Index.vue

<template>
    <el-row class="main">
        <span>this is index !!!</span>
    </el-row>
</template>

Main.vue

<template>
    <el-container class="is-vertical">
        <Header v-bind:message_id="id"></Header>
        <el-container>
            <Aside></Aside>
            <el-main :style="{minHeight: innerHeight + 'px'}">
                <router-view v-on:call="pageData"></router-view>
            </el-main>
        </el-container>
    </el-container>
</template>

<script type="text/ecmascript-6">
    export default{
    }
</script>
<style>

</style>

App.vue

<template>
    <router-view></router-view>
</template>

home.js

require('./bootstrap');

window.Vue = require('vue');

import httpPlugin from './helper/home.http';

//vue 路由
import VueRouter  from 'vue-router';
import routes from './home.routes';

const originalPush = VueRouter.prototype.push;
VueRouter.prototype.push = function push(location) {
    return originalPush.call(this, location).catch(err => err)
};

//element元件
import ElementUI from 'element-ui';

import App from './App.vue';

Vue.use(VueRouter);
Vue.use(ElementUI);
Vue.use(httpPlugin);

//路由
const router = new VueRouter({
    mode: 'history',
    base: __dirname,
    linkActiveClass: 'active',
    routes: routes
});


const app = new Vue({
    router,
    render: h => h(App)
}).$mount('#app');

home.routes.js

import article from './router/article';


export default [
    {
        path: '/home',
        component: require('./views/home/Main'),
        beforeEnter: requireAuth,
        onError: (err) => {
            console.log(err);
        },
        children: [
            {
                path: '/',
                component: require('./views/home/Index')
            },
            ...article,
        ]
    }
]


//是否登陸
function requireAuth (to, from, next) {
    console.log(from);
    console.log(to);
    //if (window.User) {
    return next();
    //}else{
    //    return next('/')
    //}
}

7、php

routes/web.php

<?php

Route::get('{path?}', 'Home\HomeController@home')->where('path', '[\/\w\.-]*');

app/Http/Controllers/Home/HomeController.php

<?php

namespace App\Http\Controllers\Home;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class HomeController extends Controller
{
    public function home(Request $request)
    {
        $params = [
            'path' => '/' . $request->path()
        ];
        return view('home/index', $params);
    }
}

resources/views/home/index.blade.php

<!doctype html>
<html lang="{{ app()->getLocale() }}">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="csrf-token" content="{{ csrf_token() }}">
    <title>test</title>
    <script>
        window.csrf_token = '{{csrf_token () }}';

        window.default_path = '{{$path}}';
    </script>
</head>
<body>
<div id="app"></div>

<script src="{{ mix('backend/js/home.js') }}"></script>

</body>
</html>

8、打包

npm run dev

9、說明

webpack.mix.js:

定義了主檔案路徑,以及編譯後的js檔案路徑
    'resources/assets/js/home.js', 'public/backend/js'

resources/assets/js/home.js

  //引入
  resources/assets/js/helper/home.http.js - 請求幫助類檔案
  resources/assets/js/home.routes.js - 路由定義檔案
  resources/assets/js/App.vue - vue入口檔案

resources/assets/js/home.routes.js

引入
resources/assets/js/views/home/Main.vue - 框架
resources/assets/js/views/home/Index.vue - 首頁

引入路由
resources/assets/js/router

routes/web.php

Route::get('{path?}', 'Home\HomeController@home')->where('path', '[\/\w\.-]*');
//路由重定向

app/Http/Controllers/Home/HomeController.php - home()

//載入頁面 - resources/views/home/index.blade.php

resources/views/home/index.blade.php

載入打包後的vue - backend/js/home.js