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