卖座后台管理系统----体系

2019-10-22

卖座后台管理系统知识体系

目录

  1. vue-cli3 创建项目(略)

  2. 重置样式和公共样式(略)

  3. 路由配置(略)

  4. 使用饿了么 ui 库,请看文档(略)

  5. 布局组件(已完成)

  6. vue 原生点击事件(已完成)

  7. vuex

  8. axios 拦截器(完成一半)

  9. 打包部署项目

  10. active-class

  11. 父子组件通信

  12. vue-cli3 脚手架配置

五、布局组件

  1. 拷贝饿了么的布局容器
  2. 展开侧边栏的设置 :default-openeds 设置
  3. 样式调整
    • layout 组件设置 padding-top
    • 头部调整(固定定位)
    • 侧边栏 html=>body=>#app>div>aside 高度全部设为 100%

六、vue 原生点击事件

在组件上添加事件的时候需要添加修饰符。native 来绑定事件,比如

  <el-submenu index="2" @click.native="open('2')"></el-submenu>

八、axios 拦截器

文档地址:http://huruqing.cn/docs/Vue/advance/02.axios.html

  1. 在新建 /utils/request.js

  2. 使用 axios 创建实例,配置 baseUrl 和超时时间

    const service = axios.create({
        // 配置基本的路径
        baseURL: 'http://132.232.87.95:3000/admin',
        timeout: 5000 // 请求超时时间(因为需要调试后台,所以设置得比较大)
    })
    
  3. response 拦截器让我们在请求成功之后,统一做某些处理(完整的代码请看项目)

    // response 拦截器
    service.interceptors.response.use(res => {
            if (res.data.code == 666) {
                return res.data
            } else {
                return Promise.reject(res.data.msg);
            }
        },
        error => {
            return Promise.reject(error)
        });
    
    export default service;
    
  4. 把 axios 挂载在 Vue 的原型上

import $axios from '@/utils/request';
Vue.prototype.$axios = $axios;
  1. 发送请求只需要这样写
let url = "/city/getList";
this.$axios
    .get(url)
    .then(res => {
    this.list = res.cities;
    console.log(res.cities);
})
    .catch(err => {
    console.log(err);
});

九、打包部署项目(上线)

  1. 全局变量 process.env

    let env = process.env.NODE_ENV;
    let baseURL = '';
    // 开发环境
    if (env === 'development') {
        baseURL = 'http://jun.huruqing.cn:3000/admin';
    } else {
        // 生产环境
        baseURL = 'http://jun.huruqing.cn:3000/admin';
    }
    

    web04 班因为条件限制,所以,开发和生产用同一套代码

  2. 配置打包路径和资源访问路径

    • 新建 /vue.config.js, 代码如下

      // 以陈灿为例
      module.exports = {
           // 资源路径
          publicPath: '/maizuo/chencan/',
          // 打包路径
          outputDir: 'chencan',
          // 关闭eslint检查
          lintOnSave: false
      }
      
  3. 执行 npm run build 命令,然后把生成的文件夹 chencan 上传到 jun.huruqing.cn/maizuo/

十、路由表和侧边栏配置

  1. 导出路由数组

    export const routes = [];
    
  2. 导入路由数组

    import {routes} from '@/router/index'
    
  3. item.meta && item.meta.title => && 左边为 false 的时候,不会继续执行

  4. 设置默认值

    function test(data) {
     data = data || {};
     console.log(data.aa);
    }
    

十一、路由守卫

  1. 配置全局路由守卫

    let routes = [];
    let router = new Router({
        routes
    })
    
    router.beforeEach((to, from, next) => {
        // 修改网页标题
        document.title = to.meta.title;
        next();
    })
    
    export default router;
    
    • to: Route: 即将要进入的目标 路由对象
    • from: Route: 当前导航正要离开的路由
    • next
  2. 利用路由守卫让没登录的时候,不管访问什么页面都调到登录页面

// 获取登录状态isLogi的值 this.$store.state
import store from '../store/index';

router.beforeEach((to, from, next) => {
    // console.log('登录状态', store.state.isLogin);
    // 修改网页标题
    document.title = to.meta.title;

    let isLogin = store.state.isLogin;
    debugger;
    // 如果没登录,并且去的页面不是登录页面, 就跳转到登陆页面
    if (!isLogin && to.path !== '/login') {
        next('/login');
    } else {
        next();
    }
})

export default router;

十二、级联组件的使用 (影院模块的制作)

  1. 覆盖饿了么的样式

    • 给组件起一个不会重复的 class, 模块名 + 组件名,比如

      <div class="cinema-add">   // cinema模块的add组件
      
    • 使用两个 style, 一个加 scoped, 另外一个不加

    • 覆盖饿了么组件样式

      <style lang="less">
      .cinema-add {
           .el-cascader {
              display: block;
          }
      }
      </style>
      

      // 下面的 style 用来写本组件的样式

      <style lang="less" scoped>
      
      </style>
      
    1. Promise.all, 同时发多个请求

      // promise1,promise2都是promise对象
      Promise.all([promise1,promise2]).then(res=> {
        // res是一个数组,返回两个promise的数据
      })
      
      // 获取城市列表和地区列表
      getList() {
          let cityUrl = '/city/allCity';
          let areaUrl = '/area/allArea';
          // 获取城市列表的promise
          let cityPromise = this.$axios.get(cityUrl);
          // 获取地区列表的promise
          let areaPromise = this.$axios.get(areaUrl);
      
          Promise.all([cityPromise,areaPromise]).then(res=> {
              console.log(res);
          }).catch(err=> {
              this.$message.error(err);
          })
      },
      
    2. 把城市列表和地区列表编程级联组件需要的数据格式

       getList() {
            let cityUrl = "/city/allCity";
            let areaUrl = "/area/allArea";
            // 获取城市列表的promise
            let cityPromise = this.$axios.get(cityUrl);
            // 获取地区列表的promise
            let areaPromise = this.$axios.get(areaUrl);
            Promise.all([cityPromise, areaPromise])
              .then(res => {
                //   console.log(res);
                // 把城市列表和地区列表编程级联组件需要的数据格式
                let cityList = res[0].cities;
                let areaList = res[1].areas;
      
                let newCityList = cityList.map(city => {
                  // 找出城市对应的地区列表
                  let newAreaList = areaList.filter(area => {
                    return area.cityId === city.cityId;
                  });
                  // 地区列表变成组件需要的数据结构
                  newAreaList = newAreaList.map(area=> {
                      return {
                          value: area.areaId,
                          label: area.name
                      }
                  })
      
                  return {
                    value: city.cityId,
                    label: city.name,
                    children: newAreaList
                  };
                });
              //   console.log(newCityList);
                this.options = newCityList;
              })
              .catch(err => {
                this.$message.error(err);
              });
      
      1. 级联组件添加清空,搜索,禁用

      2. 子组件向父组件传数据

        • 父组件自定义事件

           <Address @getAddress="getAddress"></Address>
          
           getAddress(data) {
               console.log('父组件收到的数据',data);
           },
          
        • 自组件通过 $emit 触发父组件定义的自定义事件

          handleChange(value) {
              this.$emit('getAddress',value);
          }
          

十三、请求的 loading 和 axios.finally

.finally 不管请求成功或失败都会执行回调

cinemaDetail(cinemaId) {
    let loading = this.$loading({
        lock: true,
        text: "努力加载中...",
        background: "rgba(0, 0, 0, 0.7)"
    });
    let url = "/cinema/getDetail2?cinemaId="+ cinemaId;
    this.$axios.get(url).then(res => {
        console.log(res);
    }).catch(err => {
        this.$message.error(err);
    }).finally(()=> {
        loading.close();
    })
},

十四、动态路由配置

例子 1:

// 路由配置
  {
      path: 'edit/:cinemaId',
      meta: {
      title: 'edit'
      },
      component: () => import('@/pages/demo/edit')
  },
// 页面跳转
<router-link to="/demo/edit/a1234444">去编辑</router-link>
// 获取cinemaId的值
this.$route.params.cinemaId;

例子 2: 传多个参数

// 路由配置
{
     path: 'edit/:cinemaId/:cityId/:areaId',
     meta: {
     title: 'edit'
     },
     component: () => import('@/pages/demo/edit')
 },
 // 页面跳转
 <router-link to="/demo/edit/a1234444/b234234/c1234234">去编辑</router-link>
// 获取cinemaId,cityId,areaId
let {cinemaId,cityId,areaId} = this.$route.params;

十五、添加和编辑共用同一个组件(以城市模块为例)

  1. 判断当前路由是添加还是编辑

    • 方法一:获取 cityId, 有 cityId 为编辑页面,没有则是添加页面

      this.$route.params.cityId;
      

      具体代码如下

      <template>
        <div>
          <el-button>{{isAdd?'立即添加':'立即编辑'}}</el-button>
        </div>
      </template>
      
      <script>
      export default {
        data() {
          return {
            // 是否是添加页面
            isAdd: true
          };
        },
      
        created() {
          let cityId = this.$route.params.cityId;
          this.isAdd = !!cityId ? false : true;
        }
      };
      </script>
      
    • 方法二:通过 this.$route.path 来判断

      <template>
        <div>
          <el-button>{{isAdd?'立即添加':'立即编辑'}}</el-button>
        </div>
      </template>
      
      <script>
      export default {
        data() {
          return {};
        },
      
        computed: {
          isAdd() {
            return this.$route.path.includes("add");
          }
        }
      };
      </script>
      

十六、命名规范

每个公司都有自己的命令规范,代码也有检查工具叫 eslint

  1. 文件统一大写或统一小写,跟你的同事保持一致
  2. 注意缩进
  3. 函数名一般是 动词 + 名词
  4. 函数命名和变量命名要语义化
  5. 组件名称首字母大写

十七、watch 的使用

  1. 监听路由
watch: {
  $route(newRoute,oldRoute) {
    // todo
  }
}

  1. 深层监听
 watch:{
      childrens:{
        handler:function(val,oldval){
          console.log(val.name)
        },
        deep:true//对象内部的属性监听,也叫深度监听
      },
 }

  1. 立即执行
    ``
    poster: {
    handler(newName, oldName) {
    // ...
    },
    immediate: true
    }

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 卖座后台管理系统知识体系 目录 vue-cli3 创建项目(略) 重置样式和公共样式(略) 路由配置(略) 使用饿...
    前端陈陈陈阅读 630评论 0 1
  • ## 框架和库的区别?> 框架(framework):一套完整的软件设计架构和**解决方案**。> > 库(lib...
    Rui_bdad阅读 2,973评论 1 4
  • "use strict";function _classCallCheck(e,t){if(!(e instanc...
    久些阅读 2,054评论 0 2
  • 响应式布局的理解 响应式开发目的是一套代码可以在多种终端运行,适应不同屏幕的大小,其原理是运用媒体查询,在不同屏幕...
    懒猫_6500阅读 805评论 0 0
  • http://music.163.com/#/m/song?id=108569 亲爱的lee先生: 一次偶遇,对你...
    z_白一阅读 410评论 0 0