Vue2+Vue3

Vue2

安装Axios:npm install axios --save --legacy-peer-deps

vue的概念

  1. Vue是一个用于构建用户界面的渐进式框架
  2. vue的两种使用方式
    • Vue核心包开发:场景–局部模块构造
    • Vue核心包&Vue插件工程化开发:场景–整站开发

创建Vue实例初始化渲染

核心步骤4步

  1. 准备容器
  2. 引包
  3. 创建Vue实例 new Vue()
  4. 指定配置项 -> 渲染数据
    • el 指定挂载点
    • data 提供数据

插值表达式

插值表达式{{}}

  1. 作用:利用表达式进行插值,渲染到页面中
  2. 表达式:是可以被求值的代码,JS引擎将其JS出一个结果
  3. 语法:{{表达式}}
  4. 注意点
    • 使用的事件必须存在
    • 支持表达式,而非语句,比如:if for …
    • 不能在标签属性中使用插值表达式

vue核心特性:响应式

  1. 响应式:数据变化,视图自动更新
  2. 如何访问或修改数据?
    • data中的数据,最终会被添加到实例上
    • 访问数据: “实例.属性名”
    • 修改数据:”实例.属性名” = “值”

Vue指令

  1. 指令技术带有v-前缀的特殊属性,不同属性对应不同的功能。

  2. v-html

    • 语法:v-html = "表达式" ->动态设置元素innerHTML
  3. v-show

    • 作用:控制元素显示隐藏
    • 语法: v-show = "表达式" ,表达式值true显示,false隐藏
    • 场景:频繁切换显示的场景
  4. v-if

    • 作用:控制元素显示隐藏
    • 语法: v-if= "表达式" ,表达式值true显示,false隐藏
    • 场景:要么显示,要么隐藏,不频繁切换的场景
  5. v-show 和 v-if对比

    • v-show 底层原理:切换css的display :none 来控制显示隐藏
    • v-if底层原理:根据判断条件控制元素创建和移除(条件渲染)
  6. v-else 和 v-else-if

    • 作用:辅助v-if进行判断渲染
    • 语法:v-else v-eles-if = "表达式"
    • 注意:需要紧挨着v-if一起使用
  7. v-on

    1. 作用:注册事件 = 添加监听 + 提供处理逻辑
    2. 语法
      • v-on:事件名=”内联语句”
      • @事件名 = “内联语句”
      • v-on:事件名 = “methods中的函数名”
      • @事件名 = “methods中的函数名”
      • methods函数内的this指向Vue实例
    3. 调用传参
      • @事件名 = “fn(参数1,参数2)”
  8. v-bind

    • 作用:动态的设置HTML的标签属性,如 : src , url,title…
    • 语法:v-bind:属性名 = "表达式"
    • 简写: :属性名
  9. v-for

    1. 作用:基于数据循环,多次渲染整个元素。

    2. 应用于数组,对象,数字

    3. 遍历数组语法:v-for="(item,index) in 数组名"

    4. index可以省略,如果括号只有一个元素,括号可以省略。

    5. key

      • 语法:key属性 = “唯一标识”
      • 作用:给列表项添加的唯一表示,便于Vue进行列表项的正确排序复用。
      • 注意点
        • key的值只能是字符串或者数字类型
        • key的值必须具有唯一性
        • 推荐使用id作为key(唯一),不推荐使用index作为key(会变化,不对应)
  10. v-model

    1. 作用:给==表单元素==使用,双向数据绑定 ->可以快速获取或设置表单元素内容。

      • 数据变化 -> 视图自动更新
      • 视图变化 -> 数据自动更新
    2. 语法 :v-model = "变量"

    3. 时间戳:+new Date()

    4. 用于其他表单元素

      • 它会根据控件类型自动选取正确的方法来更新元素

数组方法常用

  1. filter:根据条件,保留满足条件的对应项,得到一个新数组。将新数组赋值回原数组

    1
    this*.list = this.list.filter(item => item.id != id )
  2. unshift:数组添加

    1
    2
    3
    4
    this.daskList.unshift({
    id: +new Date(),
    name: this.daskName
    })
  3. 数组清空

    1
    this.list = []
  4. 数组累加:

    1
    this.list.reduce((sum, item) => sum + item.price, 0)
  5. 数组移除关键字:

    1
    2
    3
    4
    5
    6
    7
    const index = this.history.indexOf(key)

    if (index !== -1) {

    this.history.splice(index, 1)

    }

指令修饰符

  1. 通过”.”指明一些指令后缀,不同后缀封装了不同的处理操作 –> 简化代码

  2. 按键修饰符:@keyup.enter ->键盘回车监听

  3. v-model修饰符:

    • v-model.trim -> 去除首尾空格
    • v-model.number -> 转数字
  4. 事件修饰符

    • @事件名.stop -> 阻止冒泡
    • @事件名.prevent -> 阻止默认行为
  5. v-bind对于样式控制的增强

    1. 为了方便开发者进行样式控制,Vue扩展了v-bind的语法,可以针对class类名和style行内样式进行控制。

    2. 操作class

      1. 对象 ->键就是类名,值是布尔值。如果值为true,有这个类,否则没有这个类。适用场景:一个类名,来回切换

        语法: :class=”{active : activeIndex == index}”

      2. 数组 -> 数组中所有的类,都会添加到盒子上,本质就是一个class列表。适用场景:批量添加或删除类。

    3. 操作style

      1. 语法 :style = “样式对象”
      2. image-20231130201402061
      3. 适用场景:某个具体属性的动态设置

计算属性

  1. 概念:基于现有的数据,计算出来的新属性。依赖的数据变化,自动重新计算
  2. 语法:
    1. 声明computed配置项中,应该计算属性对应一个函数
    2. 使用起来和普通属性一样使用
    3. image-20231130211259294
  3. 缓存特性(提升性能):计算属性会对计算出来的结果缓存,再次使用直接读取缓存,依赖项变化了,会自动重新技术→并再次缓存。
  4. 计算属性完整写法
    1. 计算属性默认的简写,只能读取访问,不能修改
    2. 如果要修改→需要写计算属性的完整写法
    3. image-20231130215437930
  • computed计算属性VS methods方法

    • image-20231130214957773

watch监听器

  1. 作用:监听数据变化,执行一些业务逻辑或者异步操作。

  2. 语法:

    1. 简单写法 →简单类型数据,直接监听

    2. image-20231201153245369

    3. 完整写法 ->添加额外配置项

      • deep:true 对复杂类型深度监视

      • immediate:true 初始化立刻执行一次handler方法

        image-20231201164740714

水果店案例

image-20231201195450835

将数据存储到本地

1
2
3
4
5
6
7
8
9
watch:{
fruitList:{
deep:true,
handler(*newVulue*){
localStorage.setItem("list",JSON.stringify(*newVulue*))
​ }
​ }
​ }

将数据从本地读取

1
2
3
data: {
fruitList:JSON.parse(localStorage.getItem("list")) || fruitArr
​ },

生命周期

  1. Vue生命周期:一个Vue实例从创建到销毁的整个过程。

  2. 生命周期的四个阶段:

    • 创建:响应式数据,创建一次
    • 挂载:渲染模板,挂载一次
    • 更新:数据修改,更新视图,循环更新
    • 销毁:销毁实例
  3. Vue生命周期函数(钩子函数)

    • Vue生命周期过程中,会自动运行一些函数,被称为“生命周期钩子”->让开发者可以在特定阶段运行自己的代码。
  4. 八个钩子函数

    • beforeCreate:
    • created:发送初始化渲染请求
    • befor eMount:
    • Mounted:操作dom对象
    • beforeUpdate:
    • Updated:
    • beforeDestroy:释放Vue意外的资源(清楚定时器,延时器)
    • destroyed
  5. created应用

    • 响应式数据准备好了,可以开始发送初始化渲染请求。
  6. mounted应用

饼图渲染

  1. 初始化一个饼图ECharts 在==mounted钩子==实现,基于准备好的都dom,初始化echarts实例

  2. 根据数据实时更新数据

    1
    2
    3
    4
    5
    mounted() {
    this.myChart = echarts.init(document.getElementById('main'));
    // 绘制图表
    this.myChart.setOption({})
    }

工程化开发&脚手架Vue CLI

  1. 工程化开发模式:基于构建工具(例如:webpack)的环境开发Vue
  2. 脚手架Vue cli 步骤
  3. image-20231202085450861
  4. 过程目录结构
  5. image-20231202090825643
  6. main.js文件作用:导入App.Vue,基于App.Vue创建结构渲染index.html
  7. 项目运行流程
  8. image-20231202091943212

组件化开发&根组件

  1. 组件化:应该页面可以拆分为一个个组件,每个组件都有自己独立的结构,样式,行为。
  2. 好处:便于维护,利于复用 ->提升开发效率
  3. 组件分类:普通组件,根组件
  4. 根组件:整个应用最上层的中间,包裹所有普通小组件
    1. image-20231202092656461
    2. App.vue文件的三部分组成
      1. template:结构(有且只能一个根元素)
      2. script:js逻辑
      3. style:样式(可支持less,需要装包)
      4. image-20231202093052740
      5. 让style支持less
        • 给style加上lang=”less”
        • 安装依赖包 less less-loader
        • yarn add less less-loader -D(开发依赖)
        • npm安装:npm install less-loader less --save-dev

普通组件的注册使用

  1. 组件注册的两种方式

    1. 局部注册:只能在注册的组件内

      • 创建.vue文件(三个组成部分)

      • 在使用的组件内导入并注册

        image-20231202104720976

  2. 全局注册:所有组件内都能使用

    • 创建.vue文件(三个组成部分)

    • main.js中进行全局注册

      image-20231202104902291

  3. 注意:

    • 组件名规范 ->大驼峰命名法,如:HmdHeader
  4. 使用

    • 当成HTML标签使用<组件名></组件名>
  5. 技巧:

    • 一般都用局部注册,如果发现确实是通用组件,再抽离到全局
  6. 页面开发思路

    image-20231202121704546

组件的三大组成部分(结构、样式、逻辑)

  1. 组件 的样式冲突scoped
    1. 默认情况:写在组件中的样式会==全局生效==,因此很容易造成多个组件之间的样式 冲突问题。
    2. 全局样式:默认组件中样式会作用到全局
    3. 局部样式:可以给组件加上scoped属性,可以让样式只作用域当前组件。
    4. scoped原理
      • 当前组件内标签都被添加data-v-hash值的属性
      • css选择器都被添加[data-v-hash]的属性选择器
      • 最终效果:必须是当前组件的元素,才会有这个自定义属性,才会被这个元素作用到
  2. data是一个函数
    1. 应该组件的data选项是一个函数。保证每个组件实例,维护==独立==的一份数据对象。
    2. 每次创建新的组件实例,都会新执行一次data函数,得到一个==新对象==。

组件通信

  1. 组件通信,就是指==组件与组件==之间的==数据传递==

  2. 组件关系分类

    1. 父子关系

    2. 非父子关系

      image-20231202161500292

      image-20231202161511028

    3. 组件通信解决方案

      image-20231202161657695

      image-20231202161704414

    4. 父 -> 子: 父组件通过props将数据传递给子组件

    5. 子- > 父: 子组件**利用this.$emit(事件名,参数)**通知父组件,进行修改更新。

    6. 非父子: provide & inject 或者eventbus

    7. 通用方案 - > vuex

  3. prop

    1. 定义:组件上注册的一些自定义属性
    2. 作用:向子组件传递数据
    3. 特点
      • 可以传递任意数量的prop
      • 可以传递任意类型的prop
  4. props校验

    1. 为组件的prop指定验证要求,不符合要求,控制台就会有错误提示,帮助开发者快速发现错误
      • 语法:
        • 类型校验
        • 非空校验
        • 默认值
        • 自定义校验
    2. image-20231202201443772
  5. prop&data /单向数据流

    1. 共同点:都可以给组件提供数据

    2. 区别

      • data的数据是自己的-> 随便改
      • prop 的数据是外部的->不能直接改,要遵循单向数据流
    3. 单向数据流

      • 父组件的prop更新,会单向向下流动,影响到子组件。
    4. 口诀:谁的数据谁负责

  6. 非父子通信(拓展)-event bus ==事件总线==

    1. 作用:非父子组件之间,进行简易消息传递。(复杂场景 ->VueX)

    2. 创建一个都能访问到的事件总线(空Vue实例) -> utils/EvenBus.js

      image-20231202221052050

    3. A组件(接收方),监听Bus实例的事件

      image-20231202221130340

    4. B组件(发送方),触发Bus实例的事件

      image-20231202221203651

      image-20231202221225377

  7. 非父子通信(拓展) -provide & inject

    1. provide & inject作用:跨层级共享数据

    2. 父组件provide提供数据

      image-20231202225024463

    3. 子/孙inject取值使用

      image-20231202225104975

      image-20231203130629851

    4. 当数据类型为复杂类型如对象,推荐使用此方法

V-model原理

  1. 原理:v-model本质上是一个语法糖。例如应用在==输入框上==,就是value属性和input事件的合写。

  2. 作用:提供数据的双向绑定

    • 数据变,视图跟着变 :value
    • 视图变,数据跟着变 @input
  3. 注意:$event用于在模板中,获取事件的形参

  4. image-20231203132340043

  5. 表单类组件封装 & v-model简化代码

    1. 表单类组件封装

      • 父传子: 数据应该是父组件props传递过来的,v-model拆解绑定数据
      • 子传父:监听输入,子传父传值给父组件修改。
      • image-20231203135439108
    2. 父组件 v-model简化代码,实现子组件和父组件数据双向绑定

      • 子组件中props通过value接收,事件触发input
      • 父组件中:v-model个组件直接绑定数据(==:value + @input==)
      • image-20231203140059526

.sync修饰符

  1. 作用:可以实现子组件与父组件数据的双向绑定,简化代码
  2. 特点:prop属性名,可以自定义,非固定value
  3. 场景:封装弹框类的基础组件,visible属性 == true显示,false隐藏
  4. 本质:就是 :属性名和@updata:属性名合写
  5. image-20231203144057950

ref和$refs

  1. 作用:利用ref 和$refs可以用于==获取dom元素==,或组件实例
  2. 特点:查找范围 -> 当前组件内(更精确稳定)
  3. 获取dom:
    1. 目标标签 - 添加 ref 属性
    2. image-20231203150323860
    3. 恰当时机,通过this.$refs.xxx,获取目标标签
    4. image-20231203150853312
    5. querySelector查找范围 -> 整个页面
    6. image-20231203150937439

Vue异步更新/$nextTick

  1. 需求:编辑标题,编辑框自动聚焦

    • 点击编辑,显示编辑框
    • 让编辑框,立刻获取焦点
  2. $nextTick:等Dom更新后才会触发执行此方法里的函数体

  3. 语法:this.$nextTick(函数体)

  4. image-20231203155128802

自定义指令

  1. 定义:自己定义的指令,可以封装一些dom操作,扩展额外功能
  2. 全局注册 - 语法
    • image-20231203161809436
  3. 局部注册-语法
    • image-20231203161831975
  4. 使用
    • image-20231203161851099
  5. ==el就是指令所绑定的元素==
  6. 指令的值
    1. 语法:在绑定指令是,可以通过“等号” 的形式为指令绑定具体的参数值
    2. image-20231203163802947
    3. 通过binding.value可以拿到指令值,==指令值修改==会触发update函数。
    4. image-20231203163850488
  7. 自定义指令— v-loading指令封装
    1. 场景:实际开发过程中,发送请求需要时间,在请求的数据未回来时,页面会处于空白状态 =》用户体验不好
    2. 需求:封装一个v-loading指令,实现加载中的效果
    3. 分析:
      • image-20231203170325339
      • image-20231203170331558

插槽 - ==默认插槽==

  1. 作用:让组件内部的一些==结构==支持==自定义==。
  2. 组件内需要定制的结构部分,改用占位
  3. 使用组件时,标签内部,传入结构替换slot.
  4. image-20231204150226867

插槽-后备内容(默认值)

  1. 封装组件时,可以为预留的插槽提供后备内容(默认内容)
  2. 语法:在标签内放置内容,作为默认显示内容
  3. 效果:
    • 外部使用组件时,不传东西,则slot会显示后备内容
    • 外部使用组件时,传东西了,则slot整体会被换掉。
    • image-20231204151657143

具名插槽(具有名字的插槽)

  1. 需求:一个组件内有多处结构,需要外部传入标签,进行定制。

  2. 语法

    1. 多个slot使用==name属性==区分名字
    2. image-20231204152443025
    3. ==template==配合v-slot:名字来分发对应标签
    4. image-20231204152529608
    5. ==v-slot: 插槽名== 可以简化为 ==#插槽名==

作用域插槽

  1. 定义slot插槽的同时,是可以传值的。给插槽上可以绑定数据,将来使用组件时可以用
  2. 基本使用步骤
    1. 给slot标签,以添加属性的方式传值
    2. image-20231204154658368
    3. 所有添加的属性,都会被收集到一个对象中
    4. image-20231204154733234
    5. 在template中,通过 “#插槽名 = “obj”接收,默认插槽名为default
    6. image-20231204154828487

单页应用程序(SPA)

  1. 单页面应用(SPA):所有功能在一个HTML上实现
  2. image-20231205101440530
  3. 单页面应用场景:系统类网站,内部网站,文档类网站,移动端站点
  4. 多页面应用场景:公司官网,电商类网站

路由

生活中的路由:设备和ip的映射关系

Vue中路由:==路径和组件==的映射关系,根据路由就能知道不同路径的,应该匹配渲染哪个组件

  1. ==VueRouter介绍==

    • 作用:修改地址栏路径时,切换显示匹配的组件

    • 使用步骤(5+2)

      1. 下载
      2. image-20231205103226905
      3. 引入
      4. image-20231205103239703
      5. 安装注册
      6. image-20231205103249288
      7. 创建路由对象
      8. image-20231205103321374
      9. 注入,将路由对象注入到new Vue实例中,建立关联
      10. image-20231205103351995
      11. image-20231205103156579
    • 2个核心步骤

      1. 创建需要的组件(views目录),配置路由规则
      2. image-20231205104342675
      3. 配置导航,配置路由出口(路径匹配的中间显示的位置)
      4. image-20231205104616330
  2. 组件存放目录问题

    1. 组件分类:.vue文件分 2类;页面组件&复用组件

    2. 分类开来更易维护

      • scr/views文件夹–页面组件:页面展示-配合路由用
      • scr/components文件夹–复用组件:展示数据-常用于复用

路由的封装抽离

  • 目标:将路由模块抽离出来。好处:拆分模块,利于维护。

声明式导航-导航链接

  1. 需求:实现导航高亮效果
  2. vue-router提供了一个全局组件router-link(取代a标签)
  3. 能跳转,配置to属性指定路径(必须)。本质还是a标签,to无需#。
  4. 能高亮,默认就会提供高亮类名,可以直接设置高亮样式。
  5. image-20231205164041785
  6. router-link-active 模糊匹配(用的多)
  7. image-20231205164949002
  8. router-link-exact-active 精确匹配
  9. image-20231205165025296
  10. 自定义匹配的类名
    • image-20231205170119206

声明式导航-跳转传参

  1. 目标:在跳转路由是,进行传值。
  2. 查询参数传参==(比较适合传多个参数)==
    • 语法:to = "/path ? 参数名 = 值"
    • 对应页面组件接收传递过来的值:$route.query.参数名
  3. 动态路由传参==(优雅简洁,传单个参数比较方便)==
    1. 配置动态路由
    2. image-20231205172210737
    3. 配置导航链接
    4. to = “ /path/参数值”
    5. 对应页面组件接收传递过来的值:$route.params.参数名
    6. 动态路由参数可选符
      • image-20231205173902440
  4. image-20231205173231886

Vue路由-重定向

  1. 问题:网页打开,url默认是/路径,未匹配到组件时,会出现空白
  2. 说明:重定向-》匹配path后,强制跳转path路径
  3. 语法:{path: 匹配路径,redirect:重定向到的路径}
  4. image-20231205174436212

Vue路由-404

  1. 作用:当路径找不到匹配时,给个提示页面
  2. 位置:配在路由最后
  3. 语法:path: “* “(任意路径)-前面不匹配就命中最后这个
  4. image-20231205174821741

Vue路由-模式设置

  1. 问题:路由的路径看起来不自然,有#。
  2. hashi路由(默认) 例如:http://localhost:8080/#/home
  3. history路由(常用) 例如:http://localhost:8080/home(以后上线需要服务器端支持)
  4. image-20231205175752782

编程式导航-基本跳转

  1. path路径跳转(简易方便)
  2. image-20231205180850502
  3. name命名路由跳转(适合path路径长的场景)
  4. image-20231205212648908

编程式导航-路由传参

  1. path路径跳转传参(query传参)
  2. image-20231205213922980
  3. path路径跳转传参(动态路由传参 )
  4. image-20231205214041352
  5. name命名路由跳转传参(query传参)
  6. image-20231205220144032
  7. 接收:$route.query.参数名
  8. name命名路由跳转传参(动态路由传参)
  9. image-20231205220301765
  10. 接收:$route.params.参数名
  11. 小结
    • image-20231205220923419
    • image-20231205221001960

嵌套路由

  1. 通过==children配置项==,可以配置嵌套子路由
    • 在children配置项红,配置规则
    • 准备二级路由出口
  2. 返回上一页:==$router.back()==

组件缓存Keep-alive

  1. 路由跳转后,组件被销毁了,返回回来组件又被重建了,所以数据重新被加载了
  2. 定义:keep-alive是Vue的内置组件,当它包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。
  3. Keep-alive是一个抽象组件:它自身不会渲染成一个dom元素,也不会出现在父组件链中
  4. Keep-alive的优点
    1. 在组件切换过程中把切换出去的组件保留在内存中,放置重复渲染dom
    2. 减少加载时间及性能消耗,提高用户体验性
    3. image-20231206195420334
    4. 问题:缓存了所有被切换的组件
  5. Keep-alive的三个属性
    1. include:组件名数组,只有匹配的组件会被缓存
    2. exclude:组件名数组,任何匹配的组件都不会被缓存
    3. max:最多可以缓存多少组件实例
    4. 当组件被缓存了,就不会再执行组件的created,mounted,updated等钩子函数,所以提供了两个钩子函数:
      • ==actived==
      • deactived
      • image-20231206201147010

自定义创建项目

  1. 目标:基于Vuecli自定义创建项目架子
  2. image-20231206202806585

ESlint代码规范

代码规范错误

  • 自动修正:基于vscode插件Eslint高亮错误,并通过配置自动帮助我们修复错误。

    image-20231207150123999

Vuex

  1. 定义:vuex是一个vue的==状态管理工具==,状态就是数据—vuex是一个插件,可以帮我们管理vue通用的数据(多组件共享的数据。

  2. 应用场景:

    • 某个状态在很多个组件来使用(个人信息)
    • 多个组件共同维护一份数据(购物车)
    • image-20231207151340497
  3. 优势:

    • 共同维护一份数据,数据集中化管理
    • 响应式变化
    • 操作简洁(vuex提供了一些辅助函数)
  4. 创建一个空仓库

    1. 安装vuex—npm i vuex@3
    2. 创建vuex模块文件专门存放vuex
    3. Vue.use(Vuex)创建仓库(new Vuex.Store())
    4. 在main.js中导入挂载到Vue实例上

核心概念–state状态

  1. 提供数据:State提供唯一的公共数据源,所有共享的数据都要统一放到Store中的State中存储。在state对象中可以添加我们要共享的数据
  2. image-20231207160808776
  3. 使用数据
    • 通过store直接访问
    • 通过辅助函数
      1. mapState是辅助函数,帮助我们把store中的数据自动映射到组件的==计算属性==中
      2. 导入==mapStore==:import {mapState}from’vuex’
      3. 数组方式引入state:mapState([‘count’])
      4. 展开 运算符映射:computed:{ …mapState([‘count’])}
    • image-20231207160851831

核心概念–mutations

  1. Vuex同样遵循单向数据流,组件中不能修改仓库的数据

  2. 通过strict: true 可以开启严格模式

  3. image-20231207163902254

  4. 定义mutations对象,对象中存放==修改state的方法==

  5. image-20231207172019135

  6. 组件中提交调用mutations

  7. image-20231207172100591

  8. 提交mutation是可以传递参数的==”this.$store.commit(‘xxx’,参数)”==

    1. 提供mutation函数(带参数–提交载荷payload)
    2. image-20231207193613349
    3. 页面中提交调用mutation
    4. image-20231207193637913
    5. mutation参数有且只有一个,如果需要多个参数,==包装成一个对象==。
    6. 处理输入框
      • image-20231207200252304
  9. 辅助函数:==mapMutations==

  10. mapMutations和mapState很像,它是把位于mutations中的方法提取了出来,映射到组件methods中

  11. image-20231207201600561

核心概念–actions

  1. actions处理异步操作,==不能直接操作state,要操作state,还是需要commit mutations==

  2. mutations必须是同步的(便于监测数据变化,记录调试)

  3. 提供actions方法

    image-20231207203001748

  4. 页面中dispatch(派送)调用

    image-20231207203824699

  5. ==辅助函数–mapActions==

    1. mapActions是把位于actions中的方法提取了出来,映射到组件methods中

    2. image-20231207205135623

    3. 调用

      image-20231207205250290

核心概念-getters

  1. 类似于计算属性

  2. 定义getters

    image-20231207210530861

  3. 访问getters

    1. 通过Store访问getters
    2. image-20231207210705105
    3. 通过辅助函数mapGetters映射
    4. image-20231207210744778
  4. 注意点

    • 形参第一个参数,就是state
    • 必须有返回值,返回值就是getters的值

核心概念–模块module

  • 由于Vuex使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得复杂时,Store对象就有可能变得相当臃肿。

  • image-20231207212406590

  • 模块拆分

    1. 如user模块:Store/modules/user.js

    2. image-20231207212755328

    3. 数据使用

      image-20231207212812009

模块中的state数据访问

  • 模块中state的访问语法
    • 尽管已经分模块了,但其实子模块的状态,还是会挂到根级别的 state中,属性名就是模块名
  • 使用模块中的数据
    • 直接通过模块名访问==$store.state.模块名.xxx==
    • 通过mapState映射
      • 默认根级别的映射==mapState([‘xxx’])==
      • 子模块的映射==mapState(‘模块名’,[‘xxx’])—需要开启命名空间
      • image-20231207214755858

模块中的getters的访问

使用模块中getters中数据

  • 直接通过模块名访问$store.getters['模块名/xxx']
  • 通过mapGetters映射
    • 默认根级别的映射mapGetters([‘xxx’])
    • 子模块的映射mapGetters('模块名',['xxx'])–需要开启命名空间

模块中mutations的调用方法

  1. 默认模块中mutation和actions会被挂载到全局,需要开启命名空间,才会挂载到子模块。
  2. 调用模块中的mutation
    • 直接通过store调用==$store.commit(‘模块名/xxx’, 额外参数)==
    • 通过mapMutations映射
      • 默认根级别的映射==mapMutatuins([‘xxx’])==
      • 子模块的映射==mapMutations(‘模块名’,[‘xxx’])==-需要开启命名空间

模块中action的调用语法

image-20231208154459080

综合案例

基于json -serve工具,准备后端接口服务环境

image-20231208162922004

项目实践

项目收获

  • image-20231208204321339

调整初始化目录

  1. 删除多余文件
  2. 修改路由配置和App.vue
  3. 新增两个目录api和utils
    • api接口模块:发送Ajax请求的接口模块。
    • utils工具模块:自己封装的一些工具方法模块。

vant组件库

  1. 安装

    1
    npm i vant@latest-v2 -s
  2. 按需导入组件

    1. image-20231208212134234
    2. image-20231208212203496
    3. 提取到vant-ui.js中,main.js导入

项目中的vw适配

基于postcss插件实现vw适配

响应拦截器统一 处理错误提示

问题:每次请求,都会有可能会错误,就都错误提示。

说明:响应拦截器是我们拿到数据的第一个数据流转站,可以在里面==统一处理错误==。

vue3

crate-vue搭建Vue3项目

  1. create-Vue的Vue新的脚手架,底层切换到了vite,为开发提供极速响应。
  2. 使用create-vue项目
    1. 前提环境条件:已安装16.0或者更高的版本的Node.js
    2. 创建一个Vue应用:==npm init vue @latest==–这一指令将会安装并执行create-vue
  3. image-20231220210839768

组合式API选项

setup信息的写法和执行时机

  1. create-Vue的Vue新的脚手架,底层切换到了vite,为开发提供极速响应。
  2. 使用create-vue项目
    1. 前提环境条件:已安装16.0或者更高的版本的Node.js
    2. 创建一个Vue应用:npm init vue @latest–这一指令将会安装并执行create-vue
  3. image-20231220210839768

组合式API-reactive()函数

  1. 作用:接收对象类型数据的参数传入并返回一个响应式的对象。
  2. 核心步骤:
    1. image-20231220214627227
    2. 从vue包中导入reactive函数
    3. 在《script setu》中执行reactive函数并传入类型为==对象的初始值==,并使用变量接收返回值。

ref()函数

  1. 作用:接收==简单类型或者对象类型的数据==传入并返回一个==响应式的对象==
  2. 核心步骤:
    1. image-20231220215248347
    2. 从vue包中==导入ref函数==
    3. 在《script setup >中执行ref函数并传入初始值,==使用变量==接收ref函数的返回值
  3. 本质:是在原有传入数据的基础上,外层包了一层典型,宝成复杂类型
  4. 底层:包成复杂类型之后,再借助reactive实现的响应式
  5. 注意点:
    1. 脚本中访问数据,需要通过 ==.value==
    2. 在template中, ==.value==不需要加

computed()计算属性函数

  1. 计算属性基本思想和vue2的完全一致,组合式API下的计算属性只是修改了写法

  2. 核心步骤

    1. 导入computed函数

    2. 执行函数在回调参数return基于响应式数据做计算的值,用==变量接收==

      image-20231220221818551

watch函数

  1. 作用:侦听一个或者多个数据的变化,数据变化是执行回调函数
  2. 两个额外参数:1.immediate(立即执行) 2.deep(深度侦听)
  3. 侦听单个数据
    1. 导入watch函数
    2. 执行watch函数传入要侦听的响应式数据(ref对象)和回调函数
    3. image-20231220223422123
  4. 侦听多个数据
    1. 同时侦听多个响应式数据的变化,不管哪个数据变化都需要执行回调
    2. image-20231220223656664
  5. immediate
    1. 说明:在侦听器 ==创建时立即触发回调==,响应式数据变化之后继续执行回调。
    2. image-20231221155817079
  6. deep
    1. watch监视默认进行的是浅层监视。如:
    2. const ref1 = ref(简单类型)可以直接监视
    3. const ref2 = ref(复杂类型)监视不到==复杂内部数据==的变化,需要用到==deep: true==
  7. 精确侦听==对象的某个属性==
    1. 需求:在不开启deep的前提下,侦听age的变化,只有age变化时才执行回调
    2. image-20231221161516041

生命周期函数API

  1. image-20231221162149110

父子通信

父传子

  1. 父组件中 给子组件绑定属性
  2. 子组件内部通过props选项接收
  3. image-20231221163116958
  4. defineProps原理: 就是编译阶段的一个表示,实际编译器解析是,遇到后会进行编译转换。

子传父

  1. 父组件中 子组件标签通过@绑定事件
  2. 子组件内部通过emit方法触发事件
  3. image-20231221164718539

总结

image-20231221170514871

模板引用

  1. 概念: 通过==ref标识==获取真实的dom对象或者组件实例的对象。
  2. 调用ref函数生成一个ref对象
  3. 通过ref标识绑定ref对象到标签
  4. image-20231221173833004
  5. ==defineExpose()==: 默认情况下在《script setup>语法糖下==组件内部的属性和方法是不开放==给父组件访问的,可以通过defineExpose编译红==指定哪些属性和方法允许访问。
  6. image-20231221175143622

provide和inject

  1. 作用和场景:顶层组件向任意的底层组件传递数据和方法,实现夸层组件通信。

  2. 跨层传递普通数据

    1. 顶层 组件提供==provide函数提供==数据
    2. 底层组件通过==inject函数获取==数据
    3. 顶层组件:image-20231221175940285
    4. 底层组件:image-20231221175956806
  3. 跨层传递函数

    1. 顶层组件可以向底层组件传递方法,底层组件调用方法修改顶层组件中的数据

    2. image-20231221181001864

vue3新特性

defineOptions

  1. 可以用defineOptions定义任意的选项,props,emits,expose,slots除外
  2. image-20231221181905494

defineModel

  1. 在vue3中,自定义组件上使用v-model,相当于传递一个modelValue属性,同时触发update:modelValue事件。
  2. image-20231221220133960
  3. image-20231221220154472
  4. image-20231221220235242

pinia

pinia是Vue的最新状态管理工具,是VueX的替代品。

优点

  1. 提供更加简单的API(去掉了mutations)
  2. 提高符合,组合式风格的API(和Vue3新语法统一)
  3. 去掉了modules的概念,每一个store都是一个独立的模块
  4. 配合TypeScript更加友好,提供可靠的类型推断。

pinia持久化插件

  1. 安装插件:

    1
    npm i pinia-plugin-persistedstate
  2. main.js使用

    1
    2
    1. import persist from 'pinia-plugin-persistedstate'
    2. app.use(createPinia().use(persist))
  3. store仓库中,persist: true开启。

总结

image-20231222165337846