Vue-Axios 后台管理系统 项目 练习 总结 中……

发布于:2022-12-05 ⋅ 阅读:(709) ⋅ 点赞:(0)


前言

ヽ(✿゚▽゚)ノ

现在是2022年的9月28日,
毕业之后的我了解到了公司的一些开发技术,在学校里接触不多甚至几乎没有当然是处处碰壁,
但在其中也是学到了一点东西,可无法灵活的运用
关于前后端交互这块,陌生的就像第一次吃螃蟹
于是 在临近国庆期间 我便在网上找了一些Vue axios的实战项目来析毫剖厘
希望自己的技术能得到一些提升。


商城后台管理系统_日志

一、需要安装的环境

在这里插入图片描述
直接npm i +‘名字’

官方文档:
axios:官网
elementui:官网


二、项目文件夹结构

目前的了解
在这里插入图片描述

>database

是配置的数据库,我使用的是Wampserver32进行配置。

>dist

执行npm run build 打包的项目。

>node_modules

安装的各种依赖。

>public

在这里插入图片描述

公用文件。这里的UEditor是一个富文本编辑器就像写评论的那个效果。

>server

在这里插入图片描述

连接数据库,配置一些页面接口。
upload里存放的是上到数据库的文件。
config.js是配置文件。
index.js写了跨域的一些内容。
mysql.js是连接的数据库。
router.js是路由跳转用于控制判断是否为数据库里的数据,例如登录判断。

>src

在这里插入图片描述

主要操作的地方,组件的增加修改等都在这个文件夹里操作。

在这里插入图片描述
base.js是网络请求的地址
index.js是网络请求的方法,例如在这里插入图片描述

assets: 放置静态资源,包括公共的 css 文件、 js 文件、iconfont 字体文件、img 图片文件 以及其他资源类文件。

components: 放置通用模块组件,避免重复工作。

那个js文件夹应该是放在assets文件夹下的。

这里是引用
echarts.js是一个数据可视化的组件。
element.js是引入的elementUI组件。
i18n.js是实现中英语言切换的组件。

router: index.js放置路由设置文件。

store:
封装好的vuex结构。

在这里插入图片描述
公共方法汇总。例如我在request.js这里配置了一个请求时的状态码。

这里是引用
各种页面。

剩余的

App.vue: 入口组件,pages 里的组件会被插入此组件中,此组件再插入 index.html 文件里,形成单页面应用。

main.js:入口 js 文件,影响全局,作用是引入全局使用的库、公共的样式和方法、设置路由等。.在这里插入图片描述

register-service-worker.js:用来做离线缓存等任务的,如果在线上,只要访问过一次该网站,以后即使没有网络也可以访问(此时使用的是之前缓存的资源)。

.browserslistrc:配置兼容浏览器。
" >1%" :代表着全球超过1%人使用的浏览器
“last 2 versions” : 表示所有浏览器兼容到最后两个版本
“not ie <=8” :表示IE浏览器版本大于8(实则用npx browserslist 跑出来不包含IE9 )
“safari >=7”:表示safari浏览器版本大于等于7

gitignore:忽略某个或一组文件git提交的一个配置。

babel.config.js:主要作用是将ECMAScript 2015+ 版本的代码,转换为向后兼容的JS语法,以便能够运行在当前和旧版本的浏览器或其它环境中。Vue项目中普遍使用ES6语法,若要求兼容低版本浏览器,就需要引入Babel,将ES6转换为ES5。

package-lock.json:是在npm install执行的时候生成的一份文件,用来记录package.json的来源和版本号。锁住package.json的来源和版本号,多人开发拉取代码,执行npm install生成node_modules时依赖的版本能保持一致。package-lock.json一般要提交到git仓库。

package.json:通过命令生成的vue项目就包含package.json,这是vue项目的表述文件,依赖包就是根据package.json来安装的。

README.md:内容相关的解释。

sh.exe.stackdump:啊这,这是个啥。似乎是使用git命令后出现的。

vue.config.js:是一个可选的配置文件,如果项目的 (和 package.json 同级的) 根目录中存在这个文件,那么它会被 @vue/cli-service 自动加载。我在这里设置了api的接口网址。


三、页面搭建 (可能遇到的问题)

= ̄ω ̄=

1、 Login页面分析

先上源码

<template>
    <div class="login">
        <el-tabs
            v-model="activeName"
            type="border-card"
            class="login-tabs"
            stretch
            @tab-click="handleClick"
        >
            <el-tab-pane label="用户登陆" name="login" class="login-tabs-tab">
                <el-form
                    ref="loginForm"
                    :model="user"
                    status-icon
                    :rules="rules"
                    class="login-form"
                >
                    <el-form-item label="用户名" prop="username">
                        <el-input type="text" v-model="user.username"></el-input>
                    </el-form-item>
                    <el-form-item label="密码" prop="password">
                        <el-input type="password" v-model="user.password"></el-input>
                    </el-form-item>
                    <el-form-item>
                        <el-button type="primary" @click="submitForm('loginForm')">登陆</el-button>
                    </el-form-item>
                </el-form>
            </el-tab-pane>
            <el-tab-pane label="用户注册" name="register">
                <el-form
                    ref="registerForm"
                    :model="user"
                    status-icon
                    :rules="rules"
                    class="login-form"
                >
                    <el-form-item label="用户名" prop="username">
                        <el-input type="text" v-model="user.username"></el-input>
                    </el-form-item>
                    <el-form-item label="密码" prop="password">
                        <el-input type="password" v-model="user.password"></el-input>
                    </el-form-item>
                    <el-form-item label="确认密码" prop="surePassword">
                        <el-input type="password" v-model="user.surePassword"></el-input>
                    </el-form-item>
                    <el-form-item label="邮箱" prop="email">
                        <el-input type="email" v-model="user.email"></el-input>
                    </el-form-item>
                    <el-form-item>
                        <el-button type="primary" @click="submitForm('registerForm')">注册</el-button>
                    </el-form-item>
                </el-form>
            </el-tab-pane>
        </el-tabs>
    </div>
</template>

<script>

import { mapActions } from "vuex"

export default {
    name: "Login",
    data() {
        var validateUsername = (rule, value, callback) => {
            if (value === "") {
                callback(new Error("请输入用户名"));
            }
            callback();
        };

        var validatePassword = (rule, value, callback) => {
            if (value === "") {
                callback(new Error("请输入密码"));
            }
            callback();
        };

        var validateSurePassword = (rule, value, callback) => {
            if (value === "") {
                callback(new Error("请输入密码"));
            }
            callback();
        };

        var validateEmail = (rule, value, callback) => {
            if (value === "") {
                callback(new Error("请输入邮箱"));
            }
            callback();
        };

        return {
            user: {
                username: "",
                password: "",
                surePassword: "",
                email:""
            },
            rules: {
                username: [{ validator: validateUsername, trigger: "blur" }],
                password: [{ validator: validatePassword, trigger: "blur" }],
                email: [{ validator: validateEmail, trigger: "blur" }],
                surePassword: [
                    { validator: validateSurePassword, trigger: "blur" },
                ],
            },
            activeName: "login",
        };
    },
    methods: {
        ...mapActions("loginModule",["setUserActions"]),
        submitForm(formName) {
            this.$refs[formName].validate((valid) => {
                if (valid) {
                    /**
                     * 区分是登陆还是注册
                     */
                    if (this.activeName === "login") {
                        /**
                         * 登陆
                         */
                        this.setUserActions(this.user)
                        
                    }
                    if (this.activeName === "register") {
                        /**
                         * 注册
                         */
                        this.$api.register({
                            username:this.user.username,
                            password:this.user.password,
                            email:this.user.email
                        }).then(res =>{
                            console.log(res.data)
                        })
                    }
                } else {
                    console.log("error submit!!");
                    return false;
                }
            });
        },
        handleClick(tab, event) {},
    },
};
</script>

<style scoped lang="less">
.login {
    width: 500px;
    margin: 0 auto;
    margin-top: 100px;
    .login-form {
        padding: 40px 40px;
    }
    h3 {
        margin-top: 20px;
    }
    .login-tabs {
        border-radius: 5px;
    }
}
</style>

先从布局来说吧

在这里插入图片描述

根标签

的类名是login,用于控制这个页面的大小以及位置。

在这里插入图片描述

el-tabs

引用的是elementUI的tabs标签页,包括那些定义在标签上的属性详情见链接。

在这里插入图片描述

el-tabs

引用的是elementUI的form表单

在这里插入图片描述

el-input

引用的是elementUI的input输入框。注意这里的prop和v-model=“user.username”,都是传入 Form 组件的 (:model=“user”)user 中的字段。

在这里插入图片描述

el-button

引用的是elementUI的button按钮



script里的内容

在这里插入图片描述

mapActions

就是将组件中的事件函数映射为对应的action,其中事件函数名称与action名称应该是一样的。在这里插入图片描述

在这里插入图片描述

name

这里稍微提一下吧,我在写的时候,必须用到LoginVue这样的驼峰写法,不然报错。每个组件最好是写上他的name属性。

在这里插入图片描述

rules

这里是一个elementUI form表单的一个验证规则的属性,写成了一个函数有三个参数,rule是验证,value是值,callback是回调函数。rules写在data return对象里。
在这里插入图片描述

在这里插入图片描述

mapActions方法

在这里插入图片描述>在这里插入图片描述
来源于vuex的store文件夹下的modules的login~.js中的setUserActions方法。登录成功时执行的操作。
顺带一提登录失败时,是写在了utils公共方法文件夹下的request.js里在这里插入图片描述

在这里插入图片描述

本页面的核心 submitForm方法

该方法绑定在在这里插入图片描述
可以知道标签里写的‘loginForm’的字符串数据被methods里的formName接受,用于判断提交的是哪里的数据。然后通过elementUI tab组件自带的一个handleClick方法获取el-tab-pane标签上的name属性,以此来判断点击的是登录还是注册(具体在这),判断完之后就可以执行操作了。
如果是登录 执行了上面的setUserActions方法。
如果是注册 这里是用到了axios封装好的api接口。



最后CSS

在这里插入图片描述
稍微做了一些修饰。

效果

就是这样的了








2、 导航栏组件分析

先上源码

<template>
    <el-menu
        :default-active="activeIndex"
        class="el-menu-demo"
        mode="horizontal"
        @select="handleSelect"
        background-color="#545c64"
        text-color="#fff"
        active-text-color="#ffd04b"
        router
    >
        <el-menu-item index="/"><i class="el-icon-menu"></i>{{ $t("message.project") }}</el-menu-item>
        <el-menu-item index="/params"><i class="el-icon-document"></i>{{ $t("message.params") }}</el-menu-item>
        <el-menu-item index="/content"><i class="el-icon-setting"></i>{{ $t("message.content") }}</el-menu-item>
        <div class="user">
            <router-link to="/user" tag="span" class="user-name">{{ user.username }}</router-link>
            <el-button class="logout" @click="logoutHandle">退出</el-button>
        </div>
        <el-menu-item class="set-lang">
            <el-dropdown @command="handleCommand">
                <span class="el-dropdown-link">
                    语言环境
                    <i class="el-icon-arrow-down el-icon--right"></i>
                </span>
                <el-dropdown-menu slot="dropdown">
                    <el-dropdown-item command="zh">中文</el-dropdown-item>
                    <el-dropdown-item command="en">英文</el-dropdown-item>
                </el-dropdown-menu>
            </el-dropdown>
        </el-menu-item>
    </el-menu>
</template>

<script>
import { mapState, mapMutations } from "vuex";
import local from "../../utils/lcoalUtils";
import i18n from "../../plugins/i18n"

export default {
    name: "NavMenu",
    data() {
        return {
            activeIndex: "/",
        };
    },
    computed: {
        ...mapState("loginModule", ["user"]),
    },
    mounted() {
        if (sessionStorage.getItem("path")) {
            this.activeIndex = sessionStorage.getItem("path");
        }
    },
    methods: {
        ...mapMutations("loginModule", ["removeUser"]),
        handleSelect(key, keyPath) {
            if(key){
                sessionStorage.setItem("path", key);
            }
        },
        logoutHandle() {
            /**
             * 本地清除
             * 状态清除
             * 回到登录页
             */
            local.removeLocal("ego");
            this.removeUser();
            this.$router.push("/login");
        },
        /**
         * 切换语言环境
         */
        handleCommand(command){
            i18n.locale = command
        }
    },
};
</script>

<style scoped lang="less">
.user {
    float: right;
    margin-right: 20px;
    line-height: 60px;
    .user-name {
        color: #fff;
        margin-right: 10px;
        font-size: 15px;
        border: 1px solid #fff;
        border-radius: 50%;
        width: 40px;
        height: 40px;
        display: inline-block;
        line-height: 40px;
    }
    .logout {
    }
}

.set-lang {
    float: right !important;
}

.el-dropdown-link {
    color: #fff;
}
</style>

先从布局来说吧

在这里插入图片描述

el-menu

elementUI的导航菜单组件。

在这里插入图片描述

用户个人中心

使用的router to跳转。

在这里插入图片描述

el-dropdown

elementUI的下拉菜单。



script里的内容

在这里插入图片描述

import引入的

mapState:vuex的东西,获取多个状态的时候使用。在计算属性里使用。这里是获取了‘user’。
mapMutations:vuex的mutation的辅助函数,用于在组件中映射mutation内的方法,以便在该组件中直接使用mutation里的方法。
local:地址状态。
i18n:语言环境配置。

在这里插入图片描述

data里的数据

这里的activeIndex对应el-menu标签上default-active当前激活菜单的 index绑定的。

在这里插入图片描述

sessionStorage

跨页面传数据的时候就经常能用到它,用来传id传状态,传一些样式数据都可以。在mounted()里使用。

在这里插入图片描述

methods里的方法

handleSelect方法是elementUI里的。



最后CSS

注意级别问题吧,使用!important解决。

效果

在这里插入图片描述





四、EventBus 组件通信

使用方法

1、在这里插入图片描述
在utils(公共方法汇总)文件夹下创建eventbus.js。

2、写入的代码内容:

import Vue from "vue"

const EventBus = new Vue();
Object.defineProperties(Vue.prototype,{
    $bus:{
        get:function(){
            return EventBus
        }
    }
})

3、发送数据

this.$bus.$emit("onParamsSearch",res.data.result);
//引号里的为参数名,后面是发送的数据

4、接受数据

this.$bus.$on("onParamsSearch", (result) => {
	this.paramsData = result;
});
//引号里的为参数名,后面是接受的数据result(这个可以自定义名字res也没问题),
//后面的就是把接收到的数据赋给当前组件里的数据名。

完毕

这个方法是任意组件的通信,还是很方便的。知识+1.





五、模糊查询 实现

布局

在这里插入图片描述

elementUI组件:输入框和按钮。

查询的方法

当前组件下

在这里插入图片描述

api文件夹下

在这里插入图片描述
在这里插入图片描述

server文件夹下

在这里插入图片描述

最后list列表组件接收查询数据 渲染视图

在这里插入图片描述

就我的了解。输入框里的内容不为空时执行 api index.js里封装的在这里插入图片描述
这个方法,其中base.baseUrl等是api base.js里封装的路径。然后把输入的内容赋给了search这个参数,接下来判断状态码是否为200,如果是则发送输入的数据所查询到的列表,不是就发送空数组。查询是在server router.js里的在这里插入图片描述
查询。然后list组件接受渲染。嗯…

六、自己尝试写了一个留言功能

成功了




总结


~(~ ̄▽ ̄)~
先写到这吧,这个项目还有看完,而且该吃晚饭了。
2022/9/28 19:55

login的页面就是这样了,虽然看着简单,但如果没有指导的话,在api接口和server配置连接数据库还有store、utils这里自己写还是有亿点难度的。就目前情况来看,通过看源码尝试理解代码逻辑结构,还是勉强可以的,接下来我会自己添加一些页面以及功能。
NavMenu导航栏组件解决。准备构建首页页面。
2022/9/30 15:21

首页已经跟着写完了,新了解的有:
“:class=“{box:true,boxmargin: index % 2==0 ? true : false}” v-for”三元表达式来判断类名的应用;
“v-if=“item.hot= =true”>HOT”通过在循环列表中设置数据配合v-if来决定高亮hot显示;
还有一个三级路由显示,倒也没什么 就是在app的view视图下的homeindex的view视图下的detail的view视图下显示的内容。
效果图也比较简单就不上传了。
今天是有了解到EventBUS的一个方法实现组件通信,还有模糊查询的实现 有点懵,还是不熟练。elementUI倒是看的很熟练了。
2022/10/2 19:33

自己做了一个留言功能,发送的数据保存在数据库的一个表中,然后再渲染出来,不可思议 我成功了,明天再解决页码显示条数的问题。
2022/10/3 22:23
















请添加图片描述


网站公告

今日签到

点亮在社区的每一天
去签到