由于是后端工程师出身,前端基本一窍不通,本文从零开始记录在项目中遇到的前端问题,注意,是遇到哪个写哪个,可能后期会整理下顺序。

ES6:

一、扩展运算符(...)

1.对象的扩展运算符

理解对象的扩展运算符其实很简单,只要记住一句话就可以:

对象中的扩展运算符(...)用于取出参数对象中的所有可遍历属性,拷贝到当前对象之中

let bar = { a: 1, b: 2 };
 let baz = { ...bar };      // 结果是{ a: 1, b: 2 }

同样,如果用户自定义的属性,放在扩展运算符后面,则扩展运算符内部的同名属性会被覆盖掉。

let bar = {a: 1, b: 2};
 let baz = {...bar, ...{a:2, b: 4}};        //  结果是{a: 2, b: 4}


利用上述特性就可以很方便的修改对象的部分属性

这里有点需要注意的是扩展运算符对对象实例的拷贝属于一种浅拷贝!!!

2.数组的扩展运算符

扩展运算符同样可以运用在对数组的操作中。

可以将数组转换为参数序列

function add(x, y) {
   return x + y;
 }const numbers = [4, 38];
 add(...numbers)           // 把数组元素作为了参数,函数返回结果是 42



可以复制数组
如果直接通过下列的方式进行数组复制是不可取的:

const arr1 = [1, 2];
 const arr2 = arr1;
 arr2[0] = 2;
 arr1    // arr1此时是[2, 2]


原因是这只是把引用赋值过去了,没有达到复制的效果,用扩展运算符就很方便:

const arr1 = [1, 2];
 const arr2 = [...arr1];


如果数组里面的所有对象都是基础数据类型,则可以将所有基础数据类型重新拷贝到新的数组中。

可以用于拼接数组

const [first, ...rest] = [1, 2, 3, 4, 5];
 first // 1
 rest  // [2, 3, 4, 5]


需要注意的一点是:

如果将扩展运算符用于数组赋值,只能放在参数的最后一位,否则会报错。

const [...rest, last] = [1, 2, 3, 4, 5];
 // 报错
 const [first, ...rest, last] = [1, 2, 3, 4, 5];
 // 报错



扩展运算符还可以将字符串转为真正的数组

[...'hello']
 // [ "h", "e", "l", "l", "o" ]

二、模块化export和import

export用于对外输出本模块(一个文件可以理解为一个模块)变量的接口
import用于在一个模块中加载另一个含有export接口的模块。
也就是说使用export命令定义了模块的对外接口以后,其他JS文件就可以通过import命令加载这个模块(文件)。

export和import(一个导出一个导入)

一个a.js文件有如下代码:

export var name="李四";

在其它文件里引用如下:

import { name } from "a.js" 
alert(name)//可以弹出来“李四”

上面的例子是导出单个变量的写法,如果是导出多个变量就应该按照下边的方法,用大括号包裹着需要导出的变量:

var name1="李四";
 var name2="张三";
 export { name1 ,name2 }

如果导出的是个函数呢,那应该怎么用呢,其实一样,如下

function add(x,y){
   alert(x*y)
}
export { add }

在其他文件里引用如下:

import { add } from "a" 
add(4,6)

export与export default

上面讲的是export和import,但是export跟export default 有什么区别呢?如下:
1、在一个文件或模块中,import可以有多个,但对export来说,要不有多个export,要不仅有一个export default(仅是猜测)
2、通过export方式导出,在导入时要加{ },export default则不需要

这样来说其实很多时候export与export default可以实现同样的目的,但是请看下边的例子。

export default {a:1}  //唯一出口就是牛B,可以输出匿名对象
import b from "a.js"   //更牛B了,可以直接给导入的匿名对象命名

VUE:

一、v-bind

v-bind  主要用于属性绑定,完整语法是v-bind:xxx="xxx",官方还提供了缩写语法:xxx="xxx",这里首先以v-bind:class为例。

这里有必须注意的点,绑定的时候,CSS属性名必须用驼峰命名法

vue:
v-bind:style="{color:activeColor, font-size:size}"
//这里用 短横分隔命名法 vue会报错,换成驼峰命名法后恢复正常,即fontSize。

js:
data:{
        activeColor:‘#f00‘,
        size:‘30px‘,
        shadow:‘5px 2px 6px #000‘
    }

我们可以绑定对象: 

vue:
v-bind:class="{‘textColor‘:isColor, ‘textSize‘:isSize}

js:
data:{

        isColor:true,

        isSize:true
 
     }

绑定对象还有另一种写法:

vue:
v-bind:class="classObject"

js:
data:{
        classObject:{
            ‘textColor‘:true,
            ‘textSize‘:false 
        }
    }

除了绑定对象还可以绑定数组

vue:
v-bind:class="[classA, classB]"
//数组和对象可以混合使用  v-bind:class="[classA, { classB: isB, classC: isC }]"


js:
data:{
        classA:‘textColor‘,
        classB:‘textSize‘
    }

最骚的是还可以绑定三目运算表达式

vue:
v-bind:class="[isA?classA:‘‘, classB]" 
//首先判断isA的boolean值,如果为true,则渲染classA;如果为false,则不渲染。classB没有做三目运算,所以是始终显示的

js:
data:{
        classA:‘textColor‘,
        classB:‘textSize‘,
        isA:false 
    }

二、v-on

v-on指令是用来绑定事件的,它也有一个简写方式@,如 @click="onClick" ,在用对象同时绑定多个事件时,不能用@代替v-on。最简单的应用如下:

vue:
<button v-on:click="onClick">点我</button>


js:
methods : {

onClick : function(){
console.log("clicked");
}

}

我们还可以同时绑定多个事件

vue:
<button v-on='{mouseenter:onEnter,mouseleave:onOut}' v-on:click="onClick">点我</button>



js:
methods : {
onClick : function(){
console.log("clicked");
},
onEnter : function(){
console.log("mouseenter");
},
onOut : function(){
console.log("mouseout");
},
}

如果我们想对原生事件对象进行处理,可以用特殊变量 $event 把它传入方法:

vue:
<button v-on:click="warn('Form cannot be submitted yet.', $event)">
  Submit
</button>



js:
methods: {
  warn: function (message, event) {
    // 现在我们可以访问原生事件对象
    if (event) event.preventDefault()
    alert(message)
  }
}

 vue提倡的是在方法中只有对数据的处理,所以提供了事件修饰符用于DOM的事件处理,常用的事件修饰符有以下几个:

(1). stop:阻止冒泡(通俗讲就是阻止事件向上级DOM元素传递)

            

js展开运算符 vue_前端

            点击内层div的结果:

                                

js展开运算符 vue_运算符_02

            点击外层div的结果:

                                

js展开运算符 vue_运算符_03

            修改代码,为内层点击事件添加事件".stop"修饰符:

                

js展开运算符 vue_js展开运算符 vue_04

            再次点击内层div的结果如下:

                   

js展开运算符 vue_后台_05

 

(2). prevent:阻止默认事件的发生

           默认事件指对DOM的操作会引起自动执行的动作,比如点击超链接的时候会进行页面的跳转,点击表单提交按钮时会重新加载页面等,使用".prevent"修饰符可以阻止这些事件的发生。

(3). capture:捕获冒泡,即有冒泡发生时,有该修饰符的dom元素会先执行,如果有多个,从外到内依次执行,然后再按自然顺序执行触发的事件。

            

js展开运算符 vue_运算符_06

            此时点击最内层div,结果如下:

                        

js展开运算符 vue_前端_07

            多个获取事件 :

                   

js展开运算符 vue_运算符_08

            点击最内层结果:

                              

js展开运算符 vue_运算符_09

   (4). self:将事件绑定到自身,只有自身才能触发,通常用于避免冒泡事件的影响

                    

js展开运算符 vue_前端_10

                此时点击最内层:

                    

js展开运算符 vue_js展开运算符 vue_11

.self和.stop区别: .self只是阻止自身不执行冒泡触发,不会阻止冒泡继续向外部触发,.stop是从自身开始不向外部发射冒泡信号

 (5). once:设置事件只能触发一次,比如按钮的点击等。

 ( 6 ). native :给vue组件(注意是vue组件,不能是原生html)绑定事件时候,必须加上native ,不然不会生效。

三、v-for

当需要将一个数组或者对象循环遍历显示的时候可以使用v-for指令,需要配合特殊语法item in items;其中items是数组或者对象,item自然就是其中的一项。

为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一key属性

当遍历数组的时候有一个可选项index,是当前项的索引 类似于 v-for = (item,[index]) in items;

当遍历对象的时候,参数是(value, key, index)

vue:
<ul id="example-1">
  <li v-for="(item, index) in items" :key="item.id">
    {{ item.message }}
  </li>
</ul>


js:
 data: {
    items: [
      { message: 'Foo' , id: 1},
      { message: 'Bar' , id: 2}
    ]
  }

四、v-if

<div id='root'>
  <div v-if='show==="a"'>this is a</div>
  <div v-else-if='show==="b"'>this is b</div>
  <div v-else>this is others</div>
//这三个也要紧贴着写,中间不能被其他所分隔
</div>


<script>
  var vm = new Vue({
    el:'#root',
    data:{
      show:'a'
    }
  })
</script>

但是有一种情况需要注意下,vuejs有一种尝试复用dom的机制,如果已经在的dom,会复用之前的dom,但是这并不是我们想要的效果,这个时候就可以给他加一个key值,告诉vuejs,这是唯一的,是不能复用的dom

<div id='root'>
  <div v-if='show'>
    用户名:<input type="text" />  //key='1'
  </div>
  <div v-else>
    邮箱名:<input type="text" />   //key='2'
  </div>
</div>


<script>
  var vm = new Vue({
    el:'#root',
    data:{
      show:false  //假设show的值变为true,发现邮箱名已经变成了用户名,但是input框还是用户名的input框
    }
  })
</script>

五、slot(插槽)

简单点来说,就是把父组件的内容插入到到子组件的对应位置。

具体看这篇博客

六、components

具体看这篇博客