# vue-cli-0822
**Repository Path**: huanghe01/vue-cli-0822
## Basic Information
- **Project Name**: vue-cli-0822
- **Description**: vue-cli-0822vue-cli-0822vue-cli-0822vue-cli-0822vue-cli-0822
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 2
- **Created**: 2022-12-26
- **Last Updated**: 2023-01-11
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# Vue2 课堂笔记
## 每日彩蛋
1. 说明 `a = b = c = d = 1;`的执行过程
- 查阅MDN的运算符优先级文档,找到赋值(=)运算符,发现多个=在一个表达式中是从右向左执行的
- `c=d=1`是先执行`d=1`,然后把`d=1`的返回值赋值给c
- 赋值(=)操作符的返回值:返回=右侧的值,所以`d=1`返回1,然后把1再赋值给c
- 后边依次类推
2. `for(var i = 0,j = 0; i < 5, j < 10; i++,j++){语句}` 请问当前for循环的循环次数??为什么
- 首先直到for循环是否能够向下继续循环,只要看for中的判断式
- 判断式是多个,由逗号运算符间隔开,我们就要考虑逗号运算符的返回值
- 逗号运算符如果出现多个,则从左向右执行,并返回逗号右侧的值
- 所以当前的循环主要看j的次数来决定整个循环的次数
3. 代码题:请得到7天以后的现在的时间
- 方式1
```js
//1. 获取当前的时间
new Date();
//2. 获取当前时间的日期
new Date().getDate();
//3. 获取目标时间的日期
new Date().getDate() + 7;
//4. 获取当前的时间,把日期修改为目标日期
new Date().setDate(new Date().getDate() + 7);
```
- 方式2
```js
//1. 得到7天以后的时间戳
Date.now() + 1000 * 60 * 60 * 24 * 7;
//2.创建一个时间,把7天以后的时间戳交给参数
new Date(Date.now() + 1000 * 60 * 60 * 24 * 7);
```
4. 代码题:'abaabgfdebbafefgefsrsbabesseeeeaa' 请计算每一个字母出现的次数,及出现最多次数的字母
```js
const str = "abaabgfdebbaefefgfsrsbabesseeeeaa";
//1.创建一个对象,用来保存每一个字符出现的次数
const obj = {};
//2. 遍历字符串的每一个字符,然后去对象中判断,如果对象中不存在,则给对象新增一个属性默认值为1,如果对象存在,则把对象的值+1
for (let key of str) {
obj[key] ? obj[key]++ : (obj[key] = 1);
}
console.log(obj);
//3. 先初始化一个值用来保存出现最多的key,再初始化一个值用来保存出现最多key的次数
let bigStr = "";
let bigStrNum = 0;
//4. 遍历对象,一个的判断
for (let key in obj) {
//如果当前遍历出的新值的次数 大于目前保存的次数,那你牛逼,我们跟你
if (obj[key] > bigStrNum) {
bigStr = key;
bigStrNum = obj[key];
}
}
console.log(bigStr, bigStrNum);
```
5. 让一个字符串的首字母大写,比如 "hello every one"--->"Hello every one"
6. 让一个字符串所有单词的首字母大写,比如"hello every one"--->"Hello Every One"
7. 数组去重的方法(3种)
8. 封装一个myNew函数实现new操作符,如下,让p1和p2有一样的效果
```js
function Person(name,age){
this.name = name;
this.age = age;
}
Person.prototype.do = function(){}
//原始new
const p1 = new Person("xiaowang",18);
//手动封装new
const p2 = myNew(Person,"xiaowang",18);
```
9. 让一个不定宽高的元素在容器中水平垂直居中的方式(3种方式)
10. 给按钮绑定点击事件,频繁点击按钮时让事件最少间隔1s才能触发一次(节流),并且封装通用函数
11. 什么是事件流(事件机制)
- 事件冒泡:事件从最精确的元素(target)开始向最不精确的元素(document)依次传播
- 事件捕获:事件从最不精确的元素(document)开始向最精确的元素(target)依次传播
- W3C事件流:
当事件触发,先执行捕获过程
再执行目标元素的事件(target)
在执行冒泡过程
12. 在输入框输入内容后,等待1s后发送请求,如果1s内输入框内容改变了,则重新等待1s(防抖)
13. 我们要拷贝一个对象(深拷贝和浅拷贝)的做法
14. 整理HTML5新特性有哪些
* 语义性标签,header\footer\nav\aticle\section
* 增强表单,input的多种type类型(tel\month\email\number\color.....)
* 音频视频
* WebWorker:开启多线程
* WebStorage:本地存储
* WebSocket:是一种通信协议
* Canvas:画布
15. 整理CSS3新特性有哪些
* 选择器
* 边框,阴影,背景,渐变
* 变形
* 过渡动画
* 关键帧动画
* flex
* @media媒体查询
16. 整理ES6新特性有哪些
* let和const
* 解构赋值
* 新增数据类型(symbol,bigint)
* 新增的数据结构(map,set)
* iterator接口(for..of..,解构,扩展运算符原理)
* promise/async/await
* class类
* es6模块化
* 新增的对象字符串等方法
17. 用css画一个三角形
18. 描述undefined和null的区别?????
* null代表空,undefined代表的是找不到
* undefined出现的场景
- 声明一个变量没有赋值,则变量值是undefined
- 获取一个对象没有的属性时,则值是undefined
- 函数没有return值,则函数的返回值就是undefined
- 函数的形参没有被赋值,则这个形参的值是undefined
* null出现的场景
- 原型链的终点是null(防止原型链死循环)
- 声明变量此时不想赋值,可以先赋值为null
- 调用函数传参占位
- 把一个对象的引用移除,把这个对象变成垃圾对象
19. 已知一个网页地址`http://www.baidu.com?a=1&b=2&c=3`,请封装一个方法提炼出这个地址中的参数,并以对象形式返回{a:1,b:2,c:3}
20. 封装一个扁平化数组的函数(flat),[1,[2,[3,4],5],6]====>[1,2,3,4,5,6]
21. 封装一个函数,求数组的交集,[1,2,3,4],[2,3,5,6]===>[2,3]
22. 封装一个函数,接收一个数字作为参数,检查它是不是4的次方数,如果是则返回true,否则返回false(进阶:不使用递归)
23. 后台给了一组数据,但是这组数据不是我们想要的
```js
const obj = [
{id:3,parent:2},
{id:1,parent:null},
{id:2,parent:1}
{id:4,parent:1}
]
```
把这个数据转为我们需要的格式
```js
const result = {
id:1,
parent:null,
children:[
{
id:2,
parent:1,
children:[
{
id:3,
parent:2
}
]
},
{
id:4,
parent:1
}
]
}
```
24. 浏览器的事件轮询机制
* js代码分为了同步代码和异步代码
* 其中异步代码又分为了宏任务和微任务
- 宏任务:整体的script,定时器,ajax,事件
- 微任务:Promise.then/catch/finally async/await
* js执行代码的顺序:先执行异步(整体的script)-->再执行同步--->再执行异步
* 事件轮询机制的过程
- js执行主线程同步代码
- js遇到宏任务会把宏任务交给浏览器的对应的管理模块(其实就是浏览器开启的多线程)
- js遇到微任务,会把微任务的回调函数直接放在微任务的回调队列中
- 当浏览器的管理模块中的异步需要被执行的时候,就会把回调函数放在宏任务回调队列中
- 当js主线程的同步代码执行完毕的以后,会先清空微任务队列,然后再去执行宏任务队列中的回调
- 当每次执行完一个宏任务的时候,都会去再次清空微任务队列
- 轮询检测宏任务队列中是否有代码需要执行
25. 执行上下文
* JS引擎并不是一行行的解析和执行代码,而是一段段的去分析和执行,当执行一段代码时,先开始做一些准备工作(1:开辟一块内存空间 2:创建变量对象(VO) 3:确定作用域链 4:确定this指向),这个准备工作被称作为执行上下文
* js可执行的代码段分为2种类型: 全局代码 、 函数代码
* 每执行一段代码,都会创建相对应的执行上下文,在脚本中可能存在多个执行上下文,因为有太多的执行上下文, JS创建了一个执行上下文栈(stack) 用来管理执行上下文
* 当js开始解析程序的时候,最先遇到的全局代码,此时向执行上下文栈中 压入一个全局执行上下文,全局的一定是在整体运行结束以后(页面关闭)才被清空
* 当执行一个函数的时候 会创建一个函数的执行上下文,并压入到执行上下文栈中,只要函数执行完成,会将函数从栈里弹出
26. 变量对象(声明提升的原理):
* 变量对象是 ECMAScript规范术语。在一个执行上下文中,变量对象才被激活
* 变量对象是储存了在上下文中定义的形参,实参,变量和函数声明
* 全局执行上下文的变量对象其实就是全局对象window,因为全局的变量和函数都是window对象的属性和方法
* 每次进入一个函数的的时候会创建对应的执行上下文,执行上下文的第一步就是创建变量对象(VO),收集所有形参,实参,变量声明和函数声明
- 先收集所有的形参和实参
- 再检查所有声明的函数,如果变量对象已经有相同名字的属性,则完全替换
- 检查所有的声明的变量,变成变量对象的属性,值是undefined,如果变量名和已经声明的形参或函数相同,则变量声明不会干扰已经存在的这类属性
27. 作用域链
* 作用域链的用途,是保证对 执行环境有权访问的所有变量和函数 的有序访问
* 作用域链是在当前函数被声明的时候,就已经产生了,但是没有最前端当前函数的变量对象
* 函数执行的时候会创建自己的变量对象,并把自己的变量对象推入该作用域链的前端形成完整的作用域链
* 作用域链的前端,始终都是当前执行的代码所在环境的变量对象。全局执行环境的变量对象window始终都是作用域链中的最后一个对象。
* 标识符解析是沿着作用域链一级一级地搜索标识符的过程。搜索过程始终从作用域链的前端开始,然后逐级地向后回溯,直至找到标识符为止(如果到window还找不到标识符,如果是查询值通常会导致错误发生)
28. this指向
* 先判断当前函数是否是call/apply/bind调用,如果是,则指向强制绑定的那个值
* 判断当前函数是否是被new实例化调用,如果是,则可能指向实例化对象,也可能指向构造函数的返回的对象类型
* 判断当前函数是否是被一个上下文对象调用,如果是则指向上下文对象(注意隐式丢失的情况 var fn = o.fn; o.fn = o1.fn)
* 函数默认调用,this指向window
* 严格模式下,如果某个函数没有调用者,则内部的this指向undefined
* 箭头函数没有自己的this,需要沿着作用域链去上一级函数查询this
## 复习--git
- 01.git 操作复习
1. 初始化本地仓库(`git init`)
2. 本地仓库提交(`git add . `, `git commit -m 'init/add/fixed/docs:xxxxxx'`)
3. 新建远程仓库,拿到远程仓库的ssh地址
4. 把本地仓库和远程仓库关联(`git remote add origin xxxxxxxxx`)
5. 把本地仓库向远程仓库提交(第一次:`git push -u origin master`,第二次:`git push`)
6. 去到当前仓库中的管理页面,把当前项目设置为开源
7. 拉取其他人代码(`git clone xxxx`||`git pull`)
8. 撤销工作区的改动(`git restore .`)
9. 取消远程仓库的关联(`git remote remove origin`)
- 02.免密登录的配置
1. 配置本地git用户名和gitee的用户名一致:`git config --global user.name "username"`
2. 配置本地git邮箱和gitee的邮箱一致:`git config --global user.email "email"`
3. 在任意命令行位置书写`ssh-keygen`,生成秘钥,拿到公钥的地址
4. 用记事本打开公钥文件,复制里边内容
5. 去gitee的公钥配置中,添加公钥,即可使用ssh免密操作
## Vue学习需要使用的插件
- vscode的vue2插件:
* Vetur -- Pine Wu
* Vue 3 Snippets----hollowtree
* vue-helper --- shenjiaolong
- 其他插件:
* vscode-icons 文件列表图标插件
* Prettier - Code formatter 格式化插件
## Vue基础概念
1. MVVM模型
* MVVM(Model-View-ViewModel)是一种软件架构设计模式
* MVVM分为三个部分:分别是M(Model,模型层 ),V(View,视图层),VM(ViewModel,视图数据层,V与M连接的桥梁,也可以看作为控制器)
+ M:模型层,值得是数据模型,主要负责业务数据相关;
+ V:视图层,顾名思义,负责视图相关,细分下来就是html+css层,为了更方便的展示Model层的数据;
+ VM:V与M沟通的桥梁,负责监听M或者V的修改,是实现MVVM双向绑定的要点
* ViewModel是Vue.js的核心,它是一个Vue实例,MVVM支持双向绑定,意思就是当M层数据进行修改时,VM层会监测到变化,并且通知V层进行相应的修改,反之修改V层则会通知M层数据进行修改
2. new Vue(options)中基础配置项
* el:配置项,代表当前vue实例要挂载的容器,可以是一个选择器的字符串,也可以是已经获取的DOM元素
* template:配置项,一个字符串模板。模板将会替换容器
* data:Vue 实例的数据对象
3. $mount挂载
* 如果 Vue 实例在实例化时没有收到 el 选项,则它处于“未挂载”状态,没有关联的 DOM 元素。
* 可以使用 vm.$mount() 手动地挂载一个未挂载的实例。
* 接受的参数可以是选择器string,也可以是一个获取的DOM元素,作为容器
* 我们可以使用$mount进行异步挂载
4. 模板的语法糖写法
* 容器内部也可以进行书写模板,切记不是DOM,而是模板
* 在vue实例化过程中,如果选项中存在template选项,则把template选项的内容作为模板替换容器
* 如果选项中不存在template,则把容器的outerHTML作为模板
5. data配置项详解
* data可以是一个对象,是Vue实例的数据对象
* data的数据会在实例对象vm上作为属性存放起来
* data也可以是一个函数,返回一个对象,对象中存放当前实例需要的数据,并且建议是一个函数
* 为什么组件内的data要书写为一个函数????
01. 当一个组件被定义,data 必须声明为返回一个初始数据对象的函数
02. 因为组件可能被用来创建多个实例(组件可能被复用)。
03. 如果 data 仍然是一个纯粹的对象,则所有的实例将共享引用同一个数据对象!则数据就会互相影响
04. 通过提供 data 函数,每次创建一个新实例后,我们能够调用 data 函数,从而返回初始数据的一个全新副本数据对象。
6. 插值语法注意事项:
* 插值语法中的变量都是从当前的vm对象上去寻找的
* 插值语法中可以书写任意表达式(由一个或者多个变量或值 配合0个或多个运算符组成的 被称作为表达式,表达式都会有返回值),不能书写语句
* 插值的变量可以是任意类型的,按照一定的规则转为字符串展示(Symbol除外)
## 指令系统
### 01. 什么是指令
* 指令 (Directives) 是带有 v- 前缀的特殊 attribute。指令 attribute 的值预期是单个 JavaScript 表达式 (插值语法区域)。
* 指令的职责是,当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM
### v-bind
1. v-bind的基础使用
* 模板中的属性值默认都是字符串格式的!!!
* 如果希望属性值的区域是一个插值语法区域,我们就可以使用v-bind指令
* v-bind:强制绑定(动态绑定):把一个模板中属性的值区域变成插值语法区域,在插值语法区域中可以执行表达式,也可以去实例上拿值
* v-bind可以直接简写为 `:`
* 在v-bind中我们经常的去拼接一些值,方法如下
01. `
`
02. `
`
2. v-bind动态类的设置
* 什么时候使用动态类?当类名是通过数据来控制是否添加的时候,才会使用动态类
* 情况1-字符串:当动态类只有一个类的时候,我们可以直接使用三元等表达式,返回一个字符串即可
* 情况2-对象:当动态类的类有一个或者多个的时候(固定个数),我们可以给动态类设置一个对象,每一个类名都是对象的key,值是一个布尔值代表是否开启当前的类
* 情况3-数组:当动态类的类有一个或多个,不确定数量的时候,可以使用数组,只要在数组中的类都会添加到DOM上,不能开启和关闭,但是可以操作数组来控制类
3. v-bind动态style的设置
* v-bind可以使用动态的style控制元素的样式
* 动态的style可以接受一个对象,对象的key就是style的属性,对象的值就是style的值,对象的值可以使用插值来进行实现
* 动态类style可以接受一个数组,数组中可以包含多个动态类对象
4. 批量强制绑定
* 很多时候我们需要把对象中的属性一个个的绑定在元素或者组件上,我们可以使用批量绑定
* v-bind批量绑定 直接使用 v-bind="需要展开的对象名即可",此种写法不能简写
### v-on 事件绑定
1. 事件的书写和methods选项
* 使用v-on执行给模板绑定原生事件
``
* 事件函数写在哪里?
- 原则上来说,在data中书写函数,并且是箭头函数,函数内的this是指向当前的vue实例对象,但是一旦写成了普通函数,则this指向全局window,严格模式下会指向null,都不是我们想要的,但是我们不会把函数书写在data中,1.必须书写箭头函数 2.函数和数据混杂在一起不容易维护(data就是为了写数据的)
- methods选项中用来书写方法,比如事件回调函数,也有我们自己封装的函数等。methods中的方法已经被vue统一处理过了,vue控制methods中所有的方法的this指向当前的vue实例,为什么要把methods方法的this指向vm实例呢?因为方法一般都是用来操作数据的,而数据都在vm实例上放
* methods中的方法也会全部的放在vm实例上,供我们使用
2. event事件对象的获取
* 默认事件函数接收的第一个参数就是event事件对象(js的event对象),我们可以直接接收使用
* e.target就能获取当前事件所在的元素(真实DOM)
* 当事件函数传递参数的时候,则事件函数的第一个参数不再默认是event事件对象了,在事件指令的插值语法区域,默认存在着一个变量$event代表的就是当前事件的event事件对象,如果传参的事件函数需要event事件对象,我们可以直接把$event显性的传递进事件函数中
3. 事件函数的传参
* 如果想要给事件函数传递参数,则在绑定事件函数的时候,直接书写参数即可
* 在代码运行的时候,只要我们不触发事件,事件属性值的内容是不会有任何执行的
* 当事件触发以后,事件属性值内部的代码才会触发执行,并直接传入的参数
4. 事件逻辑的简单写法
* 如果事件的逻辑很简单,只是简单的一句操作数据,则可以不用书写函数,直接把逻辑写在事件的插值中即可
5. 事件修饰符
* 修饰符是对某条指令的补充
* .stop:阻止事件传播
* .capture:让当前的事件在捕获的阶段执行
* .prevent:阻止默认事件
* .self:只有事件真正发生在自己身上的时候才会触发
* .once:一次性事件
* .enter:按键修饰符-回车键
* ... 其他按钮修饰符
### v-model数据双向绑定
1. v-model的基础使用
* v-model 指令在表单 、