我遇到的小白问题

215 阅读9分钟

因为是第一次搞前端项目,所以遇到了很多小白问题,这里我将它记录下来,希望大佬们轻喷。


Element.ui

基础布局

在基础布局Layout中,<el-col>一行的宽度是span="24",分出更多的列是在这24中分成12+12,8+8+8等


Vuex


Vue-router

路由参数

  1. 动态路径参数,使用$router.params定义的参数是在路由路径中表示,例如:/user/:id,通过$router.params.id获取
  2. 使用查询字符串形式,路径类似/path?key=value,使用$router.query.key的方式获取查询字符串的参数
  3. 在Vue-router的定义中包含meta,例如下面展示,可以通过$router.meta.参数获得具体常量值
{
    path: 'tree',
    name: 'Tree',
    component: () => import('@/views/tree/index'),
    meta: { title: 'Tree', icon: 'tree' }
}

Vue 生命周期

created

created应该是一个函数(function) 已完成以下的配置:数据观测 (data observer),属性和方法的运算,watch/event 事件回调。然而,挂载阶段还没开始,$el 属性目前不可见。(所以,可以从服务器请求数据了)

mounted

el挂载到实例上后调用

beforeDestroy

实例销毁前调用,一般用于解绑adEventListener监听的事件


Vue组件

数组更新方法

Vue 包含一组观察数组的变异方法,所以它们也将会触发视图更新。这些方法如下:

  • push()
  • pop()
  • shift()
  • unshift()
  • splice()
  • sort()
  • reverse()

由于 JavaScript 的限制,Vue 不能检测以下变动的数组:

  • 当你利用索引直接设置一个项时,例如:vm.items[indexOfItem] = newValue
  • 当你修改数组的长度时,例如:vm.items.length = newLength

组件创建和注册

// 1.创建组件
let myComponent = Vue.extend({
	template: '<div>Some Component</div>'
}); 
// 2.注册组件
Vue.component('my-component', myComponent);

在Vue.extend()参数传入的是选项对象,自己创建的组件需要包含在Vue实例挂载的元素范围内。在Vue.component()注册的组件是全局的,可以在任意Vue实例范围内使用。
局部注册如下:

 var myComponent = Vue.extend({
      template: '<div>This is my first component!</div>'
})
        
new Vue({
     el: '#app',
     components: {
      // 2. 将myComponent组件注册到Vue实例下
           'my-component' : myComponent
     }
});

因为html是大小写不敏感的,所以组件名称不要写为大写。
Vue.js规定:在定义组件的选项时,data和el选项必须使用函数。

父组件和子组件通信

在父组件中使用子组件时,通过以下语法将数据传递给子组件:

<child-component v-bind:子组件prop="父组件数据属性"></child-component>

其中在父模板中属性名要使用中划线写法,比如以下的父模板:

var parentNode = {
  template: `
  <div class="parent">
    <child my-message="aaa"></child>
    <child my-message="bbb"></child>
  </div>`,
  components: {
    'child': childNode
  }
};

子模板的代码如下:

var childNode = {
  template: '<div>{{myMessage}}</div>',
  props:['myMessage']
}

v-ref

$children


Vue.js常用指令

  • v-if
  • v-show
  • v-for
  • v-bind
  • v-on
  • v-else

v-for

v-for中,可以使用$index来获取v-for循环到第几个了,从0开始计数

<ul>
    <li v-for="item in items">
         {{item}}
         <button v-on:click="printIndex($index)">Index</button>
    </li>
</ul>

v-show

在不满足条件时,使用v-show的指令会被添加css的style="display: none;"

v-else

必须跟在v-show或者v-if后面

v-bind

将这个元素绑定一个HTML元素特性,这个绑定行为是需要表达式运算后得的

标准形式: v-bind:argument="expression"
例如:<a href="#" v-bind:class="2>1?'ss':''"></a>

运行后因为2>1,则html为

<a href="#" class="ss"></a>

v-on

监听DOM事件,标准形式和v-bind差不多

v-bind和v-on缩写

v-bind缩写为一个冒号,v-on缩写为@符号

<!--完整语法-->
<a href="javascripit:void(0)" v-bind:class="activeNumber === n + 1 ? 'active' : ''">{{ n + 1 }}</a>
<!--缩写语法-->
<a href="javascripit:void(0)" :class="activeNumber=== n + 1 ? 'active' : ''">{{ n + 1 }}</a>

<!--完整语法-->
<button v-on:click="greet">Greet</button>
<!--缩写语法-->
<button @click="greet">Greet</button>

v-bind:is动态组件

<!-- 组件会在 `currentTabComponent` 改变时改变 -->
<component v-bind:is="currentTabComponent"></component>

ES6语法问题

正则表达式

在 JavaScript中,正则表达式也是对象。这些模式被用于 RegExp 的 exec 和 test 方法, 以及 String 的 match、replace、search 和 split 方法

Promise

Promise对象是一个构造函数,用来生成Promise实例,其中接收一个函数作为参数

//1. 原型
const promise = new Promise(一个函数)
//2. 具体
const promise = new Promise(function(resolve, reject) {
	//这里执行具体的异步操作
    //Some Code
    if (异步操作成功) {
    	resolve(value);
    } else {
    	reject(error);
    }

在这个if语句之前promise的状态都是pending,然后执行resolve时变为resolved,说明异步操作成功。而操作失败调用reject,promise的状态由pending变为rejected。
可以通过then来分别指定reject和resolve函数

//1. 传入指定函数
promise.then(resolve, reject); //reject函数是可选的
//2. 匿名函数
promise.then(function(value) {
	//这个函数是异步操作成功时调用的resolve函数
    // some code
 }, function(error) {
    //异步操作失败时调用的reject函数
    // some code
 };

promise是之前用Promise构造函数生成的。


在使用then之后,会返回一个新的Promise实例,这时当前then返回的值会作为下一个then的resolve函数的参数
//1.不包括对错误的处理行数reject
promise.then(function(value) {
	return someValue;
}).then(function(value) { //这时的value就是之前的someValue
	//some code
});
//2.包括reject函数处理
promise.then(
	function(value) { // resolve
    	return someValue;
    }				  //reject省略
).then(
	function(value) { //resolve
    	//some code
    },
    function(error) { //reject
    	//some code
    }
);

只要是Promise就能在里面执行异步操作,Promise就相当于异步操作的容器
catch函数是then(null, rejection)别名,Promise的错误具有冒泡性,会一直往下传递,知道被catch捕获

Concise Properties(对象字面量扩展)

当对象属性和语法标识符相同时,可以被简写。

  var x = 2, y = 3;
  var o = {
      x: x,
      y: y
  }

下面的代码段和上面的相同

  var x = 2, y = 3;
  var o = {
      x,
      y
  }

箭头表达式

基础语法

  1. (参数1,...,参数N) => {函数体}
  2. 单一参数 => {函数体}

例子:

> var a = b => {return b+1;}
> a(3)
4

这个函数a就是以b为参数将b加一后返回。参考

高阶函数

函数闭包

function add(a) {
    return function(b) {
        return a + b
    }
}

var add3 = add(3)
add3(4) === 3 + 4 //true

相当于在ES6中写法为多个箭头符号:

let add = a => b => a + b

定义类

注意,定义“类”的方法的时候,前面不需要加上function这个关键字,直接把函数定义放进去了就可以了。另外,方法之间不需要逗号分隔,加了会报错。

//定义类
class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }

  toString() {
    return '(' + this.x + ', ' + this.y + ')';
  }
}

在类内定义函数

var SomeObject = {
	[AFunc]:function(){
		return 123;
    }
}
//使用
> SomeObject[AFunc]()
123

这样有一个对象叫SomeObject,有一个方法叫AFunc

CSS

inherit关键字

某个属性将这个关键字作为值,则属性会继承父类的属性

span
{
color: blue;
}

.extra span
{
color: inherit;
}

选择最后一个子元素

:last-child选择权

p:last-child
{ 
	background:#ff0000;
}

等同于:nth-last-child(1)

p:nth-last-child(1)
{ 
background:#ff0000;
}

p:nth-last-child(2)选择倒数第二个

变量作用域

function square(num) {
 total = num * num;
 return total;
}
var total = 50;
var number = square(20);
alert(total);

在这里因为函数square里的total没有用var来声明,则会改变total的值,在定义一个函数时,我们一定要把它内部的变量全部明确声明为局部变量

DOM 选择器

  • getElementsByTagName:可以使用通配符,网页中所有元素都会被返回在返回数组中document.getElementByTagName("*")
  • getElementsByClassName:使用这个方法可以查找带有多个类名的元素document.getElementsByClassName("import sale")

在HTML5提供了强大的原生类CSS选择器querySelectorquerySelectorAll

document.querySelector("div.test>p:first-child");
document.querySelectorAll("div.test>p:first-child")[0];

通过obj.setAttribute("属性")设置的属性不会改变网页源代码,因为DOM的工作模式:先加载文档静态内容,再动态刷新,动态刷新不影响文档的静态内容。DOM能够对页面内容进行改变(刷新)却不需要在浏览器里刷新页面

nodeType属性

通过元素.childNodes获得元素的所有子元素,这其中不单单包括<p>这种,还包括属性节点和文本节点,他们的nodeType不同。

  • 元素节点nodeType属性值为1
  • 属性节点nodeType属性值为2
  • 文本节点nodeType属性值为3

如果JS文件或者代码在HTML文档的<head><script>中定义调用的,他会在HTML文档之前被加载到浏览器,此时没有完整的DOM就不能进行DOM选择。需要在元素全部加载后再运行,即window.onload事件中定义回调函数。

阻止默认事件行为

阻止a标签click后跳转到链接

<a id="ss" onclick="fff(this); return false;" href="127.0.0.1">Link!</a>

html5 history api

使用 back(), forward() 和 go() 方法来完成在用户历史记录中向后和向前的跳转。

window.history.back()

HTML5引入了 history.pushState() 和 history.replaceState() 方法,它们分别可以添加和修改历史记录条目。这些方法通常与window.onpopstate 配合使用。猜测路由的原理是history.pushState然后触发window.onpopstate事件,然后重新渲染相关局部页面,还有拦截<a>默认的跳转操作(Todo:还需要了解Vuex源码)

Math.ceil Math.floor Math.round

Math.ceil是向上取整, Math.floor是向下取整,Math.round是四舍五入。

> var a = 14/47
> var a = a*100
> a
29.78723404255319
> Math.ceil(a)
30
> Math.round(a)
30
> Math.floor(a)
29

javascript继承

比如一个构造函数SS

function SS() {
    this.name = "ss"
}

一个父类构造函数DD

function DD() {
    this.ddd = "ff"
}

那么如果需要SS构造出来的对象能够继承DD中的方法和属性,就需要prototype指定DD函数创建出来的对象

>SS.prototype = new DD()
>var ss = new SS()
>ss.ddd
ff

小细节

setTimeout和setInternval

在使用完后必须调用clearInterval和clearTimeout来清除定时器。在HTML5规范中规定定时器的定时时间不能小于4ms,如果是小于4ms,则默认为4ms,所以在这个例子中的0,默认的是4ms。定时器计时的线程和js引擎执行线程不一样,当计时器到时会被加入js引擎执行线程的事件队列等待执行, 所以计时到时后,不是等到你回调函数执行完才开始再次计时,而是加入事件队列后就开始在计时线程里计时了参考

json支持的类型

类型 描述
数字型(Number) JavaScript 中的双精度浮点型格式
字符串型(String) 双引号包裹的 Unicode 字符和反斜杠转义字符
布尔型(Boolean) true 或 false
数组(Array) 有序的值序列
值(Value) 可以是字符串,数字,true 或 false,null 等等
对象(Object) 无序的键:值对集合
空格(Whitespace) 可用于任意符号对之间
null

后端

flask-cros解决跨域问题

安装flask-cros

from flask_cors import CORS
app = Flask(__name__)
CORS(app, supports_credentials=True)

post得到bad request ,http code 400

这是因为我在前端用axios中设置为json类型发送请求,所以在后端POST的表单来接收就是错误的,因为发送到后端的http头部信息中Accept: application/json,所以在POST的处理函数用需要使用request.get_json()

@app.route('/detail', methods=["POST"])
def get_event_detail():
    data = request.get_json()

mysql数据库配置

对于mysql,默认配置/etc/mysql/my.conf中是bind-address = 127.0.0.1,所以如果需要远程访问mysql需要改为存放mysql服务器的IP地址。可以通过执行下面语句来查看,如果没修改前mysql只会监听来自本机的IP地址

> netstat -an | grep 3306

同时需要修改远程访问用户的权限,比如用户snort,密码snort,数据库snort。需要执行下面的命令

grant all privileges on snort.* to snort@'%' identified by "snort";

mysql数据库使用

选择语句中添加distinct去除重复的结果

select distinct ip_dst from iphdr;

自然连接:只考虑那些在两个关系模式中都出现的属性上取值相同的元素对。

使用between表示某个值在一个范围内

select name from instructor where salary between 9000 and 10000;

获取从n开始m条记录:

select * from table_name limit n, m; -- n是开始位置,m是偏移量,可以实现分页

集合操作

SQL在关系上的操作union、intersect、except分别对应数学集合论中的并集、交集、差运算

git配置代理

使用socks5代理,端口是1080,地址是127.0.0.1

git config --global http.proxy socks5://127.0.0.1:1080 
git config --global https.proxy socks5://127.0.0.1:1080 

查看git config配置信息

git config --list