Vue

49 阅读11分钟

一套用于构建用户界面的渐进式 JavaScript 框架,也是一个创建单页应用的Web应用框架


后知后觉模块

笔记备注说明

??? ---有问题未清楚明白

!!! --- 待扩展的点

** ** ----重点、工作中有用到的


模块标题

h1===> 系列模块划分

h2====> 系列

h5 ====> 知识点

  h6=== 一、【知识点需要分多条纬度】或 1. 【知识点只需要分一条纬度】

!!!待更新模块

  1. Vue的设计模式理解

  2. 虚拟dom

  3. 订阅发布模式

  4. bus总线

  5. MVVM/MVC架构


VUE系列之框架设计相关

前端框架带来了什么

www.godbasin.com/vue-ebook/v… [介绍了前端框架引入的这样的一个背景]

  1. 早期未使用框架的开发前端实现

(1) 字符串模版:使用拼接的方式生成 DOM 字符串,直接通过innerHTML()插入页面。 (2) 节点模版:使用createElement()/appendChild()/textContent等方法,动态地插入 DOM 节点。

var div = document.getElementById("div");/** 1. 字符串模版 **/
div.innerHTML = "<p>测试<a>test</a></p>";/** 2. 节点模版 **/const p = document.createElement("p");
p.textContent = "测试";const a = document.createElement("a");
a.textContent = "test";
p.appendChild(a);
div.appendChild(p);

2. 使用框架以后

数据绑定、界面更新、事件监听等都用最简单的方式提供给开发者,开发效率和代码可维护性也是直线上升。前端框架中很重要的一个功能——模板引擎

!!!MVVM/MVC架构

VUE的核心特性

vue3js.cn/interview/v…

1. 数据驱动(MVVM)

数据驱动视图:当我们想要改变页面上的某些内容时,我们不需要自己去操作****DOM ,我们只需要去改变相应的数据即可,然后vue这个框架会帮助我们去根据数据重新渲染视图。

  • Model:模型层,负责处理业务逻辑以及和服务器端进行交互
  • View:视图层:负责将数据模型转化为UI展示出来,可以简单的理解为HTML页面
  • ViewModel:视图模型层,用来连接Model和View,是Model和View之间的通信桥梁

ViewModel层怎么理解:

view和model之间通过****vue提供的viewmodel 理解成vue指令、vue框架运行时、响应式等模块 】来关联,当我们的model的数据改变之后,通过viewmodel可以马上反应到view层,而view中的一些 DOM 操作也可以通过viewmModel反应到Model 层。【双向绑定v-model、事件监听触发等?】

也可以降级将其理解成 viewModel层就是数据双向绑定原理

2. 组件化

组件化的优势:

  • 降低整个系统的耦合度,在保持接口不变的情况下,我们可以替换不同的组件快速完成需求,例如输入框,可以替换为日历、时间、范围等组件作具体的实现

  • 定位问题调试方便,由于整个系统是通过组件组合起来的,在出现问题的时候,可以用排除法直接移除组件,或者根据报错的组件快速定位问题,之所以能够快速定位,是因为每个组件之间低耦合,职责单一,所以逻辑会比分析整个系统要简单

  • 提高可维护性,由于每个组件的职责单一,并且组件在系统中是可被复用的,所以对代码进行优化可获得系统的整体升级

3. 指令系统

解释:指令 (Directives) 是带有 v- 前缀的特殊属性作用:当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM

  • 常用的指令

    • 条件渲染指令 v-if
    • 列表渲染指令v-for
    • 属性绑定指令v-bind
    • 事件绑定指令v-on
    • 双向数据绑定指令v-model

没有指令之前我们是怎么做的?是不是先要获取到DOM然后在....干点啥

vue渲染内容流程

www.godbasin.com/vue-ebook/v…

(1) 解析模板语法生成 AST。

(2) 根据 AST 结果,完成 data 数据初始化。

(3) 根据 AST 结果和 data 数据绑定情况,生成虚拟 DOM。

(4) 将虚拟 DOM 生成真正的 DOM 插入到页面中,此时页面会被渲染。

抽象语法树(Abstract Syntax Tree)也称为 AST 语法树,指的是源代码语法所对应的树状结构。也就是说,对于一种具体编程语言下的源代码,通过构建语法树的形式将源代码中的语句映射到树中的每一个节点上。

VUE系列语法知识相关

知识点:v-show和v-if的使用场景:

两者区别:

v-if 是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。 v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。 相比之下,v-show 就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。

汇总区别:

(1)手段:v-if是动态的向DOM树内添加或者删除DOM元素;v-show是通过设置DOM元素的display样式属性控制显隐;

(2)编译过程:v-if切换有一个局部编译/卸载的过程,切换过程中合适地销毁和重建内部的事件监听和子组件;v-show只是简单的基于css切换;

(3)编译条件:v-if是惰性的,如果初始条件为假,则什么也不做;只有在条件第一次变为真时才开始局部编译(编译被缓存?编译被缓存后,然后再切换的时候进行局部卸载); v-show是在任何条件下(首次条件是否为真)都被编译,然后被缓存,而且DOM元素保留; (4)性能消耗:v-if有更高的切换消耗;v-show有更高的初始渲染消耗

适用场景:

一般来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。

因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好

知识点:插槽相关理解

Vue的组件通信方式

  1. 组件之间通信分类
  • 父子组件之间的通信

  • 兄弟组件之间的通信

  • 祖孙与后代组件之间的通信

  • 非关系组件间之间的通信

  1. 组件间通信的方案

vue3js.cn/interview/v…

  1. 通过 props 传递
  2. 通过 $emit 触发自定义事件
  3. 使用 ref 【这种其实代码不好维护,但看组件,如果功能复杂,不好明确具体的意思,签约的表单组件】
  4. EventBus 【bus总线,可以直接用new Vue实例是因为 vue实例中刚好有emit,以及emit,以及on方法】
  5. parentparent 或root 【通过嵌套关系去传递 数据】
  6. attrs 与 listeners 【?????】
  7. Provide 与 Inject
  8. Vuex
  9. 插槽?

插槽传数据; 子组件向父组件传值

子组件 绑定数据 如 :data="" 父组件中slot-scope='data' ====接收到收据 在ui组件中用scope的

EventBUS总线

bus总线,可以直接用new Vue实例是因为 vue实例中刚好有emit,以及emit,以及on方法

!!!NextTick理解

vue3js.cn/interview/v…

Vue 在更新 DOM 时是异步执行的。当数据发生变化,Vue将开启一个异步更新队列,视图需要等队列中所有数据变化完成之后,再统一进行更新

!!!插槽理解

作用域插槽:

子组件在作用域上绑定属性来将子组件的信息传给父组件使用,这些属性会被挂在父组件v-slot接受的对象上

举例子:

虚拟滚动子组件:

<div v-for="(item, index) in showDataList" :key="index">
  <slot :thisItem="item"></slot>
</div>

虚拟滚动父组件:【父组件接受列表数据,去定制化列表项的布局】,更好的定制化组件封装。

<virtual-scroll v-slot:default="oneItem">
    <router-link class="one-new" to="/article">
    <!-- 新闻左侧标题、评论、来源部分 -->
    <div class="new-left">
        <h3>{{ oneItem.thisItem.title }}</h3>
        <div>
        <p>
            <img src="../assets/icons/msg.png" alt="评" />
            <span>{{ oneItem.thisItem.reads }}</span>
            <span>{{ oneItem.thisItem.from }}</span>
        </p>
        <h4>{{ oneItem.thisItem.date }}</h4>
        </div>
    </div>
    <!-- 新闻右侧图片部分 -->
    <div class="new-right">
        <img :src="imgsList[oneItem.thisItem.image]" alt="PIC" />
    </div>
    </router-link>
</virtual-scroll>

v-model理解

  1. v-model语法糖本质

blog.csdn.net/Little___Tu… 【本质】

对于v-model 我们可以理解为两个操作组成

1.v-bind绑定一个value属性

2.v-on给当前元素添加一个input事件

  1. v-model与v-bind区别
<input type="text" :value="data1">
<span>{{data1}}</span>

<input type="text" v-model="data2">
<span>{{data2}}</span>

<input type="text" v-model="data3" @input="change($event)">
<span>{{data2}}</span>

data() {
    return {
      data1: '1212', // 表单改变时候,视图层的data1不发生改变
      data2: 'xxxx2', // v-model改变的时候发生改变
      data3: '',  // 语法糖实现
    };
},

methods: {
    handleInput(event) {
      this.data3=event.target.value
    },
}

8. #### v-model应用子组件

juejin.cn/post/694486… 【介绍了v-model的应用到父子组件】

Vue修饰符

vue3js.cn/interview/v…

Vue的生命周期

生命周期介绍

Vue中实例从创建到销毁的过程就是生命周期,即指从创建、初始化数据、编译模板、挂载Dom→渲染、更新→渲染、卸载等一系列过程

vue生命周期流程图.webp

各生命周期对应做的事情.webp

具体过程分析:

  1. Vue实例初始化:会初始化事件【是父组件在模板中使用v-on或@注册的监听子组件内触发的事件】以及生命周期。

  2. beforeCreated-> created: 此时beforeCreate钩子函数执行,在其执行时,data,methods上的数据方法未被初始化。

  3. created:完成实例创建创建以后调用的钩子函数,此时可以访问到data,methods上的属性方法。

  4. created-> beforeMount:判断是否有el属性,如果不存在就停止编译,或者直到调用vm.$mount(el)才会继续编译;接着开始编译模板【template】,把data对象中的数据和vue生命的模板编译成浏览器可读的HTML

  5. beforeMount:vm.el已经完成了DOM的初始化,但未挂载上

  6. beforeMount -> mounted: 此阶段vm.el完成挂载,vm.$el生成的DOM替换了el选项所对应的DOM

  7. mounted:vm.el已完成DOM的挂载与渲染,此刻打印vm.$el,发现之前的挂载点及内容已被替换成新的DOM

  8. beforeUpdate:监听数据变化,变化之前执行,此时视图未更新

  9. updated:完成视图层的更新

  10. beforeDestroy:实例被销毁前调用,此时实例属性与方法仍可访问

  11. destroyed:实例销毁后执行的钩子

数据请求在created和mouted的区别

created是在组件实例一旦创建完成的时候立刻调用,这时候页面dom节点并未生成;mounted是在页面dom节点渲染完毕之后就立刻执行的。触发时机上created是比mounted要更早的,两者的相同点:都能拿到实例对象的属性和方法。 讨论这个问题本质就是触发的时机,放在mounted中的请求有可能导致页面闪动(因为此时页面dom结构已经生成),但如果在页面加载前完成请求,则不会出现此情况。建议对页面内容的改动放在created生命周期当中

!!!actived钩子函数

keep-alive 缓存的组件激活时【mounted的话,缓存的就不会执行】、首次进入的时候应该是mounted先执行~,因为它是挂载操作呀,后面才有激活的动作才对

为什么组件中data属性是一个函数?

vue3js.cn/interview/v… 【有js示例原理、vue源码分析】vue组件当作一个对象,data是其原型上的一个属性或者方法,这样实例化以后才能都继承到

www.cnblogs.com/yuerdong/p/… 【以前的链接】

一个组件被创建好之后,就可能被用在各个地方,而组件不管被复用了多少次,组件中的data数据都应该是相互隔离,互不影响的,基于这一理念,组件每复用一次,data数据就应该被复制一次,之后,当某一处复用的地方组件内data数据被改变时,其他复用地方组件的data数据不受影响。函数返回的是一个新实例,不同的引用

!!!vue中key的原理

vue3js.cn/interview/v…

compute和methods的区别(包括watch)

  1. computed是属性调用,而methods是函数调用
  2. computed带有缓存功能,而methods不是

1.watch擅长处理的场景:一个数据影响多个数据

2.computed擅长处理的场景:一个数据受多个数据影响

vue常见有哪些缩写,如 v-slot:slotName === #slotName

VUE系列之原理源码相关

!!!vue2双向绑定原理

juejin.cn/post/684490…

www.cnblogs.com/wangjiachen… 【以前的链接】

www.cnblogs.com/fundebug/p/… 【以前的链接】

vue3js.cn/interview/v… 【有js实例的代码】

  1. 使数据变得可观测observer【监听器】

可以使用Object.defineProperty方法完成数据劫持

Vue通过设定对象属性的 setter/getter 方法来监听数据的变化,通过getter进行依赖收集,而每个setter方法就是一个观察者,在数据变更的时候通知订阅者更新视图。--发布订阅模式【数据变化为发送者,依赖对象为 订阅者】

  1. 收集依赖【订阅器类】

定义一个依赖收集类Dep,容纳存储所有的订阅者。定义方法是添加订阅者,通知订阅者更新等

  1. 实现订阅者类watcher

所有订阅者Watcher需要在初始化的时候需要将自己添加进订阅器Dep中,所以需要触发getter的操作。

缺点是不能监听新对象的新增属性和删除属性,更新数组内容【不能监听通过下标改变数组对应数据】,数据未被劫持到。

疑问:

虚拟dom

用JS语言表示DOM结构

虚拟DOM是比直接操作DOM元素要慢的,最终还是落实到操作真实DOM

为了平衡编程效率和性能,当页面变得复杂,操作真实dom就很不方便,那么牺牲一点虚拟dom带来的性能下降换取极大的编程效率,这是值得的 ---摘自b站评论

  1. 为什么需要虚拟dom

(1)框架设计:因为不管是vue还是react,都是由数据去驱动UI变化的,渲染视图会调用render函数,这种渲染不仅发生在组件创建时,而且还会发生在依赖的数据更新的时候。如果在渲染时,直接使用真实DOM,由于真实DOM的创建、更新、插入等操作会带来大量的性能消耗,从而会极大的降低渲染效率。

(2)跨平台:前端框架不仅仅只适用在浏览器上,还有小程序,桌面端,所以不能绑定真实DOM直接进行绑定,这样用虚拟DOM可以让多端都认识。

(3) 虚拟dom是一次修改,而直接dom要修改多次[ vue3js.cn/interview/v… ]

  1. diff算法==》 快速得出哪些dom改变了

juejin.cn/post/688190…

比较只会在同层级进行, 不会跨层级比较

比较的过程中,循环从两边向中间收拢

VUE系列之生态技术栈相关

单页应用【SPA】

参考文章:www.cnblogs.com/chen-cheng/… 【单页应用,多页应用模式跳转请求资源示意图】

  1. 什么叫单页应用

vue3js.cn/interview/v…

所有必要的代码(HTMLJavaScriptCSS)都通过单个页面的加载,或者根据需要(通常是为响应用户操作)动态装载适当的资源并添加到页面页面在任何时间点都不会重新加载

举例子:就是一个杯子,早上装的牛奶,中午装的是开水,晚上装的是茶,我们发现,变的始终是杯子里的内容,而杯子始终是那个杯子结构如下图:

  1. 多页应用与单页应用的区别

多页应用MPA(MultiPage-page application),翻译过来就是多页应用在MPA中,每个页面都是一个主页面,都是独立的当我们在访问另一个页面的时候,都需要重新加载htmlcssjs文件,公共文件则根据需求按需加载如下图:

(1) 区别总结:

单页面应用(SPA)多页面应用(MPA)
组成一个主页面和多个页面片段多个主页面
刷新方式局部刷新整页刷新
url模式哈希模式历史模式
SEO搜索引擎优化难实现,可使用SSR方式改善容易实现
数据传递容易通过url、cookie、localStorage等传递
页面切换速度快,用户体验良好切换加载资源,速度慢,用户体验差
维护成本相对容易相对复杂

(2)单页应用【SPA】优缺点:

优点:

  • 具有桌面应用的即时性、网站的可移植性和可访问性
  • 用户体验好、快,内容的改变不需要重新加载整个页面
  • 良好的前后端分离,分工更明确

缺点:

  • 不利于搜索引擎的抓取

  • 首次渲染速度相对较慢

(3)单页应用,多页应用模式跳转请求资源示意图:

www.cnblogs.com/chen-cheng/…

  1. SPA首屏加载慢的问题怎么解决

FCP:首屏时间(First Contentful Paint),指的是浏览器从响应用户输入网址地址,到首屏内容渲染完成的时间,此时整个网页不一定要全部渲染完成,但需要展示当前视窗需要的内容

3.1 如何计算首屏时间

通过DOMContentLoad或者performance来计算出首屏时间

vue3js.cn/interview/v…

3.2 如何优化

原因分析:

在页面渲染的过程,导致加载速度慢的因素可能如下:

  • 网络延时问题

  • 资源文件体积是否过大

  • 资源是否重复发送请求去加载了

  • 加载脚本的时候,渲染内容堵塞了

解决方法:

vue3js.cn/interview/v…

  1. 减少首屏加载的包体积【vue异步组件实现路由懒加载、合理代码拆分、压缩代码、treeshaking】

  2. 静态资源开启本地缓存 【设置Cache-ControlLast-ModifiedEtag等响应头】、离线缓存

  3. UI框架按需加载【浏览量高的首页最好不用UI框架】

  4. 图片资源的压缩,代码压缩等

  5. SSR渲染、减少首页的预加载、script标签使用defer属性延迟避免阻塞?

  6. 单页应用****实现核心:前端路由

前端路由的核心:改变视图的同时不会向后端发出请求, vue-router就是将组件映射到路由, 然后渲染出来的。并实现了三种模式:Hash模式、History模式以及Abstract模式。

可以见下一系列:VUE路由模式

VUE路由模式

mp.weixin.qq.com/s/aR2b55xAt…

路由模式Hash与History的区别

juejin.cn/post/711059… 【分析得比较透彻】

(1)hash模式:

在浏览器中符号“#”,#以及#后面的字符称之为 hash, 用 window.location.hash 读取。特点:hash 虽然在 URL 中,但不被包括在 HTTP 请求中;用来指导浏览器动作,对服务端安全无用,hash 不会重加载页面。路由的哈希模式其实是利用了window.onhashchange事件,也就是说你的url中的 哈希值 (#后面的值)如果有变化,就会自动调用hashchange的监听事件,在hashchange的监听事件内可以得到改变后的url,这样能够找到对应页面进行加载

(2)history模式:

history 采用 HTML5 的新特性;且提供了两个新方法: pushState(), replaceState()可以对浏览器历史记录栈进行修改,以 及 popState 事件的监听到状态变更pushState方法、replaceState方法,只能导致history对象发生变化,从而改变当前地址栏的 URL 但浏览器不会向后端发送请求,也不会触发popstate事件的执行。

区别总结:

juejin.cn/post/686787… 【总结得详细、也还原了两种模式的代码实现、解释了为什么刷新得时候,history模式需要后台配合】

juejin.cn/post/699384… 【区别这块分析的更多】

  1. 外观上:hash模式携带#,不美观,并且由长度限制
  2. 原理实现上:

hash模式是基于window.hashChange事件,监听url上hash的变化【window.history能监听到】,切换不同的路由组件页面实现无刷新跳转,

history模式是基于HTML5的history Api, putState、replaceState的方法去改变浏览器历史记录栈,改变不同的路由组件实现无刷新跳转,

===》 hash 只能修改 # 后面的部分,所以只能跳转到与当前 url 同文档的url , history才是彻底释放了前端路由。

===》而history模式而言,新的 url 可以是与当前 url 同源的任意 url ,也可以是与当前 url 一样的地址。

  1. 兼容性:哈希模式兼容性好一些,没有h5的属性。

  2. SEO优化:hash 可以改变 url ,但是不会触发页面重新加载(hash的改变是记录在 window.history 中),即不会刷新页面。也就是说,所有页面的跳转都是在客户端进行操作。因此,这并不算是一次 http 请求,所以这种模式不利于 SEO 优化。????那history呢?????

  3. history模式存在问题:用户在页面手动刷新时,或者采用history.go()等api的时候,如果ngix需要配置当前的url规则,否则会出现404页面。【浏览器直接访问嵌套路由时,会报 404 问题。】

为什么history需要后端配合:

pushState是将当前地址存到浏览器历史记录目录中,当用户前进,后退或者选择跳转到历史某个记录的时候,会触发popstate事件,我们可以监听该事件,手动更新组件。但是这样用户刷新和操作地址栏输入地址,就类似新打开一个网页一样,会向服务器发起请求,如果此时地址和服务器配置的地址不一致就报404错误。所以对于history模式最好后端配合,当发现找不到的时候,nginx配置一下返回首页比较好,也不是说一直返回index,这只是其中一种可以有的解决方式。也设置需要单独跳转的路径,或者覆盖全路径。

?????

自己理解:

acsp.sf-express.com/acsp/sign/home【acsp.sf-express.com/acsp/sign】

===》 acsp.sf-express.com/acsp/sign/B

由首页跳转到b页面的时候,如果页面直接刷新,后端没有配置,获取不到

对应资源文件

代码实现路由模式原理

原理:

  1. 监听地址栏中hash变化驱动界面变化
  2. pushsate记录浏览器的历史,驱动界面发送变化

实现Hash路由模式

核心通过监听url中的hash来进行路由跳转

mp.weixin.qq.com/s/aR2b55xAt… [有具体的代码]

实现Histoty路由模式

history 模式核心借用 HTML5 history api

mp.weixin.qq.com/s/aR2b55xAt… [有具体的代码]

  • 动态路由

Vue2于Vue3区别

  1. vue2和vue3双向绑定 方法不同

vue2: object.definedProperty()--数据劫持

vue3: new Proxy()

借助以上方法完成双向绑定,这些方法 是可以监听属性发生改变、和获取

(1)object.definedProperty本身的缺陷:后添加的属性是劫持不到的,数据更新了但是反应不到视图上,vue2采用this.$set解决,vue3没有这个问题,也就没有这个问题

let data = {}

Proxy直接可以劫持整个对象,并返回一个新对象,我们可以只操作新的对象达到响应式目的

  1. 组合式api

vue3js.cn/interview/v…

逻辑组织方面,逻辑复用方面 是 更清晰的,更好去维护的,optionapi, 定义的数据、以及方法、监听等是散落在页面中的。

  1. 源码体积借助treeshaing可以更小

组合式的api更好进行treeshaking, vue2这些water、compute不管项目中有没有用到,都会打包,vue3是用到了才打包。

Vue3的tree Shakeing

vue3js.cn/interview/v…

Tree shaking是基于ES6模板语法(importexports),主要是借助ES6模块的静态编译思想,在编译时就能确定模块的依赖关系,以及输入和输出的变量

Tree shaking无非就是做了两件事:

  • 编译阶段利用ES6 Module判断哪些模块已经加载

  • 判断那些模块和变量未被使用或者引用,进而删除对应代码

Vue3.0性能提升主要是通过哪几方面体现的?

vuex

优质博客:blog.csdn.net/dkr38020598… ----介绍得详细

www.cnblogs.com/msi-chen/p/…

  1. vuex是什么;

  2. (它采用集中式存贮管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化)。

  3. Vuex是专门为Vue服务,用于管理页面的数据状态、提供统一数据的,相当于数据库mongoDB,MySQL等,任何组件都可以存取其中的数据。全局更新。

  4. 它规定所有的数据必须通过action—>mutaion—>state这个流程进行来改变状态的。再结合Vue的数据视图双向绑定实现页面的更新。统一页面状态管理,可以让复杂的组件交互变的简单清晰

  5. vuex的核心概念;

  6. vuex五大核心属性:state,getter,mutation,action,module

    1. state:存储数据,状态;在根实例中注册了store 后,用 this.$store.state 来访问;对应vue里面的data;存放数据方式为响应式,vue组件从store中读取数据,如数据发生变化,组件也会对应的更新。一般这个state赋值给computed。
    2. getter:可以认为是 store 的计算属性,它的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。
    3. mutation:更改 Vuex 的 store 中的状态的唯一方法是提交 mutation
    4. action:包含任意异步操作,通过提交 mutation 间接更变状态。
    5. module:将 store 分割成模块,每个模块都具有state、mutation、action、getter、甚至是嵌套子模块。 -----命名空间更有利于规划
    6. module,后访问module中的数据 用**this.$store.state.User.info ** 其中User是模块的名称。
  7. vuex中的数据传递过程

  8. 当组件进行数据修改的时候,需要调用dispatch来触发actions里面的方法。actions里面的每个方法(actions里面的每个函数都会有一个context参数,可以使用commit方法)中都会有一个commit方法,当方法执行的时候会通过commit来触发mutations里面的方法进行数据的修改。mutations里面的每个函数都会有一个state参数,这样就可以在mutations里面进行state的数据修改,当数据修改完毕后,会传导给页面。页面的数据也会发生改变。

  9. 为什么要使用vuex:

  10. 项目中不可避免的是某些变量需要在全局范围内引用,此时父子组件的传值,子父组件间的传值,兄弟组件间的传值成了我们需要解决的问题。虽然vue中提供了props(父传子)commit(子传父)兄弟间也可以用localstorage和sessionstorage。但是这种方式在项目开发中带来的问题比他解决的问题(难管理,难维护,代码复杂,安全性低)更多。vuex的诞生也是为了解决这些问题,从而大大提高我们vue项目的开发效率。所以我们需要把组件的共享状态抽取出来,以一个全局单例模式管理。在这种模式下,我们的组件树构成了一个巨大的“视图”,不管在树的哪个位置,任何组件都能获取状态或者触发行为!另外,通过定义和隔离状态管理中的各种概念并强制遵守一定的规则,我们的代码将会变得更结构化且易维护。

  11. vuex的使用

  12. state-------------------action-------------------Mutation

  13. dispatch commit

  14. this.$store.dispatch("changeCity",city)

  15. vuex 中的代码

actions :{  action中的函数有两个参数,一个是ctx,后面的就是传入参数
    changeCity(ctx,city){  
    //console.log(city)
    //ctx表示的是上下文,可以拿到commit方法
       ctx.commit("changeCity",city)
    }
},
mutations:{ //mutations 中也有两个参数,一个是 state,后面的就是传入参数
      changeCity(state,city){
           state.city=city
      }
}
  1. 相关映射:
  2. ...mapState() 中的mapState通过扩展运算符将store.state.orderList 映射this.orderList 这个this 很重要,这个映射直接映射到当前Vue的this对象上。

所以通过this都能将这些对象点出来

...mapState(['orderList','login']), ====> 可以传入数组
...mapState({orderList:"orderList",login:(state)=>state.login), ====> 也可以传入对象: (这种对象 且对象是个函数的时候还可以组合本组件的数据)
                        
                        ...mapState({orderList:"orderList",login:(state)=>this.str+'状态是:'+state.login)