Laravel Vue Admin - #1 Admin panel Setup

首先,用到了laravel ui扩展包 及基础的 vue 脚手架:

执行:

composer require laravel/ui

批注 2020-04-18 213106

执行:

php artisan ui vue --auth

批注 2020-04-18 213144

执行:

npm install & npm run watch

批注 2020-04-18 213240

介绍一下Laravel Permission 扩展包:

A package to add roles and permissions to Laravel

https://github.com/spatie/laravel-permission

因为自Laravel 5.1.1版本开始就提供了很不错的授权功能,用起来比较简洁,检查用户是否有操作的权限也是超级简单。这个Laravel Permission扩展包就是以Jeffrey's code  为基础,发展起来的,可以很方便的给用户授予角色,权限。

参考:https://docs.spatie.be/laravel-permission/v3/introduction/

// Adding permissions to a user
$user->givePermissionTo('edit articles');

// Adding permissions via a role
$user->assignRole('writer');

$role->givePermissionTo('edit articles');

 前言

由于这个扩展包提供所有的权限都是注册于Laravel Gate之上。

只要你的User模型类实现了 Illuminate\Contracts\Auth\Access\Authorizable【这个是默认的Illuminate\Foundation\Auth\User中实现了的】,那么默认提供的can方法也是可以使用的:

$user->can('edit articles');

blade中也可以使用:

@can('edit articles')
...
@endcan

记得User模型类中需要使用HasRoles这个trait来实现扩展包的功能。

所以至少你的User模型类应该有这个:

use Illuminate\Foundation\Auth\User as Authenticatable;
use Spatie\Permission\Traits\HasRoles;

class User extends Authenticatable
{
    use HasRoles;

    // ...
}

另外,你的User模型不能有role或者roles属性以及roles()方法,且数据库中也不能有这两个字段。

因为HasRoles trait已经提供了,否则你重写的方法可能造成不当的结果。

同样,你的User模型类也不能有permission或者permissions属性或者permissions()方法,数据库中也不能有这两个字段。

因为HasRoles trait中的 HasPermissions trait已经提供了。

这个安装包会生成config/permission.php文件。如果你有一个自建文件和这个文件同名,那移动到其他位置或者重命名一下,否则会冲突。视个人的需要也可以添加自己的方法到里面。

安装

执行:

composer require spatie/laravel-permission

批注 2020-04-18 213313

config/app.php修改如下:

'providers' => [
    // ...
    Spatie\Permission\PermissionServiceProvider::class,
];

批注 2020-04-18 213721

然后执行:

php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider"

批注 2020-04-18 213807

生成了permission.php文件,以及一个create_permission_tables.php文件:

批注 2020-04-18 213908

如果需要UUID请看:UUID

执行migrate之前确保env中DB_DATABASE设置正确,否则会报错:

批注 2020-04-18 214813

我的database是vue

所以:

批注 2020-04-18 214647


然后执行:

php artisan migrate

批注 2020-04-18 214716

最后,按照前言中的要求,修改User模型类。

批注 2020-04-18 215120

Vuetify安装:

参考: Webpack install 执行:

npm i vuetify --save

批注 2020-04-18 215535

然后需要引用vuetify:

js/app.js添加:

import Vuetify from "vuetify";

Vue.use(Vuetify);

import 'vuetify/dist/vuetify.min.css';

批注 2020-04-18 223838

为了让修改的样式不受缓存影响,在webpack.mix.js后添加一个version();

批注 2020-04-18 224126

然后layout/app.blade.php中 asset()方法改为mix()方法:

批注 2020-04-18 224239批注 2020-04-18 224323


参考https://vuetifyjs.com/en/getting-started/quick-start/#bootstrapping-the-vuetify-object

添加下面代码到webpack.mix.js中:

// webpack.config.js

module.exports = {
  rules: [
    {
      test: /\.s(c|a)ss$/,
      use: [
        'vue-style-loader',
        'css-loader',
        {
          loader: 'sass-loader',
          // Requires sass-loader@^7.0.0
          options: {
            implementation: require('sass'),
            fiber: require('fibers'),
            indentedSyntax: true // optional
          },
          // Requires sass-loader@^8.0.0
          options: {
            implementation: require('sass'),
            sassOptions: {
              fiber: require('fibers'),
              indentedSyntax: true // optional
            },
          },
        },
      ],
    },
  ],
}

创建一插件文件:src/plugins/vuetify.js

// src/plugins/vuetify.js

import Vue from 'vue'
import Vuetify from 'vuetify'
import 'vuetify/dist/vuetify.min.css'

Vue.use(Vuetify)

const opts = {}

export default new Vuetify(opts)

批注 2020-04-19 005815

然后修改app.js对vuetify的引用:

批注 2020-04-19 010423

路由:

web.php中添加:

Route::any('/admin/{any?}', 'AdminController@index')->where('any', '.*')->middleware('auth');

控制器:

执行:

php artisan make:controller AdminController

批注 2020-04-18 224659

新建的控制器添加方法:

public function __construct()
{
    $this->middleware('auth');
}

//
public function index(Request $request)
{
    return view('admin');
}

index方法返回admin这个view视图,现在来新建这个视图文件:

批注 2020-04-18 231337

如果不用layouts.app基础框架那么 拷贝一下layouts.app中的内容 替换div#app中的内容:

批注 2020-04-18 231453

注意这里添加了一个Admin的vue component【vue组件】,所以开始处理这个vue组件:

在components文件夹下新建一个Admin.vue文件:

批注 2020-04-18 231818

Admin.vue直接用vuetify的模板:Pre-made layouts 暂时选了 Dark附上代码链接

初步的Admin.vue:

<template>
    <v-app id="inspire">
        <v-navigation-drawer
            v-model="drawer"
            app
            clipped
        >
            <v-list dense>
                <v-list-item link>
                    <v-list-item-action>
                        <v-icon>mdi-view-dashboard</v-icon>
                    </v-list-item-action>
                    <v-list-item-content>
                        <v-list-item-title>Dashboard</v-list-item-title>
                    </v-list-item-content>
                </v-list-item>
                <v-list-item link>
                    <v-list-item-action>
                        <v-icon>mdi-settings</v-icon>
                    </v-list-item-action>
                    <v-list-item-content>
                        <v-list-item-title>Settings</v-list-item-title>
                    </v-list-item-content>
                </v-list-item>
            </v-list>
        </v-navigation-drawer>

        <v-app-bar
            app
            clipped-left
        >
            <v-app-bar-nav-icon @click.stop="drawer = !drawer"/>
            <v-toolbar-title>Application</v-toolbar-title>
        </v-app-bar>

        <v-content>
            <v-container
                class="fill-height"
                fluid
            >
                <v-row
                    align="center"
                    justify="center"
                >
                    <v-col class="shrink">
                        <v-tooltip right>
                            <template v-slot:activator="{ on }">
                                <v-btn
                                    :href="source"
                                    icon
                                    large
                                    target="_blank"
                                    v-on="on"
                                >
                                    <v-icon large>mdi-code-tags</v-icon>
                                </v-btn>
                            </template>
                            <span>Source</span>
                        </v-tooltip>
                        <v-tooltip right>
                            <template v-slot:activator="{ on }">
                                <v-btn
                                    icon
                                    large
                                    href="https://codepen.io/johnjleider/pen/bXNzZL"
                                    target="_blank"
                                    v-on="on"
                                >
                                    <v-icon large>mdi-codepen</v-icon>
                                </v-btn>
                            </template>
                            <span>Codepen</span>
                        </v-tooltip>
                    </v-col>
                </v-row>
            </v-container>
        </v-content>

        <v-footer app>
            <span>&copy; 2019</span>
        </v-footer>
    </v-app>
</template>

<script>
    export default {
        name: "Admin",
        props: {
            source: String,
            user: Object,
        },
        data: function () {
            return {
                drawer: null,
            }
        },
        created() {
            this.$vuetify.theme.dark = true;
        },

    }
</script>

<style scoped>

</style>


Vue-router

安装:

执行:

npm i vue-router

安装完成:

批注 2020-04-19 003328

然后app.js中引用:

批注 2020-04-19 010604

因为admin route及AdminController都经过了auth中间件,所以注册一个用户是必须的:

批注 2020-04-19 003740

然后登录 :

注意执行:

npm install & npm run watch-poll

打开链接:http://vue.test/admin 即可看到:

批注 2020-04-19 010928

接下来添加vue的route文件:

批注 2020-04-19 011220

先添加,再编辑:

app.js里面需要添加代码应用这几个route:

import Dashboard from "./components/pages/Dashboard";
import Users from "./components/pages/Users";
import Settings from "./components/pages/Settings";
import Roles from "./components/pages/Roles";
import Permissions from "./components/pages/Permissions";

const routes = [
    {
        path: '/admin/',
        component: Dashboard,
    },
    {
        path: '/admin/users',
        component: Users,
    },
    {
        path: '/admin/roles',
        component: Roles,
    },
    {
        path: '/admin/settings',
        component: Settings,
    },
    {
        path: '/admin/permissions',
        component: Permissions,
    },
];
const router = new VueRouter({
    mode: 'history',
    routes,
});

并且vue实例需要配置这个router:

const app = new Vue({
    el: '#app',
    vuetify,
    router,
});

接下来 用户点击dashboard按钮 setting按钮的跳转,以及添加用户的users roles permissions按钮:

需要修改Admin.vue:

<template>
    <v-app id="inspire">
        <v-navigation-drawer
            v-model="drawer"
            app
            clipped
        >
            <v-list dense>
                <v-list-item link to="/admin">
                    <v-list-item-action>
                        <v-icon>mdi-view-dashboard</v-icon>
                    </v-list-item-action>
                    <v-list-item-content>
                        <v-list-item-title>Dashboard</v-list-item-title>
                    </v-list-item-content>
                </v-list-item>

                <v-list-group no-action>
                    <v-list-item slot="activator">
                        <v-list-item-action>
                            <v-icon>mdi-account</v-icon>
                        </v-list-item-action>
                        <v-list-item-content>
                            <v-list-item-title>User Management</v-list-item-title>
                        </v-list-item-content>
                    </v-list-item>

                    <v-list-item link to="/admin/users">
                        <v-list-item-action>
                            <v-icon>mdi-account</v-icon>
                        </v-list-item-action>
                        <v-list-item-content>
                            <v-list-item-title>Users</v-list-item-title>
                        </v-list-item-content>
                    </v-list-item>

                    <v-list-item link to="/admin/roles">
                        <v-list-item-action>
                            <v-icon>mdi-account</v-icon>
                        </v-list-item-action>
                        <v-list-item-content>
                            <v-list-item-title>Roles</v-list-item-title>
                        </v-list-item-content>
                    </v-list-item>

                    <v-list-item link to="/admin/permissions">
                        <v-list-item-action>
                            <v-icon>mdi-account</v-icon>
                        </v-list-item-action>
                        <v-list-item-content>
                            <v-list-item-title>Permissions</v-list-item-title>
                        </v-list-item-content>
                    </v-list-item>

                </v-list-group>


                <v-list-item link to="/admin/settings">
                    <v-list-item-action>
                        <v-icon>mdi-settings</v-icon>
                    </v-list-item-action>
                    <v-list-item-content>
                        <v-list-item-title>Settings</v-list-item-title>
                    </v-list-item-content>
                </v-list-item>

            </v-list>
        </v-navigation-drawer>

        <v-app-bar
            app
            clipped-left
        >
            <v-app-bar-nav-icon @click.stop="drawer = !drawer"/>
            <v-toolbar-title>Application</v-toolbar-title>
        </v-app-bar>

        <v-content>
            <v-container
                class="fill-height"
                fluid
            >
                <v-row
                    align="center"
                    justify="center"
                >
                    <v-col class="shrink">
                        <v-tooltip right>
                            <template v-slot:activator="{ on }">
                                <v-btn
                                    :href="source"
                                    icon
                                    large
                                    target="_blank"
                                    v-on="on"
                                >
                                    <v-icon large>mdi-code-tags</v-icon>
                                </v-btn>
                            </template>
                            <span>Source</span>
                        </v-tooltip>
                        <v-tooltip right>
                            <template v-slot:activator="{ on }">
                                <v-btn
                                    icon
                                    large
                                    href="https://codepen.io/johnjleider/pen/bXNzZL"
                                    target="_blank"
                                    v-on="on"
                                >
                                    <v-icon large>mdi-codepen</v-icon>
                                </v-btn>
                            </template>
                            <span>Codepen</span>
                        </v-tooltip>
                    </v-col>
                </v-row>
            </v-container>
        </v-content>

        <v-footer app>
            <span>&copy; 2019</span>
        </v-footer>
    </v-app>
</template>

<script>
    export default {
        name: "Admin",
        props: {
            source: String,
            user: Object,
        },
        data: function () {
            return {
                drawer: null,
            }
        },
        created() {
            this.$vuetify.theme.dark = true
        },
    }
</script>

<style scoped>

</style>

vue-router会在点击按钮的时候跳转到对应的route加载component,但是目前代码中缺少一个展示加载的component的代码:添加

<router-view></router-view>

到内容的地方:

<template>
    <v-app id="inspire">
        <v-navigation-drawer
            v-model="drawer"
            app
            clipped
        >
            <v-list dense>
                <v-list-item link to="/admin">
                    <v-list-item-action>
                        <v-icon>mdi-view-dashboard</v-icon>
                    </v-list-item-action>
                    <v-list-item-content>
                        <v-list-item-title>Dashboard</v-list-item-title>
                    </v-list-item-content>
                </v-list-item>

                <v-list-group no-action>
                    <v-list-item slot="activator">
                        <v-list-item-action>
                            <v-icon>mdi-account</v-icon>
                        </v-list-item-action>
                        <v-list-item-content>
                            <v-list-item-title>User Management</v-list-item-title>
                        </v-list-item-content>
                    </v-list-item>

                    <v-list-item link to="/admin/users">
                        <v-list-item-action>
                            <v-icon>mdi-account</v-icon>
                        </v-list-item-action>
                        <v-list-item-content>
                            <v-list-item-title>Users</v-list-item-title>
                        </v-list-item-content>
                    </v-list-item>

                    <v-list-item link to="/admin/roles">
                        <v-list-item-action>
                            <v-icon>mdi-account</v-icon>
                        </v-list-item-action>
                        <v-list-item-content>
                            <v-list-item-title>Roles</v-list-item-title>
                        </v-list-item-content>
                    </v-list-item>

                    <v-list-item link to="/admin/permissions">
                        <v-list-item-action>
                            <v-icon>mdi-account</v-icon>
                        </v-list-item-action>
                        <v-list-item-content>
                            <v-list-item-title>Permissions</v-list-item-title>
                        </v-list-item-content>
                    </v-list-item>

                </v-list-group>


                <v-list-item link to="/admin/settings">
                    <v-list-item-action>
                        <v-icon>mdi-settings</v-icon>
                    </v-list-item-action>
                    <v-list-item-content>
                        <v-list-item-title>Settings</v-list-item-title>
                    </v-list-item-content>
                </v-list-item>

            </v-list>
        </v-navigation-drawer>

        <v-app-bar
            app
            clipped-left
        >
            <v-app-bar-nav-icon @click.stop="drawer = !drawer"/>
            <v-toolbar-title>Application</v-toolbar-title>
        </v-app-bar>

        <v-content>
            <v-container
                class="fill-height"
                fluid
            >
                <v-row
                    align="center"
                    justify="center"
                >
                    <v-col class="shrink">
                        <router-view></router-view>
                    </v-col>
                </v-row>
            </v-container>
        </v-content>

        <v-footer app>
            <span>&copy; 2019</span>
        </v-footer>
    </v-app>
</template>

<script>
    export default {
        name: "Admin",
        props: {
            source: String,
            user: Object,
        },
        data: function () {
            return {
                drawer: null,
            }
        },
        created() {
            this.$vuetify.theme.dark = true
        },
    }
</script>

<style scoped>

</style>

最后效果:

批注 2020-04-19 013357

posted @ 2020-04-18 21:52  dzkjz  阅读(610)  评论(0编辑  收藏  举报