elementUI-day01----elementUI的使用、elementUI配置项、SliderTabBar.vue渲染、SliderTabBar.vue默认选中、路由切换、项目登录-mock数据模拟后台登录接口

### 项目搭建

    vue create my_cms
    Babel Router Vuex CSS
    Use history mode for router?    n
    Sass/SCSS (with dart-sass)
    In package.json
    Save this as a preset for future projects?      n

 

### 安装插件

    npm i element-ui axios js-cookie mockjs
    npm install babel-plugin-component -D  ----按需引入

 

### elementUI的使用

    ①安装插件:
        npm i element-ui
        npm install babel-plugin-component -D
    ②配置babel.config.js(按需加载,修改完要重启):
        "plugins": [
            [
            "component",
            {
                "libraryName": "element-ui",
                "styleLibraryName": "theme-chalk"
            }
            ]
        ]
    ③src下新建common/components/index.js,完整组件列表和引入方式(实际工作中按需引入):
        import Vue from 'vue';
        import {
        Pagination,
        Dialog,
        Autocomplete,
        Dropdown,
        DropdownMenu,
        DropdownItem,
        Menu,
        Submenu,
        MenuItem,
        MenuItemGroup,
        Input,
        InputNumber,
        Radio,
        RadioGroup,
        RadioButton,
        Checkbox,
        CheckboxButton,
        CheckboxGroup,
        Switch,
        Select,
        Option,
        OptionGroup,
        Button,
        ButtonGroup,
        Table,
        TableColumn,
        DatePicker,
        TimeSelect,
        TimePicker,
        Popover,
        Tooltip,
        Breadcrumb,
        BreadcrumbItem,
        Form,
        FormItem,
        Tabs,
        TabPane,
        Tag,
        Tree,
        Alert,
        Slider,
        Icon,
        Row,
        Col,
        Upload,
        Progress,
        Spinner,
        Badge,
        Card,
        Rate,
        Steps,
        Step,
        Carousel,
        CarouselItem,
        Collapse,
        CollapseItem,
        Cascader,
        ColorPicker,
        Transfer,
        Container,
        Header,
        Aside,
        Main,
        Footer,
        Timeline,
        TimelineItem,
        Link,
        Divider,
        Image,
        Calendar,
        Backtop,
        PageHeader,
        CascaderPanel,
        Loading,
        MessageBox,
        Message,
        Notification
        } from 'element-ui';

        Vue.use(Pagination);
        Vue.use(Dialog);
        Vue.use(Autocomplete);
        Vue.use(Dropdown);
        Vue.use(DropdownMenu);
        Vue.use(DropdownItem);
        Vue.use(Menu);
        Vue.use(Submenu);
        Vue.use(MenuItem);
        Vue.use(MenuItemGroup);
        Vue.use(Input);
        Vue.use(InputNumber);
        Vue.use(Radio);
        Vue.use(RadioGroup);
        Vue.use(RadioButton);
        Vue.use(Checkbox);
        Vue.use(CheckboxButton);
        Vue.use(CheckboxGroup);
        Vue.use(Switch);
        Vue.use(Select);
        Vue.use(Option);
        Vue.use(OptionGroup);
        Vue.use(Button);
        Vue.use(ButtonGroup);
        Vue.use(Table);
        Vue.use(TableColumn);
        Vue.use(DatePicker);
        Vue.use(TimeSelect);
        Vue.use(TimePicker);
        Vue.use(Popover);
        Vue.use(Tooltip);
        Vue.use(Breadcrumb);
        Vue.use(BreadcrumbItem);
        Vue.use(Form);
        Vue.use(FormItem);
        Vue.use(Tabs);
        Vue.use(TabPane);
        Vue.use(Tag);
        Vue.use(Tree);
        Vue.use(Alert);
        Vue.use(Slider);
        Vue.use(Icon);
        Vue.use(Row);
        Vue.use(Col);
        Vue.use(Upload);
        Vue.use(Progress);
        Vue.use(Spinner);
        Vue.use(Badge);
        Vue.use(Card);
        Vue.use(Rate);
        Vue.use(Steps);
        Vue.use(Step);
        Vue.use(Carousel);
        Vue.use(CarouselItem);
        Vue.use(Collapse);
        Vue.use(CollapseItem);
        Vue.use(Cascader);
        Vue.use(ColorPicker);
        Vue.use(Transfer);
        Vue.use(Container);
        Vue.use(Header);
        Vue.use(Aside);
        Vue.use(Main);
        Vue.use(Footer);
        Vue.use(Timeline);
        Vue.use(TimelineItem);
        Vue.use(Link);
        Vue.use(Divider);
        Vue.use(Image);
        Vue.use(Calendar);
        Vue.use(Backtop);
        Vue.use(PageHeader);
        Vue.use(CascaderPanel);

        Vue.use(Loading.directive);

        Vue.prototype.$loading = Loading.service;
        Vue.prototype.$msgbox = MessageBox;
        Vue.prototype.$alert = MessageBox.alert;
        Vue.prototype.$confirm = MessageBox.confirm;
        Vue.prototype.$prompt = MessageBox.prompt;
        Vue.prototype.$notify = Notification;
        Vue.prototype.$message = Message;
    ④main.js中引入:
        import "@common/components/index.js";
    ⑤pages/Layout/index.vue中可以直接用elementUI的组件:
        <el-container>
            <el-aside width="200px">
                <SliderTabBar /> 
            </el-aside>
            <el-container>
                <el-header>Header</el-header>
                <el-main>
                    <Container />
                </el-main>
            </el-container>
        </el-container>

 

### elementUI配置项

    <el-menu
        default-active="2"
        class="el-menu-vertical-demo"
        @open="handleOpen"
        @close="handleClose"
        background-color="#545c64"
        text-color="#fff"
        active-text-color="#ffd04b"
    >
        <!-- 二级路由 -->
        <el-submenu index="1">
            <template slot="title">
                <i class="el-icon-location"></i>
                <span>导航一</span>
            </template>
            <el-menu-item index="1-4-1">选项1</el-menu-item>
            <el-menu-item index="1-4-2">选项1</el-menu-item>
            <el-menu-item index="1-4-3">选项1</el-menu-item>
        </el-submenu>

        <!-- 没有子标题 -->
        <el-menu-item index="2">
            <i class="el-icon-menu"></i>
            <span slot="title">导航二</span>
        </el-menu-item>
    </el-menu>

 

    注解:
        1、el-menu标签:包裹菜单栏
        2、el-submenu标签:包裹二级路由
        3、el-menu-item标签:只有自己,没有子级
        4、template标签:二级路由的标题

 

        配置项:
            default-active="2"          默认选中的index项 
            @open="handleOpen"          打开的时候触发的函数
            @close="handleClose"        关闭的时候触发的函数
            active-text-color="#ffd04b" 选中文字的颜色



### SliderTabBar.vue渲染

    <template v-for="item in sliders">
        <!-- 二级路由 -->
        <el-submenu :index="item.path" :key="item.path" v-if="item.children&&item.children.length>0">
            <template slot="title">
                <i class="el-icon-location"></i>
                <span>导航一</span>
            </template>
            <el-menu-item index="1-4-1">选项1</el-menu-item>
            <el-menu-item index="1-4-2">选项1</el-menu-item>
            <el-menu-item index="1-4-3">选项1</el-menu-item>
        </el-submenu>

        <!-- 没有子标题 -->
        <el-menu-item :index="item.path" :key="item.path" v-else>
            <i class="el-icon-menu"></i>
            <span slot="title">导航二</span>
        </el-menu-item>
    </template>

 

    注意:  
        1、导航的配置项一般是后端返回的,不是前端写死的。
        2、***因为有的导航带子级路由,有的导航不带,在遍历的时候需要区分开来,可以用v-if搭配v-else使用,而v-if的优先级低于v-for,它俩不能一起用,所以在外层嵌套一层template标签用于做遍历。
        3、index是唯一标识,相当于key值。
        4、如果要使用字体图标就在前面加上i标签:<i :class="item.icon"></i>

 

### SliderTabBar.vue默认选中

    ①data中定义defaultActive变量为 /home:
        defaultActive:"/home",
    ②设置default-active的默认值为defaultActive:
        :default-active="defaultActive"
    ③*watch监听路由跳转对象:
        watch: {
            "$route":{
                handler(newValue,oldValue){
                    this.defaultActive=newValue.path;
                },
                immediate:true
            }
        }

 

### 路由切换

    SliderTabBar.vue页面,在el-menu-item标签中添加点击事件,用编程式导航跳转路由。
    ①如果有子级路由则添加 @click="handlePush(child.path)"
     如果没有子级路由则添加 @click="handlePush(item.path)"
    ②事件函数:
        methods: {
            handlePush(path){
                this.$router.push(path);
            }
        }

 

### 项目登录-mock数据模拟后台登录接口

    ①utils下新建utils.js,导出quertObject()方法,用于将url地址栏参数转成对象格式:
        export const quertObject=(url)=>{
            let queryString=url.split("?")[1];
            let obj={};
            let arr=queryString.split("&");
            for(let i=0;i<arr.length;i++){
                let key=arr[i].split("=")[0];
                let value=arr[i].split("=")[1];
                obj[key]=value;
            }
            return obj;
        }
    ②src下新建mock/index.js,模拟后端接口,定义url、请求方式为get,判断username和password是否正确:
        import Mock from "mockjs";
        import {quertObject} from "@utils/utils.js";
        /*
            登录接口
        */
        Mock.mock(/\/user\/login/,"get",(options)=>{
            let obj=quertObject(options.url);
            if(obj.username=="admin"&&obj.password=="admin"){
                return {
                    code:200,
                    data:{
                        authToken:"adfadfasf"                    }
                }
            }else{
                return{
                    code:500,
                    data:{
                        info:"用户名或密码不正确"
                    }
                }
            }
        })
    ③定义完mock数据后一定要在main.js中引入mock:
        import "@mock/index.js";
    ④utils下新建request.js,进行axios拦截:
        import axios from "axios";
        // import loading from "@plugins/Loading/index.js";
        import Vue from 'vue';
        // import loading from ""
        console.log(Vue)

        const http=axios.create({
            timeout:5000,
            withCredentials:true,// 允许携带token
            // baseUrl:""
        });

        http.interceptors.request.use(config=>{
            if(config.method=="get"){
                config.params={...config.data};
            }
            // config.headers["authToken"]=store.token;
            // 开启loading
            // loading.show();
            return config;
        },(err)=>{
            return Promise.reject(err);
        });

        http.interceptors.response.use(config=>{
            if(config.status==200){
                // 关闭loading
                // loading.hide();
                return config.data;
            }
        },(err)=>{
            return Promise.reject(err);
        });

        export default http;
    ⑤api下新建request.js,定义loginApi方法请求mock中的地址,请求方式为mock中定义的格式get,导出loginApi方法:
        import http from "@utils/request.js";

        export const loginApi=(loginModel)=>{
            return http({
                method:"get",
                url:"/user/login",
                data:loginModel
            })
        }
    ⑥Login/index.vue中引入loginApi方法,点击登录按钮时,进行数据请求,将当前填写的username和password带过去,判断返回值,如果code为200,则提示登录成功,并且保存authToken和进行路由的跳转:
        import { loginApi } from "@api/request.js";

        methods: {
            async handleLogin() {
                let data = await loginApi(this.login_model);
                if (data.code == 200) {
                    this.$message({
                        message: "登录成功",
                        type: "success",
                        onClose:()=>{
                            // 保存authToken
                            this.$store.commit("handleAuthToken",data.data.authToken);
                            this.$router.push("/home");
                        }
                    });
                }else{
                    this.$message.error(data.data.info);
                }
            }
        }
    ⑦store/index.js中,保存token(借助js-cookie插件):
        import Cookies from "js-cookie";
        state:{
            authToken:Cookies.get("token")||""
        },
        mutations:{
            handleAuthToken(state,params){
                state.authToken=params;
                Cookies.set("token",state.authToken);
            }
        }

 




posted @ 2020-03-22 10:40  吴小明-  阅读(360)  评论(0编辑  收藏  举报