Heim  >  Artikel  >  Web-Frontend  >  vue-manage-system Hintergrundmanagementsystem-Entwicklungsprozess (Code)

vue-manage-system Hintergrundmanagementsystem-Entwicklungsprozess (Code)

不言
不言Original
2018-09-13 16:16:152914Durchsuche

Der Inhalt dieses Artikels befasst sich mit dem Entwicklungsprozess (Code) des Hintergrundverwaltungssystems vue-manage-system. Ich hoffe, dass er für Sie hilfreich ist.

Vorwort

vue-manage-system, eine auf Vue.js und element-ui basierende Backend-Managementsystem-Vorlage, ist seit ihrem ersten Commit Ende 2016 fast zwei Jahre her Es gibt auch 5.000 Sterne auf GitHub, was mich motiviert hat, weiter zu aktualisieren. Ich bin auch auf viele Fallstricke gestoßen, die ich hier zusammenfassen werde.

Github-Adresse: vue-manage-system

Benutzerdefinierte Symbole

element-ui enthält relativ wenige Schriftartensymbole, und viele der gebräuchlicheren sind daher nicht verfügbar Sie müssen die gewünschten Schriftartsymbole selbst einführen. Die beliebteste Symbolbibliothek, Font Awesome, verfügt über satte 675 Symbole, was jedoch auch zu einer relativ großen Schriftartendatei führt und es nicht erforderlich ist, so viele Symbole im Projekt zu verwenden. Dann ist die Alibaba Icon Library zu diesem Zeitpunkt eine sehr gute Wahl.

Erstellen Sie zunächst ein Projekt auf dem Ali-Symbol, legen Sie das Symbolpräfix fest, z. B. el-icon-lx, legen Sie die Schriftfamilie fest, z. B. lx-iconfont, und fügen Sie dem Projekt die Symbole hinzu, die Sie verwenden möchten. Ich wähle aus Die Schriftart dieser Klasse generiert Online-Links, da alle Seiten Symbole verwenden müssen. Fügen Sie einfach den CSS-Link direkt in index.html ein.

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>vue-manage-system</title>
    <!-- 这里引入阿里图标样式 -->
    <link rel="stylesheet" href="//at.alicdn.com/t/font_830376_qzecyukz0s.css">
</head>
<body>
<p id="app"></p>
</body>
</html>

Dann müssen Sie den Namen der Symbolklasse mit dem Präfix el-icon-lx und festlegen Verwenden Sie die Schriftart lx -iconfont.

[class*="el-icon-lx"], [class^=el-icon-lx] {
    font-family: lx-iconfont!important;
}

Aber wo soll ich diesen Stil platzieren? Das ist nichts, was man einfach so beiläufig einbauen kann. In main.js wird der Element-UI-Stil eingeführt, und es gibt einen CSS-Abschnitt im Stil:

[class*=" el-icon-"], [class^=el-icon-]{
    font-family: element-icons!important;
    speak: none;
    font-style: normal;
    font-weight: 400;
    font-variant: normal;
    text-transform: none;
    line-height: 1;
    vertical-align: baseline;
    display: inline-block;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

Wenn dieser CSS-Abschnitt nach unserem benutzerdefinierten Stil ausgeführt wird, wird er natürlich überschrieben. Bei unserem Stil können die benutzerdefinierten Symbole nicht angezeigt werden. Beim Erstellen des Projekts werden die Stile in APP.vue in app.css gepackt und dann werden die in main.js referenzierten Stile an die Rückseite angehängt. Dann können wir den benutzerdefinierten Stil in eine CSS-Datei einfügen und ihn dann einführen, nachdem das Element-UI-CSS in main.js eingeführt wurde. Dann kann die Standardschriftart überschrieben werden und dann kann das Symbol über . <i class="el-icon-lx-people"></i>

Der schlaue Mensch hat herausgefunden, dass es kein solches Problem gibt, wenn das Präfix meines benutzerdefinierten Symbols kein el-icon- enthält. Ja, um den gleichen Stil wie die Originalschrift beizubehalten, müssen Sie das gesamte CSS kopieren

/* 假设前缀为 el-lx */
[class*="el-lx-"], [class^=el-lx-]{
    font-family: lx-iconfont!important;
    speak: none;
    font-style: normal;
    font-weight: 400;
    font-variant: normal;
    text-transform: none;
    line-height: 1;
    vertical-align: baseline;
    display: inline-block;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}
Navigationsmenü

element-ui Die Dokumentation zum Navigationsmenü ist ebenfalls sehr detailliert. Aber einige Leute werfen immer noch Fragen auf oder fügen QQ hinzu, um mich zu fragen: Wie erstelle ich das Menü der dritten Ebene usw. Darüber hinaus kann es sich bei bestimmten Menüelementen um bestimmte Datenelemente handeln, die vom Server basierend auf Berechtigungen zurückgegeben werden, sodass sie nicht in der Vorlage fest codiert werden können.

Stellen Sie zunächst das Format der Menüdaten wie folgt ein. Auch wenn das vom Server zurückgegebene Format nicht diesem entspricht, muss das Frontend es in das folgende Format verarbeiten:

export default {
    data() {
        return {
            items: [{
                icon: 'el-icon-lx-home',
                index: 'dashboard',
                title: '系统首页'
            },{
                icon: 'el-icon-lx-calendar',
                index: '1',
                title: '表单相关',
                subs: [{
                    index: '1-1',
                    title: '三级菜单',
                    subs: [{
                        index: 'editor',
                        title: '富文本编辑器'
                    }]
                }]
            },{
                icon: 'el-icon-lx-warn',
                index: '2',
                title: '错误处理',
                subs: [{
                    index: '404',
                    title: '404页面'
                }]
            }]
        }
    }
}
Das Symbol ist das Menüsymbol, das oben verwendet werden kann. Der Index ist die Routing-Adresse. Die Vorlage zeigt das Menü der zweiten Ebene und das Menü der dritten Ebene an, indem sie bestimmt, ob das Menü Untermenüs enthält.

<el-menu :default-active="onRoutes" :collapse="collapse" router>
    <template v-for="item in items">
        <template v-if="item.subs">
            <el-submenu :index="item.index" :key="item.index">
                <template slot="title">
                    <i :class="item.icon"></i><span slot="title">{{ item.title }}</span>
                </template>
                <template v-for="subItem in item.subs">
                    <el-submenu v-if="subItem.subs" :index="subItem.index" :key="subItem.index">
                        <template slot="title">{{ subItem.title }}</template>
                        <!-- 三级菜单 -->
                        <el-menu-item v-for="(threeItem,i) in subItem.subs" :key="i" :index="threeItem.index">
                            {{ threeItem.title }}
                        </el-menu-item>
                    </el-submenu>
                    <el-menu-item v-else :index="subItem.index" :key="subItem.index">
                        {{ subItem.title }}
                    </el-menu-item>
                </template>
            </el-submenu>
        </template>
        <!-- 没有二级菜单 -->
        <template v-else>
            <el-menu-item :index="item.index" :key="item.index">
                <i :class="item.icon"></i><span slot="title">{{ item.title }}</span>
            </el-menu-item>
        </template>
    </template>
</el-menu>
Damit ist ein dynamisches Navigationsmenü fertig.

Das Auslösen der Erweiterung oder Reduzierung der Sidebar-Komponente über eine Schaltfläche in der Header-Komponente erfordert die Übertragung von Daten zwischen Komponenten. Dabei wird die Kommunikation zwischen Komponenten über ein separates Event Center (Event Bus) von Vue.js verwaltet.

const bus = new Vue();
Lösen Sie das Minimierungsereignis aus, wenn in der Header-Komponente auf die Schaltfläche geklickt wird:

bus.$emit('collapse', true);
Hören Sie sich das Minimierungsereignis in der Seitenleistenkomponente an:

bus.$on('collapse', msg => {
    this.collapse = msg;
})
Chart adaptiv

vue Das in -manage-system verwendete Diagramm-Plug-in ist vue-schart, das ein Canvas-basiertes Diagramm-Plug-in schart.js kapselt. Damit sich das Diagramm an seine Breite anpasst und neu gerendert wird, wenn sich die Größe des Fensters oder des übergeordneten Elements ändert, müssen Sie diese Funktion manuell implementieren, wenn sie nicht im Diagramm-Plug-in implementiert ist.

vue-schart stellt die Methode renderChart() zum erneuten Rendern des Diagramms bereit. In Vue.js ruft die übergeordnete Komponente die Methode der untergeordneten Komponente auf, die über $refs aufgerufen werden kann.

<schart ref="bar" canvasId="bar" :data="data" type="bar" :options="options"></schart>
Hören Sie dann auf das Größenänderungsereignis des Fensters und rufen Sie die Methode renderChart() auf, um das Diagramm neu zu rendern.

import Schart from 'vue-schart';
export default {
    components: {
        Schart
    },
    mounted(){
        window.addEventListener('resize', ()=>{
            this.$refs.bar.renderChart();
        })
    }
}
Aber denken Sie daran, den Listener zu entfernen, wenn die Komponente zerstört wird! Die Größenänderung des Abhörfensters ist abgeschlossen, aber was ist mit der Größenänderung des übergeordneten Elements? Da die Breite des übergeordneten Elements auf einen Prozentsatz eingestellt ist, ändert sich die Breite des übergeordneten Elements, wenn die Seitenleiste ausgeblendet wird. Allerdings hat p kein Größenänderungsereignis und kann seine Breitenänderung nicht überwachen, aber wir wissen, wann die Faltung ausgelöst wird. Ist es also möglich, das Diagramm erneut zu rendern, indem die Renderfunktion aufgerufen wird, wenn sich die Falte ändert? Dann ist es besser, die Änderungen der Seitenleiste über Event Bus zu überwachen und sie nach 300 ms erneut zu rendern, da beim Falten ein 300 ms langer Animationsprozess stattfindet

bus.$on('collapse', msg => {
    setTimeout(() => {
        this.$refs.bar.renderChart();
    }, 300);
});
Multi-Tab-Seite

Multi- Registerkarte Seite, es ist auch ein Problem Das funktionalste.

当在 A 标签页输入一些内容之后,打开 B 标签再返回到 A,要保留离开前的状态,因此需要使用 keep-alive 进行缓存,而且关闭之后的标签页就不再缓存,避免关闭后再打开还是之前的状态。keep-alive 的属性 include 的作用就是只有匹配的组件会被缓存。include 匹配的不是路由名,而是组件名,那么每个组件都需要添加 name 属性。

在 Tags 组件中,监听路由变化,将打开的路由添加到标签页中:

export default {
    data() {
        return {
            tagsList: []
        }
    },
    methods: {
        setTags(route){
            const isExist = this.tagsList.some(item => {
                return item.path === route.fullPath;
            })
            if(!isExist){
                this.tagsList.push({
                    title: route.meta.title,
                    path: route.fullPath,
                    name: route.matched[1].components.default.name
                })
            }
        }
    },
    watch:{
        $route(newValue, oldValue){
            this.setTags(newValue);
        }
    }
}

在 setTags 方法中,将一个标签对象存到标签数组中,包括title(标签显示的title),path(标签的路由地址),name(组件名,用于include匹配的)。路由地址需要用 fullPath 字段,如果使用 path 字段,那如果地址后面带有参数,就都没保存起来了。

在 Home 组件中,监听到标签的变化,缓存需要的组件。

<keep-alive :include="tagsList">
    <router-view></router-view>
</keep-alive>
export default {
    data(){
        return {
            tagsList: []
        }
    },
    created(){
        // 只有在标签页列表里的页面才使用keep-alive,即关闭标签之后就不保存到内存中了。
        bus.$on('tags', msg => {
            let arr = [];
            for(let i = 0, len = msg.length; i < len; i ++){
                // 提取组件名存到tagsList中,通过include匹配
                msg[i].name && arr.push(msg[i].name);
            }
            this.tagsList = arr;
        })
    }
}

总结

由于该项目中不包含任何业务代码,所以还是相对比较简单的,不过从开发中还是积累了一些经验,在其它项目中可以更加熟练地开发。功能虽然不算多,但是也勉强够用,如果有什么好的建议,可以开 issue 一起讨论。

相关推荐:

ASP.NET MVC5+EF6+EasyUI 后台管理系统微信公众平台开发

基于thinkphp的后台管理系统模板快速搭建,thinkphp后台模板

Das obige ist der detaillierte Inhalt vonvue-manage-system Hintergrundmanagementsystem-Entwicklungsprozess (Code). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn