前端开发总结 学习历程

说不上来的比后端java有意思的感觉,并且相对条理清晰。考虑自己目前的现状只是学会使用了一些基础工具软件,和在公司框架下做些功能,其实都是一知半解不懂原理,仅仅是工具的使用者。
然而在这一行想要走的远,就必须要有积累,要从底层开始理解学习,并且大部分时候,选择比努力都重要
毕业时我选了java后端,现在我换选前端。毕竟现在对前端感兴趣而兴趣是最大的老师
JS编程小技巧
2021/4/12 准备从宝信离开且转型为前端
重新学习巩固下前端的知识内容体系:

HTML/CSS/浏览器

常用H5标签:
<button>
<select>
<option>
<lable>
<div>
<input>
<form>
<iframe>
H5新标签:

1.块级元素
独占一行,对宽高的属性值生效;如果不给宽度,块级元素就默认为浏览器的宽度,即就是100%宽;
包含p、div、ul、ol、li、dl、dt、dd、h1~h6、form;
2.行内元素:
可以多个标签存在一行,对宽高属性值不生效,完全靠内容撑开宽高!
包含a、span、em、strong、b、i、u、label、br;
3.
行内块元素:结合的行内和块级的有点,不仅可以对宽高属性值生效,还可以多个标签存在一行显示

常用CSS标签:color,position 盒子模型
px、em、rem三者的联系与区别
浏览器把url变成屏幕显示的网页

  1. 浏览器首先使用 HTTP 协议或 HTTPS 协议,向服务端请求页面;
  2. 渲染引擎把请求回来的 HTML 代码经过解析,构建成 DOM 树;
  3. 计算 DOM 树上的 CSS 属性;
  4. 最后根据 CSS 属性对元素逐个进行渲染,得到内存中的位图,绘制到界面上。
  5. JS引擎读出网页JS代码并执行。
    F12浏览器调试工具devtools

POST(参数在请求体中 没有长度限制)/GET(参数在请求行中URL后 长度限制 相对不安全)
session服务器端 没有大小限制 数据安全,cookie客户端 有大小限制 相对不安全

Bootstrap:

Bootstrap中文网+案例
其他:
路径设置
浏览器对文件的加载执行
a标签中href=""的几种用法

JS基础

DOM

DOM/BOM理解与操作
DOM(Document+Object+Model文档对象模型)
DOM对象也就是JS对象
JS操作网页的接口,将网页转为一个树状结构,所有的节点都有接口.
DOM的最小单位是节点,节点的类型有七种且都继承Node。
Document(整个文档树的顶层节点),DocumentType(doctype标签),Element(网页的各种HTML标签),Attrbute(网页元素的属性),Text(标签之间或标签包含的文本),Commnet(注释), DocumentFragment(文档的片段).
在这里插入图片描述

BOM:

Brower object model 浏览器对象模型
window顶层对象,其他的BOM对象都是window对象的属性;
document(文档)、navigator(浏览器)、screen(屏幕)、location(地址)、history(历史)

ECMAscript:

数据类型

JS数据类型
基本:Number、String、Boolean、Null、undefined(undefined 是没有定义的,null 是定义了的空对象指针,string一但创建内容不可变,都有对应的类与方法)。在这里插入图片描述
虽然是一个基本类型,但是存储的时候是按照对象的方式存储的,所以基本数据类型也能调用方法:
在这里插入图片描述

引用:object(Data、function、Array)【对象其实就是一组数据和功能的集合】
ES6: Symbol 类型的对象永远不相等,即便创建的时候传入相同的值。可以用解决属性名冲突的问题。
BigInt 任意精度整数,可以安全存储和操作大整数。即始超出 Number 能够表示的安全整数范围。
注意:JavaScript 不区分整数值和浮点数值,所有数字在 JavaScript 中均用浮点数值表示,所以在进行数字运算的时候要特别注意进度缺失问题。
Number可以使用四种数字进制:十进制,二进制,八进制和十六进制。非十进制只使用于整数。
== 和 === 有什么区别?
在这里插入图片描述

对象:{}

在JS中万物皆对象,{}
对象的创建:
1、直接使用{}创建;
2、通过执行new操作符后跟要创建的对象类型的名称来创建。等效{}
3、利用构造函数。
在这里插入图片描述
对象中的属性或方法同时也是对象,也可以调用自带方法
在这里插入图片描述

构造函数创建对象:

(不需要return,创建必须使用new,构造函数类似java的类,new理解为类的实例化为对象)
在ES6中写法改变。
在这里插入图片描述

new的执行过程:

1、new构造函数 在内存中创建空对象
2、this指向刚创建的空对象
3、执行构造函数给空对象添加属性和方法
4、返回对象。(所以不需要return)

object 的每个实例都有下列属性和方法:
在这里插入图片描述

对象其实就是一组数据和功能的集合。(Data、function、Array)

例如下图
数组对象arr包括数据[1,2]
以及作为new Array的数组对象所包含的常用方法:
在这里插入图片描述
对象在创建完后,可以用=赋值,添加新的属性和方法。
在这里插入图片描述

遍历对象:

for(x in a){alert(x);alert(a[x]);} x就是对象的每一个属性名。

常用对象:

Date、Math、Array、Number、String

变量

弱类型语言,创建变量不需要申明数据类型可自动识别。
全局作用域,局部作用域(函数内),块级作用域({}内部,ES6新增特性)。

函数

函数也是对象,Function类的对象
JS中函数可作为参数传递
创建/调用方式:
(1)命名函数: function a(){} / a();
这里 a 是函数名
(2)函数表达式(匿名函数):var a = function(){} / a();
这里a是变量名,函数存在变量中
JS函数调用(4种方法)
function a(){} 和 var a = function(){}的区别

Array数组

Array 对象
在JavaScript中,常用Array来存储和操作对象:
新建:var ary = new Array(); 或 var ary = [];
增加:ary.push(value);
删除:delete ary[n];
concat() 连接两个或更多的数组,并返回结果。
join() 把数组的所有元素放入一个字符串。元素通过指定的分隔符进行分隔。
pop() 删除并返回数组的最后一个元素
push() 向数组的末尾添加一个或更多元素,并返回新的长度。
shift() 删除并返回数组的第一个元素
slice() 从某个已有的数组返回选定的元素
sort() 对数组的元素进行排序
splice() 删除元素,并向数组添加新元素。
toString() 把数组转换为字符串,并返回结果。
遍历:for ( var i=0 ; i < ary.length ; ++i ) ary[i];
for (x in ary) ary[x];

JSON

JS
1.JS对象表示类的实例
2.不能传输
3.键值对,键不加双引号,值可以是函数/对象/字符串/数字/布尔
4.Js对象转换为Json:JSON.stringify(jsobj)
JSON串
1.JSON只是一种数据格式,不存在JSON对象的概念
2.可以跨平台数据传输,速度快
3.键值对,键必须加双引号 值不能是方法函数,不能是undefined/NaN
4.Json转化为js对象:JSON.parse(jsonstring); /Jsobj=eval("("+jsonstring+")");
在这里插入图片描述

JSON按属性去重代码
JSON与JS对象的区别与对比

AJAX

async、await、promise
Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)。
不是语言,只是一种更好更快的交互技术。
应用场景例如:百度时输入搜索内容自动返回部分结果;登录提示用户密码错误等。都是在不刷新网页的前提下完成的。

案例

写一个本地数据接口
本地写接口测试

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
    <script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
    <script>
         $(function () {
            $.ajax({
                url:'http://localhost:3000/posts',
                methods:'get',
                success:function(res){
                    console.log(res);
                },
                error:function f1(err) {
                    console.log("请求失败");
                }
            })
        })
    </script>
</body>
</html>

打断点或在控制台即可看到请求成功返回的数据

核心是XHR(XMLHttpRequest)
这里直接学习Jquery AJAX,它对XHR进行了封装
jQuery.get()
jQuery.post()
菜鸟教程案例

跨域

什么是跨域?
浏览器有同源策略,不允许ajax访问其他域接口
http://www.yourname.com:80/page1.html
http端口80 https端口默认443
跨域条件:协议、域名、端口有一个不同就算跨域
(2)、可以跨域的三个标签
有三个标签允许跨域加载资源

<img src="xxx" />
<link href="xxx" />
<script src="xxx" />

status状态码说明

2xx — 表示成功处理请求,如200;
3xx — 需要重定向,浏览器直接跳转;
4xx — 客户端请求错误,如404
5xx — 服务端错误

ES6

ES6手册
阮一峰ES6
ECMAScript 6(以下简称ES6)是JavaScript语言的下一代标准。ES6是在2015年发布的。
新特性包括:

let, const:

var改为let 只在let所在代码块生效 避免作用域冲突,const声明常量

class, extends, super(this constructor)

完全可以看作构造函数的另一种简化写法。
类:一类具有相同属性和方法对象的抽象,类实例化为对象时拥有类的属性和方法。是对象的工厂。
js中关于class类的关键字的使用
ES5中的类(构造函数):

function Point(x, y) {
  this.x = x;
  this.y = y;
}

Point.prototype.toString = function () {
  return '(' + this.x + ', ' + this.y + ')';
};

ES6中的类(构造函数):

class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }

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

constructor方法是类的默认方法,通过new命令生成对象实例时,自动调用该方法。一个类必须有constructor方法,如果没有显式定义,一个空的constructor方法会被默认添加。
练手:
在这里插入图片描述

arrow functions

1、简化自定义函数 省略function关键字,=>指代函数
在这里插入图片描述
2、使用箭头函数时,函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。

template string

destructuring

解构赋值,即按照一定模式,从数组和对象中提取值,对变量进行赋值
1、变量给对象赋值

let cat = 'ken'
let dog = 'lili'
let zoo = {cat, dog}
console.log(zoo)  //Object {cat: "ken", dog: "lili"}

2、对象给变量赋值
这里type和many是不同的变量

let dog = {type: 'animal', many: 2}
let { type, many} = dog
console.log(type, many)   //animal 2 

default

指定函数参数的默认值
ES5写法:

function animal(type){
    type = type || 'cat'  
    console.log(type)
}
animal()

ES6写法:

function animal(type = 'cat'){
    console.log(type)
}
animal()

rest arguments

参数个数不确定时使用数组

function animals(...types){
    console.log(types)
}
animals('cat', 'dog', 'fish') //["cat", "dog", "fish"]

Jquery

JS的一个库,功能包括操作DOM对象、事件处理、动画、AJAX等。可以简化JS,有独立的函数
Jquery和JS的理解与区别(概念/使用方法等)
document.getElementById()返回的是DOM对象,而$()返回的是jQuery对象,也就是通过jQuery包装DOM对象后产生的对象,是个数组,内部每个元素都是独立的DOM对象。
jQuery对象是jQuery独有的,其可以使用jQuery里的方法。 不能使用DOM方法
DOM对象与jquery对象区分与转换
Jquery选择器

//.html();是Jquery方法  .innerHTML是DOM对象方法  两者不能交叉调用
$(document.getElementById("msg")).html(); 
$("#msg").html(); 
$("#msg")[0].innerHTML; 
$("#msg").eq(0)[0].innerHTML; 
$("#msg").get(0).innerHTML;//通过$()包裹DOM对象或.get(0)等方法互相转化

$("input")[0].value//DOM对象通过.访问节点
$("input").val();//jquery通过方法访问
document.getElementsByTagName("button")[0].textContent//JS原生方法ByTagName获取的也是数组  选择器简化了DOM操作

$等同于Jquery. Jquery.(document).ready(function(){})

jQuery中this与$(this)的区别
这是jQuery的一个函数,也是最核心最基本的函数
(1)功能一:传入一个选择器字符串,获得这个选择器对应的dom内容,保存在[]中,也就是俗称的jQuery对象。例如
(’#id’)(‘.class’) $(‘tag’)
(2)功能二:传入一个匿名函数,例如
$(function(){})//这个匿名函数在网页载入完成后开始执行
(3)功能三:将JavaScript对象包装成为jQuery对象。例如

$(this)
$({a:1,b:2,c:3})
$(document.getElementById('idstr'))

this是javascript自身的 语法关键字,它指向一个javascript对象,所以可以使用所指向的目标javascript对象所拥有的方法, 但他自己不是一个普通的变量,所以你无法自己定义一个变量叫this

所以为了使用jQuery对象的方法,你必须传入jQuery函数$(this), 将javascript 对象包装成为一个jquery对象。

这里的$(this)是一个JQuery对象,而jQuery对象沒有title 属性,因此这样写是错误的。

JQuery拥有attr()方法可以get/set DOM对象的属性,所以正确的写法应该是这样:

正确的代码:

$("#textbox").hover(   
      function() {   
         $(this).attr(’title’, ‘Test’);   
      },   
      function() {   
         $(this).attr(’title’,OK);   
      }   
); 

使用jQuery的好处是它包裝了各种浏览器版本对DOM对象的操作,因此统一使用$(this)而不再用this应该是比较不错的选择。

jquery-tmp

是一种模板编辑器 在内部定义标签模板和数据位

 <script id="myTemplate" type="text/x-jquery-tmpl">
  <tr><td>${ID}</td><td>${Name}</td></tr>
 </script>

通过函数调用添加数据与展现, $(’#id’).tmpl(数据).appendTo(标签)

 <script type="text/javascript">
  $(function () {
   var users = [{ ID: 'hao1', Name: 'Tony' }, { ID: 'hao2', Name: 'Mary hui'}];
   $('#myTemplate').tmpl(users).appendTo('#rows');
  });
 </script>

VUE

Vue.js 的核心是一个允许采用简洁的模板语法来声明式地将数据渲染进 DOM 的系统.
VUE中文官网
1、简化DOM操作,使用特殊语法,自动操作被修饰的DOM元素。
2、响应式数据驱动,页面由数据生成,数据改变后页面同步更新。

简单案例

<!DOCTYPE html>
<html>
<head>
   
    <title>123</title>
</head>
<body>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div class="app">
    {{ message }}
    <h2>{{ a.name }}</h2>
    <h2>{{ b[0] }}</h2>
    <h2 v-text="message"></h2>
    <h2 >差值表达式实现部分数据动态替换+{{ message+"!"}}</h2>
</div>
<<script>
    var a = {"name":"zzc","age":12};
    var b =["第一","第二","第三"];
    var app = new Vue({
        el:'.app',
        data:{
            message:b[2]+b[1],
            a:{"name":"zzc","age":12},
            b:["第一","第二","第三"]
                // 当一个 Vue 实例被创建时,它将 data 对象中的所有的 property 加入到 Vue 的响应式系统中。
                // 当这些 property 的值发生改变时,视图将会产生“响应”,即匹配更新为新的值。
        },
    })
</script>
</body>
</html>

el选择器(挂载点)

作用范围:el选项命中的元素及其后代元素
选择器:支持.class 、#id 、标签选择
不支持单标签,双标签中建议挂载没有默认样式的DIV标签。

data(数据对象)

可以写复杂类型的数据,遵守JS语法即可
数据和 DOM 已经被建立了关联,所有东西都是响应式的,数据更新时页面同步更新。
在这里插入图片描述

语法:

method:{}
 methods: {
    reverseMessage: function () {
      this.message = this.message.split('').reverse().join('')
    }
  }
计算属性缓存与方法调用:

{{ reversedMessage }}在实例中添加computed:{reversedMessage函数} 等效 {{ reversedMessage() }}在实例中添加方法 但可以防止重复计算

computed:{ }

中使用到的data里的变量是可以追踪到的,当text发生了改变时,textReverse 也会做出相应的改变。
// https://blog.csdn.net/weixin_45136832/article/details/93174128

计算属性computed 侦听属性watch:

实例中添加 watch:{}侦听数据property的变化 与在实例中添加computed:{} 等效且更快节省资源

侦听器watch{}:

实例中添加 watch:{}侦听数据property的变化 当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。
watch案例 $watch案例:

class与style绑定:
v-标签:

{{ 插值+表达式 }} v-once 实现一次性插值不更新 {{ number + 1 }} {{ ok ? ‘YES’ : ‘NO’ }} {{ message.split(’’).reverse().join(’’) }}
v-html=“data property”
v-text=“data property”
v-on @event=“method property”
v-bind :标签属性=“data property” <a v-bind:[attributeName]=“url”> …
v-model input、textarea 及 select标签内 或与自定义组件结合使用
v-slot

//简单理解为父组件可根据v-slot指定(或匿名)的子组件中<slot>标签  替换掉对应位置的内容       
//匿名(只有一个不用命名)/具名(多个时指定插槽名)/作用域(需获取子插槽数据时)
父组件:<template v-slot:todo>
              任意内容
             <p>我是匿名插槽 </p>
        </template>
子组件:<slot name="todo">我是默认值</slot>
我是默认值会被‘ 任意内容<p>我是匿名插槽 </p>’替换掉
//支持动态命名:v-slot:{dynamicSlotName}

案例1

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"> 
<title>菜鸟教程(runoob.com)</title> 
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<style>
</style>
</head>

<body>

    <div id="id">
        <span>Multiline message is:</span>
       
        <input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
        <label for="jack">Jack</label>
        <input type="checkbox" id="john" value="John" v-model="checkedNames">
        <label for="john">John</label>
        <input type="checkbox" id="mike" value="Mike" v-model="checkedNames">
        <label for="mike">Mike</label>
        <br>
        <span>Checked names: {{ checkedNames }}</span>
        <br>
        <p style="white-space: pre-line;">{{ message }}</p>
        <br>
        <textarea v-model="message" placeholder="add multiple lines"></textarea>

        <br>
            单选:
            <select v-model="selected" title="单选">
              <option disabled value="">请选择</option>
              <option>A</option>
              <option>B</option>
              <option>C</option>
            </select>
            <span>Selected: {{ selected }}</span>

            <br>
            <hr>
            多选:
            <select v-model="selected2" multiple style="width: 50px;" title="多选">
                <option>A</option>
                <option>B</option>
                <option>C</option>
              </select>
              <br>
              <span>Selected: {{ selected2 }}</span>
              <br>
              <hr>
            用 v-for 渲染的动态选项:
            <select v-model="selected3">
                <option v-for="option in options" v-bind:value="option.value">
                  {{ option.text }}
                </option>
              </select>
              <span>Selected: {{ selected }}</span>
              <br>
              <hr>
            选中后给data property 赋值
            <select v-model="selected4">
                <!-- 内联对象字面量 -->
              <option v-bind:value="{ number: 123 }">123</option>
              <!-- <option v-bind:value="123">123</option> -->
            </select>
    </div>
<!-- 修饰符号:  .lazy  每次 input 事件触发转为在 change 事件_之后_进行同步:
                .number 自动将用户的输入值转为数值类型
                 .trim   自动过滤用户输入的首尾空白字符-->

	<script>
        let vm = new Vue({
            el: '#id',
            data: {
                checkedNames: [],
                message:null,
                selected:'',
                selected2:[],
                selected3:'A',
                options: [
                    { text: 'One', value: 'A' },
                    { text: 'Two', value: 'B' },
                    { text: 'Three', value: 'C' }
                ],
                pick:true
            }
    })
	</script>
</body>
</html>

v-if=“data property 表达式”
v-else-if=“data property 表达式”
v-else=“data property 表达式”
v-show=“data property 表达式”

v-for=“迭代项 / (迭代项,索引) / (键,值,索引) / in 数组/对象”

<!DOCTYPE html>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
    <!-- vue实例通过id挂载在DOM上  包括实例的数据和方法  文本插值或绑定元素attribute展示数据  通过数据改变响应控制DOM -->
    <div id="app_1">
        <!--vue插值表达式,data中定义是数据显示到此处-->
                  插值表达式:{{massage}} 
        <!--			三目运算符-->
                  {{massage==1? "massage=1" : "massage!=1"}}
        <!--			数学运算-->
                  {{massage*3.14}}
        <p v-cloak>{{msg}}</p>
    </div>
    <div id="app_html_text">
        <p v-html="msg"></p>
        <p v-text="msg"></p>
    </div>
    <div id="app_on_blind">
        <!--可直接将v-blind:简写为“:”  将title属性绑定在mytitle数据上-->
        <!--可直接将v-on:简写为“@”  -->
            <input type="button" value="按钮" v-bind:title="mytitle"  v-on:click="show()">
     </div>

     <hr>
    
     <div id="app_model">
        v-model实现数据与表单双向绑定:<span>{{ message }}</span>
         <!-- v-model 能够实现表单元素和model间的双向绑定,但是v-model只能在表单中使用 <input>、<textarea> 及 <select>-->
        <input v-model="message">
      </div>

    <hr>

    <div id="app_if_show">
        <input type="button" value="toggle" @click="toggle">
        <!-- v-if特点:每次都会重新创建和删除dom元素 -->
        <!-- v-show: 每次不会创建和删除,但改变display的属性-->
        <!-- v-if的值为true则展示绑定了v-if的元素,否则展示绑定了v-else属性的元素。(类似与if....else语句) -->
        <h1 v-if="flag">这是v-if的h1</h1>
        <h1 v_else="flag">这是v-else的h1</h1>
        <h1 v-show="number>1">这是v-show的h1</h1>
    </div>

    <hr>

    <div id="app_elseif">
        <div>
            <p>成绩等级:
                <div v-if="score > 90">优秀</div>
                <div v-else-if="score > 80">良好</div>
                <div v-else-if="score > 60">中等</div>
                <div v-else>不及格</div>
            </p>
        </div>
        请输入成绩:<input v-model="score">
    </div>

    <hr>

    <div id="app_for">
        <ul>
            迭代普通数组:<p v-for="(item,i) in list">--索引值--{{i}}   --每一项--{{item}}</p>
            迭代对象数组1:<p v-for="(user,i) in listObjs">--id--{{user.id}}   --姓名--{{user.name}}</p>
            迭代对象数组2:另一种写法:<p v-for="listObj in listObjs">--id--{{listObj.id}}   --姓名--{{listObj.name}}</p>  
            迭代对象:<p v-for="(val,key,index) in user"></p>
             <table border="1">
				<tr>
					<td>序号号</td>
					<td>编号</td>
					<td>名称</td>
					<td>价格</td>
				</tr>
				<tr v-for="(p,index) in products">
					<td>{{index+1}}</td>
					<td>{{p.id}}</td>
					<td>{{p.name}}</td>
					<td>{{p.price}}</td>
				</tr>
			</table>
            <p v-for="count in 3">迭代数字:这是第{{count}}次循环</p>
        </ul>
    </div>

    <hr>

        <div id="app_on">
        <button v-on:click="fun1('vue的onclick')">vue的onclick</button>
        <button @click="fun1('haha')">haha</button>
        keydown:<input type="text" v-on:keydown="fun($event)">
        keydown.enter:<input type="text" @keydown.enter="fun3()">
        mouseover:<input type="text" @mouseover="fun2()">
        <!-- 修饰符: 事件修饰符 v-on:click.stop/.prevent/.capture/.self/.once/.passive  @事件名.prevent:阻止事件的默认行为  @事件名.stop:阻止事件的传播行为 
                      按键修饰符  @keydown.按键码 监听键盘事件是按键修饰符    @keyup.enter是监听enter键的修饰符
                     系统修饰键   .ctrl .alt .shift
                     鼠标按钮修饰符   .left .right .middle -->
            <!-- 修饰符: -->
            <!-- 阻止单击事件继续传播 -->
            <a v-on:click.stop="doThis"></a>
            <!-- 提交事件不再重载页面 -->
            <form v-on:submit.prevent="onSubmit"></form>
            <!-- 修饰符可以串联 -->
            <a v-on:click.stop.prevent="doThat"></a>
            <!-- 只有修饰符 -->
            <form v-on:submit.prevent></form>
            <!-- 添加事件监听器时使用事件捕获模式 -->
            <!-- 即内部元素触发的事件先在此处理,然后才交由内部元素进行处理 -->
            <div v-on:click.capture="doThis">...</div>
            <!-- 只当在 event.target 是当前元素自身时触发处理函数 -->
            <!-- 即事件不是从内部元素触发的 -->
            <div v-on:click.self="doThat">...</div>
    </div>

    <script>
        
        new Vue({
            el:"#app_on",
            data:{
                message:"hello vue"
            },
            methods:{
                fun1:(msg)=>{
                // fun1:function (msg) {
                    alert(msg);
                },
                fun2(){console.log('鼠标悬浮事件触发')},
                fun3(){console.log('@keydown.enter触发')},
                fun:(event)=>{
					var keyCode = event.keyCode;
					console.log(keyCode);
					if (!(keyCode>=48&&keyCode<=59)){
						// event.preventDefault();//阻止默认行为
						event.stopPropagation();//阻止冒泡
					}
				}
            }
        });

        var app= new Vue ({
            el: "#app_for",
            data:{
                list:[1,2,3,4,5,6],
                listObjs:[
                    {id:1, name:'zs1'},
                    {id:2, name:'zs2'},
                    {id:3, name:'zs3'},
                    {id:4, name:'zs4'},
                    {id:5, name:'zs5'},
                    {id:6, name:'zs6'},
                ],
                products:[
					{id:1,name:"电视机",price:2000},
					{id:2,name:"洗衣机",price:2000}
				],
                user:{
                    id:1,
                    name:'托尼.贾',
                    gender:'男'
                }
            }
        })

        var app_elseif = new Vue({
            el:'#app_elseif',
            data:{
                score:null//  
            },
            methods:{
            }
        })

        var app_if_show = new Vue({
            el:'#app_if_show',
            data:{
                flag:true,
                number:2
            },
            methods:{
                toggle(){
                    this.flag = !this.flag;
                }
            }
        })


        var app_model = new Vue({
            el: '#app_model',
            data: {
                message: 'Hello Vue!'
            }
        })

        var vm_on_blind = new Vue({
            el:'#app_on_blind',
            data:{
                mytitle:"v-bind:title"
            },
             methods: {
                show: function () {
                    alert("Hello!");
                }
            },
        })

        var vm_1 = new Vue({
        el:'#app_1',
        data:{
            massage:1
        },
        methods:{}
        })

        var vm_2 = new Vue({
        el:'#app_html_text',
        data:{
            msg:"<h2>你好,我在测试v-html的作用</h2>"
        },
        methods:{}
        })

    </script>
</body>
</html>

组件:

vue 父子组件
vue中 关于$emit的用法
组件插槽v-slot
父子组件传值方法prop
父子组件传值方法2
本质上是一个拥有预定义选项的一个 Vue 实例 任意应用界面都可以抽象为一个组件树

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
      <!-- 
        关系:  组件  --(包含于)->  DOM元素 <---(绑定)--- VUE实例   组件本质是有预定义选项可复用的Vue实例
        无组件:vue实例通过id挂载在DOM上        包括实例的数据和方法  文本插值或绑定元素attribute展示数据  通过数据改变响应控制DOM
        有组件: 组件是可复用的 Vue 实例,除template模板外,所以它们与 new Vue 接收相同的选项,例如 data、computed、watch、methods 以及生命周期钩子等。仅有的例外是像 el 这样根实例特有的选项。
        
        data:必须是函数  以保证每个实例可以维护一份被返回对象的独立的拷贝
        Prop: 是你可以在组件上注册的一些自定义 attribute 
               ▲作用是  自定义标签组  templeat模板中使用制作模板   在使用模板时  根据挂载在不同被VUE实例绑定的DOM下的data proprets  利用v-bind绑定数据与模板  填充模板数据生成模板

     -->

    <div id="components-demo">
        <button-counter></button-counter>
        <br>
        组件复用:
        <button-counter></button-counter>相互不影响
        <br>
        <hr>
        静态数据模板
        <blog-post title="My Vue"></blog-post>
        <br>
        <hr>
        v-bind绑定VUE实例的data  动态数据模板
        <blog-post
            v-for="post in posts"
            v-bind:key="post.id"
            v-bind:title="post.title"
        ></blog-post>
        <br>
        <hr>
        重构模板 使得vue实例data随时更新都可在模板内使用
        <blog-post1
            v-for="post in posts"
            v-bind:key="post.id + '-only'"
            v-bind:post="post"
        ></blog-post1>





      </div> 

    <!-- -->

    <script>
        // 注册组件   全局注册的组件  可以用在其被注册之后的任何 (通过 new Vue) 新创建的 Vue 根实例,也包括其组件树中的所有子组件的模板中。
        Vue.component('button-counter', {
            data: function () {  //组件复用时的数据独立
                return {
                count: 0
                }
            },
            template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>',
            method:{},
            component:{}
        })
        // 自定义组件的attribute
        Vue.component('blog-post', {
            props: ['title'], 
            template: '<h3>{{ title }}</h3>'
        })
        Vue.component('blog-post1', {
            props: ['post'],//重构组件 将props与要挂载DOM下BUE实例内要使用的数据项同名   template中添加根元素
            template: `
                <div >
                <h3>{{ post.title }}</h3>
                <div v-html="post.content"></div>
                </div>
                `
        })
        
        // VUE实例  绑定dom
        new Vue({ el: '#components-demo',
                    data: {
                        posts: [
                        { id: 1, title: '孙奇' },
                        { id: 2, title: '刘坤' },
                        { id: 3, title: '崔福强' }
                        ]
                     }
        })

        
    </script>
</body>
</html>

在这里插入图片描述

VUE指令等

生命周期:

生命周期图示
设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等 过程中也会运行生命周期钩子函数,可添加自己的代码。 created/updated/destroyed…: function () {}

操作真实DOM:

原生JS或JQ操作DOM时,浏览器会从构建DOM树开始从头到尾执行一遍流程。 https://www.jianshu.com/p/af0b398602bc

虚拟DOM:

虚拟DOM不会立即操作DOM,而是将这多次更新的diff内容保存到本地一个JS对象中,最终将这个JS对象一次性attch到DOM树上,避免大量无谓的计算量。

VUE虚拟DOM:

在底层的实现上,Vue 将模板编译成虚拟 DOM 渲染函数。结合响应系统,Vue 能够智能地计算出最少需要重新渲染多少组件,并把 DOM 操作次数减到最少。
在这里插入图片描述

路由:

路由API 参考

//一、npm install -g @vue/cli 下载路由
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
//二、引入并使用路由

import Home from './Home.vue'
import Login from './Login.vue'

const router = new VueRouter({
//三、创建路由组
    mode: 'history',
    routes: [
        {
            path: '/',//默认路由   这个path与真实项目文件的path区分开  只是URL后跟的信息而已  组件都是通过import的路劲引入
            component: Home,
            meta: {
                requireAuth: true
            }
        },
        {
            path: '/login',
            component: Login,
            meta: {
                requireAuth: false
            }
        }
    ]
})
export default router
//四、抛出路由  在外面用<router-link>等方式使用路由切换显示组件
//children  redirect  meta     fullPath  等待完善
//路由转移方法  this.$router.push("/路由地址"); 

路由监听器

router.beforeEach( (to, from, next)=>{
    let islogin = sessionStorage.getItem('islogin')

    if(islogin === 'true'){
        next()
    }else {
        if(to.path != '/'){
            next('/')
        }else {
            next()
        }
    }
})

Vuex:

也就是管理组件间需要共享的data

VUEX官方
五分钟搞懂Vuex
状态管理模式。
它采用集中式存储管理应用的所有组件的状态。
这个状态我们可以理解为在data中的属性,需要共享给其他组件使用的部分。
也就是说,是我们需要共享的data,使用vuex进行统一集中式的管理。

vuex中,有默认的五种基本的对象:

  • state:存储状态(变量)
  • getters:对数据获取之前的再次编译,可以理解为state的计算属性。我们在组件中使用 $sotre.getters.fun()
  • mutations:修改状态,并且是同步的。在组件中使用$store.commit(’’,params)。这个和我们组件中的自定义事件类似。
  • actions:异步操作。在组件中使用是$store.dispath(’’)
  • modules:store的子模块,为了开发大型项目,方便状态管理而使用的。这里我们就不解释了,用起来和上面的一样。

使用VUEX:

  • 安装 npm install vuex --save
  • 在store.js文件中,引入vuex并且创建state数据,使用vuex
    在这里插入图片描述
  • 在main.js中引入store: import store from './vuex/store' 使用:new Vue({ ... store,...})
  • 然我我们在任意一个组件中就可以使用我们定义的count属性了。
    <h3>{{$store.state.count}}</h3>

操作VUEX

  • 在store.js文件中定义mutation,sactions对象的方法,操作state数据,在组件中调用即可。
  • getters来获取我们的state

Element UI

项目中常用的网站快速成型工具
npm i element-ui -S
// main.js中
import ElementUI from ‘element-ui’
import ‘element-ui/lib/theme-default/index.css’

Vue.use(ElementUI)

VUE -CLI:

node.js→npm→vue.cli
Vue-cli是vue官方出品的快速构建单页应用的脚手架
用于搭建vue项目,将 Vue 生态中的工具基础标准化,简化配置。

CLI (@vue/cli) 是一个全局安装的 npm 包,提供了终端里的 vue 命令。它可以通过 vue create 快速搭建一个新项目,或者直接通过 vue serve 构建新想法的原型。你也可以通过 vue ui 通过一套图形化界面管理你的所有项目。
VUE -CLI官方
安装过程与VUE项目结构讲解

插件/依赖:

   vue/cli-plugin-babel  把各种javascript千奇百怪的语言统统专为浏览器可以认识的语言。
   vue/cli-plugin-eslint  一个代码检测工具,用于检测代码的编写是否符合 ESLint 所设定的规范

package.json

定义项目开发所需要的各种模块以及一些项目配置信息(如项目名称、版本、描述、作者等)。

scripts字段:

定义了你可以用npm运行的命令 npm run serve就对应:

"scripts": {
    "serve": "vue-cli-service serve"
  },

npm run xxx(例如:build/serve/dev):

把写好的Vue网页放到服务器上,运行本命令vue-cli会自动进行项目发布打包

dependencies字段和devDependencies字段:

npm install命令,会自动安装dependencies和devDempendencies字段中的模块到node_modules中

  • dependencies字段指项目运行时所依赖的模块;
  • devDependencies字段指定了项目开发时所依赖的模块;

项目重要目录:

|-- package.json // 项目基本信息 脚本配置 所需模块
|-- index.html // 入口页面
|-- src // 源码目录
| |-- main.js // 程序入口文件,加载各种公共组件
| |-- App.vue // 页面入口文件
| |-- router.js//路由文件
| |-- components // vue公共组件

构建项目文件间的逻辑时开发的基础
在这里插入图片描述

实际开发中:

index.html与package.json基本不用管,只需要关注:

  • main.js引入vue、router、store、app.vue根组件等,注册并使用他们
  • App.vue单页应用中长期存在的组件如:版本信息的import引入、components中注册、template中激活。与最重要的使用<router-view /> 来链接其组件
  • router.js 引入路由文件与组件import,使用路由Vue.use(Router),组件注册进路由对象,最后抛出该路由对象全局使用export default router

main.js文件

main.js是整个项目动态运行时的入口,在src文件夹下:
引入路由并将其注册到VUE实例上
引入模板

import Vue from 'vue'//必选
import App from './App'//引入了APP的组件和模板  App.vue
import router from './router'//引入路由
new Vue({
  el: '#app',
//一定要注入到vue的实例对象上
  router})

App.vue文件:

页面入口文件
router-link标签 使用路由

<template>  <!-- 模板的HTMLDom结构 -->
<div id="app">
<img src="./assets/logo.png">
 <div>
        <router-link to="/page1">Page1</router-link>
        <router-link to="/page2">Page2</router-link>
      </div>
      <router-view></router-view><!-- 说明使用了路由机制-->
</div>
</template>
 
<script>
export default {
name: 'app'
}
</script>
 
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>

router/index.js 路由文件:

npm install vue-router -g安装router
package.json文件中找到"vue-router": "^3.5.1"
创建router文件:

//引入vue
import Vue from 'vue';
//引入vue-router
import VueRouter from 'vue-router';
//第三方库需要use一下才能用
Vue.use(VueRouter)
//引用page1页面
import page1  from './page1.vue';
//引用page2页面
import page2  from './page2.vue';

//定义routes路由的集合,数组类型
const routes=[
    //单个路由均为对象类型,path代表的是路径,component代表组件
    {path:'/page1',component:page1},
    {path:"/page2",component:page2}
]

//实例化VueRouter并将routes添加进去
const router=new VueRouter({
//ES6解构赋值,等于routes:routes  
    routes
});

//抛出这个这个实例对象方便外部读取以及访问
export default router

在main.js中:

//引用router.js
import router from './router.js'
new Vue({
  el: '#app',
//一定要注入到vue的实例对象上
  router})

router路由基本使用
官方Router-API

.vue文件们

分为template script style 三个部分,以后我们大部分的工作都是写这些.vue结尾的文件。

宏任务微任务,同步异步,JS执行机制:

在这里插入图片描述

因为javascript是一门单线程语言,是按照语句出现的顺序执行的
宏任务和微任务
JS执行机制
在这里插入图片描述

  • 同步的进入主线程,异步的进入Event Table并注册函数。
  • 事情完成例如定时3秒,Event Table会将这个函数移入Event Queue
  • Event Queue分为宏任务Queue与微任务Queue
  • 主线程任务执行完,Event Queue读取对应的函数,进入主线程执行
  • 上述过程会不断重复,也就是常说的Event Loop(事件循环)。

来自掘金,作者:ssssyoki

除了广义上的同步异步任务还可以分为宏任务\微任务
宏任务:包括整体代码script,setTimeout,setInterval。
微任务:Promise,process.nextTick。
但遇到异步操作时会分别放在宏任务queue队列中与微任务queue队列中。
等宏整体JS执行完后,先从微任务queue拿回调,微任务queue空了在执行宏任务queue
案例理解:

setTimeout(function() {
    console.log('setTimeout');
})

new Promise(function(resolve) {
    console.log('promise');
}).then(function() {
    console.log('then');
})

console.log('console');
//先将整体代码作为宏任务执行,同步直接执行,异步注册Event queue
//setTimeout异步注册于宏任务队列  .then注册于微任务队列
//宏任务(整体代码)完成->微任务队列->宏任务如此循环

异步:

在这里插入图片描述

异步:遇到后先执行非异步操作 最后返回来执行异步
Promise对象 与 async关键字声明的函数 都是异步操作的容器 内部会包含异步操作,但不影响内部同步操作的执行
promise(.resolve .reject .then .catch)
async(await throw .then .catch)
async 是建立在 promise机制之上的

理解JS异步操作
javascript是单线程,依次执行一个任务,要想让任务能够顺利进行,我们需要排队,异步就是将任务放入异步队列,在主线程执行结束之后再去执行

使用async 理解promise/异步/回调

Javascript是一个单线程的编程语言所以会涉及到大量的异步函数
煮饭事件就是一个异步事件 等着饭熟不做其他事就是阻塞
电饭煲通知就是一个回调函数,得到通知再回去处理煮饭这个事件
在饭还没熟的过程中,我们就能够去做其它事情了。这就是所谓的异步机制

常见的异步任务主要有3类:

  • 网络请求(Ajax)
  • 事件触发(onclick | onchange etc.)
  • 定时函数(setTimeout | setInterval)

回调地狱: 异步任务相互依赖,层层嵌套,每层都有大量代码,可读性极差

Promise对象

异步操作的容器
封装异步操作为promise对象,可new/.resolve()/.reject()

let z = new Promise((resolve, reject) => {
      setTimeout(() => {//将异步函数封装为Promise对象
        resolve(event)//也可通过resolve()/reject()直接设置返回的promise对象状态
      }, 1000)
    })               
z    //等待态  Promise {<pending>}

let a = Promise.resolve(123)//等同于 let a = new Promise((resolve,reject)=>{resolve(123)})
a.then((result) => {
    console.log(result)   // 成功态  Promise {<fulfilled>: 123}
})

let b = Promise.reject('123')//等同于let b = new Promise((resolve,reject)=>{reject(123)})
b.catch((result) => {
    console.log(result)   // 123 失败态
})

被封装的函数有了三种状态,将异步执行,可.catch捕捉异常态,可.then链式调用(解决异步函数的回调地狱)
Promise.resolve() 快速获取一个成功状态的promise对象
Promise.reject() 快速获取一个拒绝状态的promise对象
三种状态 :pending(等待态),resolved/fulfilled(成功态),rejected(失败态)
可以对异步函数来一个Promise封装方便链式调用
.then下一步的操作 返回一个promise对象,可以继续用then方法调用,再次调用所获取的参数是上个then方法return的内容
.catch 捕捉异常

function getNumber() {
    var p = new Promise(function(resolve, reject) {
        setTimeout(function(){
            var num = Math.ceil(Math.random()*10);
            if(num<5) {
                resolve(num)
            } else {
                reject('数字太大了')
            }
        }, 2000)
    });
    return p;
}
getNumber()
        .then(function(data) {
            console.log('resolve');
            console.log(data);
        })
        .catch(function(reason) {
            console.log('reject');
            console.log(reason); 
        })

async(异步) await关键字:

promise和async区别的案例 :用await来避免异步嵌套
异步操作的容器
async、await、promise
基于promise,与promise协同工作,放在函数关键字前修饰,表示函数是一个异步函数,不需要书写繁杂的Promise
·确保了函数返回一个promise
·允许在这其中使用await
·内部可使用await、throw
·函数可调用.then、.catch

let a = Promise.resolve(123)
a.then((result) => {
    console.log(result)
})

//对比Promise对象的写法  无需手动封装  函数写在async中直接返回Promise对象

async function a(){//声明异步函数
      "123";//返回的都是promise对象  
      //异常通过throw抛出:throw "123"
      //await写在async里面  后面可以放任何表达式,更多是promise对象表达式   用来等待 Promise 对象的状态被 resolved  但当await的是正常的表达式则立即执行。最好把await命令放在try...catch代码块中。
}

//同样使用.then.catch 调用者变为了使用async修饰的函数  本质也是promise对象 

console.log(a());//调用时会先返回promise对象  这里输出promise对象
a().then((result)=>{
    console.log(result);//底层还是promise,可以使用then方法添加回调函数。
}).catch((result)=>{
    console.log(result);//也可以捕获promise异常态
});

练习:
ES6 Promise实战练习题

function sleep(second) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('request done! '+ second + Math.random());
        }, second);
    })
}
async function bugDemo() {
    console.log(await sleep(2000));
    console.log(await sleep(3000));
    console.log(await sleep(1000));
    console.log('clear the loading~');
}
bugDemo();//Promise {<pending>}__proto__: Promise[[PromiseState]]: "fulfilled"[[PromiseResult]]: undefined
		 //VM512:9 request done! 20000.65040025283329
		 //VM512:10 request done! 30000.8083610725410029
		 //VM512:11 request done! 10000.006901671040587809
		 //VM512:12 clear the loading~

webpack

webpack 是一个现代 JavaScript 应用程序的静态模块打包器
前端的常用资源都可以作为一个模板导出,我们在代码中直接引用即可,最后把我们的代码打包整合起来。
最简单语言理解 webpack 的用法
webpack (1)——核心概念的理解

PostMan

postman安装使用教程—图文讲解

Module模块

es6的导入导出-模块化
es6 module 中模块加载方式是静态加载。
一个文件可以默认为一个模块
·export向外暴露接口
·import导入接口,只能出现在模块的最外层(顶层)结构中
二者结合使用实现模块间交互等功能

VUE项目组件相互引用

VUE项目中就可以通过组件的导出和引用 互相组合使用组件

<script>
    import aaa  from '@/components/common/aaa.vue'
    //导入组件模块
    export 组件{//定义本组件同时也作为模块导出
		components:{aaa}//定义组件  且要在template中使用该组件标签
}

Nodejs

node.js→npm→vue.cli
node.js:JS的非浏览器运行环境 类似于tomcat 自动添加环境变量 在各命令行都能使用
$ npm:npm(Node Package Manager)前端包管理工具 类似maven
配置npm服务器以下载依赖 npm config set registry (链接)http://registry.weihong.com.cn/
什么是node.js
node.js安装及环境配置
nodejs安装及设置NPM全局路径
npm基本命令

JSON-server使用

JSON-server使用
cnpm insatll -g concurrently
运行vue-cli的时候同时启动json-server 未实现 失败了 两个VScode可实现
json-server 会将一个json文件作为数据库来存储数据,对json数据的格式是有要求的,如data.json的内容:
在这里插入图片描述
自己写数据接口测试很方便

Git

下载安装,设置好账号密码和地址 生成SSH密匙在gitlab上配置密匙 git init新建工作区 导入项目
1. Vscode中:
ctrl+· 打开终端
打开或新建文件夹,作为工作空间存储项目
git init 新建git工作区
git clone (SSH地址)
npm init 指定文件夹下安装包前,cmd进入目录下初始化项目生成 package.json 文件(npm run XXX 是执行配置在 package.json 中的脚本)
npm install/ npm install i
npm run build/npm run serve
关闭或结束:ctrl+c / 杀进程 netstat -nao|grep 某端口,然后kill -9 进程名。
2. 目录下新建文件夹 右键打开 power shell 输入git clone+地址 cd进入项目根目录 TAB查找 code .用VS CODE打开
GIT操作:
上传:git add .
git commit -m"附带内容"
git push -u 账号 密码
Git 常用命令
git branch 查看本地所有分支
git status 查看当前状态
git commit 提交
git branch -a 查看所有的分支
git branch -r 查看本地所有分支
git commit -am “init” 提交并且加注释
git remote add origin git@192.168.1.119:ndshow
git push origin master 将文件给推到服务器上
git remote show origin 显示远程库origin里的资源
git push origin master:develop
git push origin master:hb-dev 将本地库与服务器上的库进行关联
git checkout --track origin/dev 切换到远程dev分支
git branch -D master develop 删除本地库develop
git checkout -b dev 建立一个新的本地分支dev
git merge origin/dev 将分支dev与当前分支进行合并
git checkout dev 切换到本地dev分支
git remote show 查看远程库
git add .
git rm 文件名(包括路径) 从git中删除指定文件
git clone git://github.com/schacon/grit.git 从服务器上将代码给拉下来
git config --list 看所有用户
git ls-files 看已经被提交的
git rm [file name] 删除一个文件
git commit -a 提交当前repos的所有的改变
git add [file name] 添加一个文件到git index
git commit -v 当你用-v参数的时候可以看commit的差异
git commit -m “This is the message describing the commit” 添加commit信息
git commit -a -a是代表add,把所有的change加到git index里然后再commit
git commit -a -v 一般提交命令
git log 看你commit的日志
git diff 查看尚未暂存的更新
git rm a.a 移除文件(从暂存区和工作区中删除)
git rm --cached a.a 移除文件(只从暂存区中删除)
git commit -m “remove” 移除文件(从Git中删除)
git rm -f a.a 强行移除修改后文件(从暂存区和工作区中删除)
git diff --cached 或 $ git diff --staged 查看尚未提交的更新
git stash push 将文件给push到一个临时空间中
git stash pop 将文件从临时空间pop下来
新员工入职时GIT下载与基本配置
下载GITHUB项目
GIT提交代码流程

值得记录的知识点网址

此篇博客长期更新,记录自己学习前端的历程,包括各种知识站点和个人总结、代码等
从最基础的开始重新学习,一步一个脚印扎实掌握下来
前端chrome浏览器调试总结
(前端必会)理解异步和Promise的使用
Vue3.0中setup函数的使用

ref 模块是用来声明简单数据类型的,例如,string , number ,boolean 
reactive 模块是用来声明复杂数据类型的,例如,数组,对象等

GET和POST两种基本请求方法的区别

get获取数据 设置URL  
POST操作数据  设置参数 安全 容量大

其他知识点

揭秘前端文件上传原理
vue中使用axios等异步方法this指向的问题
对象解构赋值与对象数组抽离部分对象值:

_this.craftlist = _this.craftarray.map((it) => {
	 return { workprocedureid: it.workprocedureid, workprocedurename: it.workprocedurename };
});

map函数去操作数组对象,解构去操作对象之间的赋值。
map是浅拷贝 地址存在引用关系(深拷贝是开辟新栈)
深拷贝浅拷贝
es6中的find filter 在数组中查找对象

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

跳动的世界线

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值