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.80609
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.用户的交互如何处理
关于工作中的规范,项目思路,别人的开源
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()


