工作笔录

Created
Jun 6, 2022 03:08 PM
Tags
简介

6.6

传给后端的数据,有多种数据模式:表单,json
练习前端向后端发不同类型的数据
前端自搭服务experss
express --view=pug myapp
$ cd myapp
$ npm install
$ DEBUG=myapp:* npm start //ios
set DEBUG=myapp:* & npm start //windows
PS> $env:DEBUG='myapp:*'; npm start
前端配置
vue create hello-world

cd admin

npm install axiso -- save

新建一个文件夹 model 用来集中处理 与后端交互的逻辑

//request.js 用来封装axios 
import axios from 'axios'

// 添加响应拦截器
axios.interceptors.response.use(res => {
  return res.data
}, error => {
  return Promise.reject(error)
})

export default {
  post: function (url = '', data = {}, config) {
    return axios.post(url, data, config)
  },
  put: function (url = '', data = {}, config) {
    return axios.put(url, data, config)
  },
  get: function (url, params = {}, config) {
    const OPTIONS = Object.assign({ params }, config)
    return axios.get(url, OPTIONS)
  },
  delete: function (url = '', params = {}, config) {
    const OPTIONS = Object.assign({ params }, config)
    return axios.delete(url, OPTIONS)
  }
}
//api.js 统一 加个 /api 前缀 作用 区分一下/
const PREFIX = '/api'
export default {
  send: PREFIX + '/send'
}

//about.js ==> 某个页面下的所有 请求!!!
import request from './request.js'
import API from './api.js'


export default {
  sendMessage (params) {
    return request.get(API.send, params)
  },
  login (params) {
    return request.post(API.login, params)
  },
  logout () {
    localStorage.clear()
  },
  list () {
    return request.get(API.user)
  },
  update (id, params) {
    return request.put(API.userItem(id), params)
  },
  add (params) {
    return request.post(API.user, params)
  },
  delete (id) {
    return request.delete(API.userItem(id))
  }
}
vue.config.js
module.exports = {
    // 开发环境下的代理地址
    devServer: {
        proxy: 'http://localhost:3000'
    },
    // 静态资源打包地址
    outputDir: '../public/admin',
    // HTML 打包地址
    indexPath: process.env.NODE_ENV === 'production'
        ? '../../views/admin.tpl'
        : 'admin.tpl',

    // 部署应用包时的基本 URL
    publicPath: process.env.NODE_ENV === 'production'
        ? '/admin/'
        : '/',
}
配置axios
request.js

import axios from 'axios'

// 添加响应拦截器
axios.interceptors.response.use( res => {
  return res.data;
}, error => {
  return Promise.reject(error)
})

export default {
  post: function (url='', data={}, config) {
    return axios.post(url, data, config);
  },
  put: function (url='', data={}, config) {
    return axios.put(url, data, config);
  },
  get: function (url, params={}, config) {
    let OPTIONS = Object.assign({ params }, config);
    return axios.get(url, OPTIONS)
  },
  delete: function (url='', params={}, config) {
    let OPTIONS = Object.assign({ params }, config);
    return axios.delete(url, OPTIONS)
  }
}
 
express 后端 配置
文件夹 controllers
index.js
const sendController = {
  send:async function(req, res) {
    const { name } = req.body;
    console.log(req.body)
    res.send('ok');
  }
}
module.exports = sendController;

routes
api.js
var express = require('express');
var router = express.Router();
var sendController = require('./../controllers/index');

/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index', { title: 'Express' });
});

router.get('/send', sendController.send);

module.exports = router;

app.js
var indexRouter = require('./routes/index');
var apiRouter = require('./routes/api');

app.use('/', indexRouter);
app.use('/api',apiRouter);
token(判断是否登录)
//登录时
localStorage.setItem('token',token);

//退出登录
localStorage.clear();
this.$router.replace({ name: 'Login'});//跳去登录页

//导航守卫
appRouter.beforeEach((to, from, next) => {
    //NProgress.start();

    let hasToken = localStorage.getItem('token') ? true : false;
    if(to.name === 'Login' && hasToken){
      next({name: 'Article'})
    }
    if(to.name !== 'Login' && !hasToken){
      next({name: 'Login'})
    }
    next();
})

0607

npm 合并多条命令 用&
"scripts": {
    "serve": "vue-cli-service lint & vue-cli-service serve ",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint"
  },

npm run serve 报错
可以谷歌一下报错内容
可能这样子可以解决:
删除 node_modules yarn-lock
然后该用 yarn install + yarn run serve
 
最近 npm run build :ERROR: ErrorStackParser.parse is not a function

0608

GitHub Copilot could not connect to server. Extension activation failed: "connect ECONNREFUSED 127.0.0.1:443”
hosts
140.82.112.5 github.com
140.82.112.5 api.github.com

或者 修改 dns
8.8.8.8

0609

vue暂存页面数据,深度(如:页面中有翻页的表格)

data () {
    const stash = LocalStrage.getItem('stash')
    return Object.assign({ a: 1, b2 }, stash)
  },
  methods: {
    stash () {
      localStorage.setItem('satsh', JSON.stringify(this.$data))
    }
  }
后端的增删改查
const knex = require('./knex');

class Base {
  constructor(props) {
    this.table = props;
  }

  all(){
    return knex(this.table).select()
  }

  select(params) {
    return knex(this.table).select().where(params)
  }

  insert(params){
    return knex(this.table).insert( params )
  }

  update(id, params ){
    return knex(this.table).where('id', '=', id).update( params )
  }

  delete(id){
    return knex(this.table).where('id', '=', id).del()
  }
}

module.exports = Base;

0612

快速上手前端框架
1.数据从哪里来
2.数据怎么展示
3.展示效果如何美化
4.用户的交互如何处理
 
关于工作中的规范,项目思路,别人的开源
关于SmartAdmin
简介 SmartAdmin由河南·洛阳 团队研发的一套互联网企业级的通用型中后台解决方案!使用最前沿的前后台技术栈SpringBoot和Vue,前后端分离, 我们开源一套漂亮的代码和一套整洁的代码规范 ,让大家在这浮躁的代码世界里感受到一股把代码写好的清流!同时又让开发者节省大量的时间,减少加班,快乐工作,热爱生活。SmartAdmin 让你从认识到忘不了,绝对是你最想要的! 开源地址 (欢迎 Star ~ ~ ╰( ̄▽ ̄)╭) 疑惑 有人问:又是个"轮子"? 轮子靠谱吗?为什么要选择你这个轮子? 1024Lab 回答: 它不是"轮子",目的不是为了重复造轮子! 我们开源的是一套 "漂亮的代码" 和 "代码规范"。 理念与思想 我们分享的不是代码,不是徒劳无功的堆砌功能,而是你必须的基础功能,比如Vue前端权限、心跳、动态Reload、Keepalived标签页等等,可能还有一些正是你当前项目中缺失的功能。 我们分享的不仅有代码,还有一套经过几十人验证过的前、后端代码。细节决定成败,好的规范能让我们敲下的每行代码更铿锵有力! 我们推崇高质量的代码,身为开发,代码即利剑,键盘上一套行云流水,宛如侠客,事了拂衣去,深藏身与名。 我们推崇团队的高度配合默契、互相帮助,从不加班,而不是一看到别人的代码就头皮发麻,留其996.ICU 我们热爱编程,热爱代码,保持谦逊,不断学习,快乐工作,热爱生活。 请相信并认真阅读下面的每一个点,让你感受不一样的编码体验 演示图 技术体系 前端:Vue + Vue-Router + Vuex + ViewUI + vue-enum 后端:SpringBoot2 + Mybatis-plus + jwt + druid + mysql 前端代码规范smart-front-standard -guide(大力推荐) 基于阿里规范之上的后端规范smart-backend-standard-guide(大力推荐) 前端特点 高质量的代码、代码结构、和代码注释 漂亮的UI,菜单栏、标签页,体验、交互更好用的员工、部门、角色、菜单管理等等 优化基于Keepalive的标签页,做到标签页该缓存的时候缓存,比如左右切换等,不该缓存的时候不缓存,比如新建,表单提交结束等 前端常量维护: vue-enum,拒绝出现魔法数字,代码不可维护的现象 全新的基于前端的权限设计(忘掉传统的权限设计吧,已经不适合这个前端时代) 基于websocket的在线人数 支持一级、二级、三级菜单,四级菜单以及搜索功能 其他功能:邮件、富文本、消息、系统配置等等 写不完了,太多好的细节需要你的发现......
关于SmartAdmin
 
0614
枚举vue
//common/enum.js

// 定义symbol
const _flag = Symbol("flag");

/**
 * 枚举类
 * @author liujing
 */
export default class Enum {
  constructor(flag) {
    if (flag != undefined && flag == _flag) {
      return;
    }
    //获取所有的成员变量
    let objList = this.__proto__.constructor;
    //用来装载枚举类型与变量值
    let enumList = [];
    let infoList = [];
    //遍历
    for (let obj in objList) {
      //判断对象是否为Array类型,把数组和值进行分离
      if (objList[obj] instanceof Array) {
        enumList.push(obj);
      } else {
        infoList.push(obj);
      }
    }
    //创建所有的枚举对象
    for (let i = 0; i < enumList.length; i++) {
      //枚举对象数组值
      let enumObj = objList[enumList[i]];
      //判断数组值是否与变量长度匹配,不匹配直接抛出异常
      if (enumObj.length != infoList.length) {
        throw new Error(enumList[i] + " 对象实例化失败:枚举参数不匹配");
      }
      //创建枚举对象,使用falg标志防止重复创建
      let obj = new Enum(_flag);
      //设置枚举值
      for (let x = 0; x < infoList.length; x++) {
        obj[infoList[x]] = enumObj[x];
      }
      //挂载到this上
      console.log(enumList[i]);
      this[enumList[i]] = obj;
    }
    //防止被修改
    Object.freeze(this);
  }
}

commont/UserStatusEnum
import Enum from "@/common/Enum.js";

class UserStatusEnum extends Enum {
  /**
   * 枚举对象
   */
  static NORMAL = [1, "正常"];
  static DISABLE = [0, "禁用"];

  /**
   * 状态编码
   */
  static code;

  /**
   * 状态描述
   */
  static desc;
}

const obj = new UserStatusEnum();

export default obj;


// import UserInfoEnum from "./../src/common/UserStatusEnum";

0618

<template>
    <div :class="classes">
        <slot></slot>
    </div>
</template>
<script>
    const prefixCls = 'ivu-collapse';
    export default {
        name: 'Collapse',
        props: {
            accordion: {
                type: Boolean,
                default: false
            },
            value: {
                type: [Array, String]
            },
            simple: {
                type: Boolean,
                default: false
            }
        },
        data () {
            return {
                currentValue: this.value
            };
        },
        computed: {
            classes () {
                return [
                    `${prefixCls}`,
                    {
                        [`${prefixCls}-simple`]: this.simple
                    }
                ];
            }
        },
        mounted () {
            this.setActive();
        },
        methods: {
            setActive () {
                const activeKey = this.getActiveKey();
                this.$nextTick(() => {
                    this.$children.forEach((child, index) => {
                        const name = child.name || index.toString();
                        child.isActive = activeKey.indexOf(name) > -1;
                        child.index = index;
                    });
                });
            },
            getActiveKey () {
                let activeKey = this.currentValue || [];
                const accordion = this.accordion;
                if (!Array.isArray(activeKey)) {
                    activeKey = [activeKey];
                }
                if (accordion && activeKey.length > 1) {
                    activeKey = [activeKey[0]];
                }
                for (let i = 0; i < activeKey.length; i++) {
                    activeKey[i] = activeKey[i].toString();
                }
                return activeKey;
            },
            toggle (data) {
                const name = data.name.toString();
                let newActiveKey = [];
                if (this.accordion) {
                    if (!data.isActive) {
                        newActiveKey.push(name);
                    }
                } else {
                    let activeKey = this.getActiveKey();
                    const nameIndex = activeKey.indexOf(name);
                    if (data.isActive) {
                        if (nameIndex > -1) {
                            activeKey.splice(nameIndex, 1);
                        }
                    } else {
                        if (nameIndex < 0) {
                            activeKey.push(name);
                        }
                    }
                    newActiveKey = activeKey;
                }
                this.currentValue = newActiveKey;
                this.$emit('input', newActiveKey);
                this.$emit('on-change', newActiveKey);
            }
        },
        watch: {
            value (val) {
                this.currentValue = val;
            },
            currentValue () {
                this.setActive();
            }
        }
    };
</script>

//个人实现版

<template>
  <div id="app">
    <div
      class="contaninger"
      @click="handlerOpenOrClose(index, true)"
      v-for="(item, index) in list"
      :key="index"
    >
      {{ item.name }}
      <p class="p1" v-if="item.isShowP">收起</p>
      <p class="p2" v-else>展开</p>
    </div>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      list: [
        {
          name: "p1",
          value: "p1",
          isShowP: false,
        },
        {
          name: "p2",
          value: "p2",
          isShowP: false,
        },
        {
          name: "p3",
          value: "p3",
          isShowP: false,
        },
        {
          name: "p4",
          value: "p4",
          isShowP: false,
        },
      ],
      clickList: [],
    };
  },
  methods: {
    handlerOpenOrClose(index, isShowP) {
      console.log(JSON.parse(JSON.stringify(this.clickList)), "点击前");

      const list = [...this.clickList];

      if (list.length === 0) {
        console.log("第一次点击");
        this.list[index].isShowP = isShowP;
        list.push(index);
      } else {
        list.push(index);

        if (list[0] === index) {
          console.log("重复点击");
          this.list[index].isShowP = !this.list[index].isShowP;
          list.shift();
        } else {
          console.log("点击其他");
          this.list[index].isShowP = isShowP;
          this.list[list[0]].isShowP = false;
          list.shift();
        }
      }

      this.clickList = list;

      console.log(JSON.parse(JSON.stringify(this.clickList)), "点击后");
    },
  },
};
</script>

<style scoped>
.contaninger {
  width: 100%;
  background: rgb(51, 102, 232);
  opacity: 0.5;
  margin: 10px auto;
  text-align: center;
  color: #fff;
}
.p1 {
  height: 100px;
}
.p2 {
  height: 50px;
}
</style>
0621
eventbus +router
路由切换时==》
新組件: beforeCreate 新組件: created 新組件: beforeMount 旧組件: beforeDestroy 旧組件: destroy 新組件: mounted
<template>
  <div class="about">
    <h1>This is an about page</h1>
    <button @click="eventhandler">发送</button>
  </div>
</template>
<script>
import { EventBus } from '@/until/event.js'

export default {
  name: 'About',
  data () {
    return {
      msg: 'jjj js!'
    }
  },
  methods: {
    eventhandler () {
      console.log('send')

      this.$router.push('/')
    }
  },
  destroyed () {
    EventBus.$emit('send', this.msg)
  }
}
</script>


<template>
  <div class="home">
    {{ msg }}
  </div>
</template>

<script>
// @ is an alias to /src

import { EventBus } from '@/until/event.js'

export default {
  name: 'Home',
  components: {},
  data () {
    return {
      msg: 'Hello Vue!'
    }
  },
  created () {
    console.log('djjdd')
    EventBus.$on('send', (msg) => {
      this.msg = msg
      console.log(msg)
    })
  }
}
</script>

import Vue from 'vue'
export const EventBus = new Vue()