Vue


# Vue基础知识

# 基本语法

# el挂载点:

1.Vue实例的作用范围是什么呢?

ans:Vue会管理el选项命中的元素及其内部的后代元素

2.是否可以使用其他的选择器?

ans:可以使用其他的选择器,但是建议使用ID选择器

3.是否可以设置其他的dom元素?

ans:可以使用其他的双标签,不能使用HTML和BODY

# v-text

1.作用:设置标签的内容

2.默认写法会替换全部内容,使用差值表达式{{}}可以替换指定内容

# v-show

1.作用:根据真假切换元素的显示状态

2.原理是修改元素的display,实现显示隐藏

3.指令后面的内容,最终都会解析为布尔值

4.值为true元素显示,值为false元素隐藏

5.数据改变之后,对应元素的显示状态会同步更新

# v-if

1.作用:根据表达式的真假切换元素的显示状态

2.本质:通过操作dom元素来切换显示状态

3.值为true元素元素存在dom树中,值为false,从dom树中移除

4.频繁的切换v-show,反之使用v-if,前者的切换消耗小

# v-for

1.作用:根据数据生成列表结构

2.数组经常和for结合使用

3.语法是(item,index) in 数据

4.item和index可以结合其他指令一起使用

5.数组的更新会同步到页面上,是响应式的。

# detailes

事件修饰符

  • @click.prevent ==> 阻止事件默认行为
  • @click.stop ==> 阻止冒泡
  • @click.trim ==> 不保留行前行后空格

# 过滤器相关(Vue3已经废弃)

作用

  • 筛选加工

使用方式

  • <h1>\{\{ msg | filterA \}\}</h1> 双括号插值内。
  • <h1 v-bind:id=" meg | filterA">\{\{ msg \}\}</h1>v-bind绑定的值的地方.(msg为需要filter处理的值,filterA为过滤器。)

过滤器的例子

点击查看例子
<div id="app">
    <p>电脑价格:{{price | addPriceIcon}}</p>
</div>
<script>
 let vm = new Vue({
    el:"#app",
    data:{
        price:200
    },
    filters:{
        //处理函数
        addPriceIcon(value){
            console.log(value)//200
            return '¥' + value
        }
    }
 })
</script>
点击查看例子
<div id="app">
    //输入框
    <input type="text" v-model="content" @change="changeEvent">
     //显示层,后边加一个过滤器处理函数,把英文首字母变为大写
    <h3>{{viewContent | changeCapitalLetter}}</h3>
</div>
 
<script>
 let vm = new Vue({
    el:"#app",
    data:{
        viewContent:"",
        content:""    
    },
    methods:{
        changeEvent(){
            this.viewContent = this.content;
        }
    },
    filters:{
        changeCapitalLetter(value){//value是输入框的内容,也是要显示的内容
            if(value){
                let str = value.toString();
                //获取英文,以空格分组把字符串转为数组,遍历每一项,第一项转为大写字母
                let newArr = str.split(" ").map(ele=>{
                   return ele.charAt(0).toUpperCase() + ele.slice(1)
                });
                return newArr.join(" ")  //数组转字符串 以空格输出。。。
            }
        }
    }
 })
</script>

过滤器的注意点

  • 要定义到filters节点下,本质是一个函数
  • 在过滤函数中,一定要有return值
  • 在过滤器的形参中,就可以获取到“管道符”前面待处理的那个值
  • 如果全局过滤器和私有过滤器名字一致,此时按照“就近原则”,调用的是“私有过滤器”

# 路由

路由的概念和原理

  1. 什么是路由

路由(英文:router)就是对应关系。

  1. SPA 与前端路由

SPA 指的是一个 web 网站只有唯一的一个 HTML 页面,所有组件的展示与切换都在这唯一的一个页面内完成。
此时,不同组件之间的切换需要通过前端路由来实现。

结论:在 SPA 项目中,不同功能之间的切换,要依赖于前端路由来完成!

  1. 什么是前端路由

通俗易懂的概念:Hash 地址与组件之间的对应关系。

  1. 前端路由的工作方式

① 用户点击了页面上的路由链接
② 导致了 URL 地址栏中的 Hash 值发生了变化
③ 前端路由监听了到 Hash 地址的变化
④ 前端路由把当前 Hash 地址对应的组件渲染都浏览器中

结论:前端路由,指的是 Hash 地址与组件之间的对应关系!

路由的简易实现

  1. location.hash拿到锚链接的值
  2. 绑定onhashchange事件「使用箭头函数确保this的指向」
  3. 然后一个swich case实现就好了。

路由的小规则

  1. redirect:重定向跳转
  2. children:子路由规则---“不要加'/'”

默认子路由:如果children数组中,某个路由规则的Path值为空字符串,则为默认子路由

动态路由

  1. 动态路由是指把Hash地址中可变的部分定义为参数项,从而提高规则的复用性

# axios

axios的挂载

// (main.js)把axios挂载为$http的一个属性
Vue.prototype.$http = axios
// 今后,在每个vue组件中要发起请求,直接调用 this.$http.xxx
// 但是,把axios挂载到Vue原型上,有一个缺点:“不利于API接口的复用”

# 动态组件

<component is=""></component>

  1. component本质上是一个占位符
  2. is的值是要渲染的组件的名称
  3. 如果想要缓存这个组件,可以使用<keep-alive></keep-alive>,keep-alive有include 和 excluede 两种属性,不可以同时使用
  4. keep-alive的生命周期有两个,第一个是deactivated,第二个是activated。
  5. 如果在”声明组件“的时候没有name属性,则属性的名称默认为注册时的名称(一般用在标签里)。

# 插槽

  1. slot,插槽是为Vue的封装者提供的,作用是吧内容填充到指定名称的插槽中
  2. 在使用有具体名称的插槽时,需要在外层套一个<template>,在template中填入插槽的名字,v-slot的简写是#
  3. 作用域插槽:封装时为既留的slot提供属性对应的值,例如
<template #content="scope">
<slot>

</slot>
</template>
  1. 一般自定义的属性都在scope作用域里,可以这样访问到。
  2. 作用域插槽可以解构赋值。

# Promise

  1. 回调地狱

多层回调函数的相互嵌套,就形成了回调地狱。

  1. 基本概念
  • Promise是一个构造函数「可以new一个实例出来」

new出来的Promise实例对象,代表一个异步操作。const p = new Promise()

  • Promise.prototype上包含一个.then()方法

每一次new Promise()构造函数得到的实例对象都可以通过原型链的方式访问到.then()方法,例如p.then()

  • .then()方法用来预先指定成功和失败的回调函数

p.then(成功的回调函数,失败的回调函数)
p.then(result=>{},error=>{})
成功的回调函数必选,失败的回调函数必选

  1. Promise细化学习
  • .then()方法的特性

如果上一个.then()方法返回了一个新的Promise实例对象,则可以通过下一个.then()继续进行处理。通过.then()方法的链式调用,就解决了回调地狱的问题。

  • 基于Promise按顺序读取文件的内容
点击查看例子
import thenFs from 'then-fs'

thenFs.readFile('./files/1.txt/','utf8')
    .then((r1) => {
        console.log(r1)
        return thenFs.readFile('./files/2.txt/','utf8')
    })
    .then((r2) => {
        console.log(r2)
        return thenFs.readFile('./files/3.txt/','utf8')
    })
    .then((r3) => {
        console.log(r3)
    })
  • .catch捕获错误

在Promise的链式操作中发生了错误,可以使用Promise.prototype.catch 方法进行捕获和处理

点击查看例子
import thenFs from 'then-fs'

thenFs.readFile('./files/1.txt/','utf8')
    .then((r1) => {
        console.log(r1)
        return thenFs.readFile('./files/2.txt/','utf8')
    })
    .then((r2) => {
        console.log(r2)
        return thenFs.readFile('./files/3.txt/','utf8')
    })
    .then((r3) => {
        console.log(r3)
    })
    .catch(err => {
        console.log(err.message)
    })

如果不希望前面的错误导致后续的.then无法正常执行,则可以将.catch的调用提前

点击查看例子
import thenFs from 'then-fs'

thenFs.readFile('./files/11.txt/','utf8')
    .catch(err => {
        console.log(err.message)
    })
    .then((r1) => {
        console.log(r1)
        return thenFs.readFile('./files/2.txt/','utf8')
    })
    .then((r2) => {
        console.log(r2)
        return thenFs.readFile('./files/3.txt/','utf8')
    })
    .then((r3) => {
        console.log(r3)
    })
  • Promise.all()方法

Promise.all()方法会发起并行的Promise异步操作,等所有的异步操作全部结束后才会执行下一步的.then操作(等待机制)。

点击查看例子
import thenFs from 'then-fs'

const promiseArr = [
    thenFs.readFile('./files/1.txt/','utf8'),
    thenFs.readFile('./files/2.txt/','utf8'),
    thenFs.readFile('./files/3.txt/','utf8'),
]
// 实例顺序就是结果顺序
Promise.all(promiseArr).then(([r1,r2,r3]) => {
    console.log(r1,r2,r3)
})
.catch(err => {
    console.log(err.message)
})
  • Promise.race()方法

Promise.all()方法会发起并行的Promise异步操作,只要任何一个异步操作完成,就执行下一步的.then操作(赛跑机制)。

点击查看例子
import thenFs from 'then-fs'

const promiseArr = [
    thenFs.readFile('./files/1.txt/','utf8'),
    thenFs.readFile('./files/2.txt/','utf8'),
    thenFs.readFile('./files/3.txt/','utf8'),
]

Promise.race(promiseArr).then(result) => {
    console.log(result)
})
.catch(err => {
    console.log(err.message)
})
  1. 基于Promise封装读文件的方法
import fs from 'fs'

function getFile(fpath){
    return new Promise(function(resolve,reject){
        fs.readFile(fpath,'utf8',(err,dataStr) => {
            if(err) return reject(err)
            resolve(dataStr)
        })
    })
}

# async/await

async/await是ES8引入的新语法,用来简化Promise异步操作。在async/await出现之前,开发者只能通过链式.then()的方式处理Promise异步操作。

import thenFs from 'then-fs'

async function getAllFile() {
    const f1 = await thenFs.readFile('./files/1.txt','utf8');
    console.log(f1);
    const f2 = await thenFs.readFile('./files/2.txt','utf8');
    console.log(f2);
    const f3 = await thenFs.readFile('./files/3.txt','utf8');
    console.log(f3);
}
  • 注意事项
  1. 有await必须要async修饰。
  2. 在async方法中,第一个await之前的代码会同步执行,await之后的代码会异步执行。
console.log('A')
async function getAllFile(){
    console.log('B')
    const r1 = await thenFs.readFile('./file/1.txt','utf8');
    console.log(r1);
    const r2 = await thenFs.readFile('./file/2.txt','utf8');
    console.log(r2);
    const r3 = await thenFs.readFile('./file/3.txt','utf8');
    console.log(r3);
    console.log('D');
}
getAllFile()
console.log('C')
// 执行顺序
// A
// B
// C
// r1 r2 r3
// D

# EventLoop

  • JavaScript 是一门单线程执行的编程语言。也就是说,同一时间只能做一件事。

单线程的问题:如果前一个任务非常耗时,则后续任务就不得不一直等待,从而导致程序假死的问题。

  • 同步任务和异步任务

同步任务

  • 又叫非耗时任务,指的是在主线程上排队执行的那些任务。
  • 只有前一个任务执行完毕,才能执行后一个任务

异步任务

又叫耗时任务,异步任务由JavaScript委托给宿主环境进行执行。 当异步任务执行完成后,会通知JavaScript主线程执行异步任务的回调函数。

# 组件通信

一般有如下情况:

  • 父子组件通信
  • 兄弟组件通信
  • 跨多层级组件通信
  • 任意组件

# 生命周期

beforeCreate钩子函数调用的时候,是获取不到props或者data中的数据的,因为这些数据的初始化都在initState中。

然后会执行created钩子函数,在这一步的时候已经可以访问到之前不能访问到的数据,但是这时候组件还没被挂载,所以是看不到的。

接下来会先执行beforeMount钩子函数,开始创建VDOM,最后执行mounted钩子,并将VDOM渲染为真实DOM并且渲染数据。组件中如果有子组件的话,会递归挂载子组件,只有当所有子组件全部挂载完毕,才会执行根组件的挂载钩子。

接下来是数据更新时会调用的钩子函数beforeUpdateupdated,这两个钩子函数没什么好说的,就是分别在数据更新前和更新后会调用。

另外还有keep-alive独有的生命周期,分别为activateddeactivated。用keep-alive包裹的组件在切换时不会进行销毁,而是缓存到内存中并执行deactivated钩子函数,命中缓存渲染后会执行actived钩子函数。

最后就是销毁组件的钩子函数beforeDestroydestroyed。前者适合移除事件、定时器等等,否则可能会引起内存泄露的问题。然后进行一系列的销毁操作,如果有子组件的话,也会递归销毁子组件,所有子组件都销毁完毕后才会执行根组件的destroyed钩子函数。