vue2 vue-cli vue-router vuex

Vue2

插值表达式

  • 利用表达式进行插值渲染,将数据渲染到页面中。

  • 语法:{{ 表达式 }}

  • PS:

    • 使用的数据要存在
    • 支持的是表达式,不是语句 iffor
    • 不能在标签属性中使用{{ }}

v-show和v-if

  • v-show底层原理:切换cssdisplay: none来控制显示隐藏
    • 场景:频繁切换显示隐藏的场景
  • v-if底层原理:根据判断条件控制元素的创建和移除(条件渲染)
    • 场景:要么显示,要么隐藏,不频繁切换的场景

v-on

  • 作用:注册事件 = 添加监听 + 提供处理逻辑
  • 语法①:v-on:事件名="内联语句"
    • 简写:@事件名
  • 语法②:v-on:事件名="methods中的函数名"
    • methods函数内的this指向Vue实例

v-bind

  • 作用:动态设置html的标签属性,如src、url、title...
  • 语法:v-bind:属性名="表达式"
  • 可以简写,如v-bind:src可以简写为:src

v-for

  • 作用:基于数据循环,多次渲染整个元素(数组、对象、数字…

  • 语法:v-for="(item,index) in 数组"

    • item每一项,index下标
    • index可以省略,v-for="item in 数组"
  • key作用:给元素添加唯一标识,便于Vue进行列表项的正确排序服用

    • v-for的默认行为会尝试原地修改元素(就地复用)
    • key的值只能是字符串或数字类型
    • <li v-for="(item,index) in xxx" :key="唯一值">

v-model

  • 作用:给表单元素使用,双向数据绑定,可以快速获取或设置表单元素内容

    • 数据变化,视图自动更新
    • 试图变化,数据自动更新
  • 语法:v-model='变量'

  • v-model应用于其他表单元素,它会根据控件类型自动选取正确的方法来更新元素

    • radio前置理解:
      • name:给单选框加上name属性,就可以分组(同一组互相会互斥
      • value:给单选框加上value属性,用于提交给后台的数据
    • select前置理解:
      • option需要设置value值,提交给后台
      • selectvalue值,关联了选中的optionvalue
  • 原理:本质上是个语法糖

    • 例如应用到输入框上,就是value属性和input事件的合写。

    • 数据变,视图跟着变 :value

    • 视图变,数据跟着变 @input

    • $event用于在模板中,获取事件的形参

记事本小案例

  • 1、列表渲染
    • v-for key的设置 {{}}插值表达式
  • 2、删除功能
    • v-on调用传参 filter过滤,覆盖修改原数组
  • 3、添加功能
    • v-model绑定 unshift修改原数组添加
  • 4、底部统计和清空
    • 数组.length累计长度
    • 覆盖数组清空列表
    • v-show控制隐藏
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="./css/index.css" />
<title>记事本</title>
</head>
<body><!-- 主体区域 -->
<section id="app"><!-- 输入框 --><header class="header"><h1>记事本</h1><!-- @keyup.enter 监听键盘回车事件 --><input @keyup.enter="add" v-model="todoName" placeholder="请输入任务" class="new-todo" /><button @click="add" class="add">添加任务</button></header><!-- 列表区域 --><section class="main"><ul class="todo-list"><li class="todo" v-for="(item,index) in list" :key="item.id"><div class="view"><span class="index">{{ index + 1 }}.</span> <label>{{ item.name }}</label><button @click="del(item.id)" class="destroy"></button></div></li></ul></section><!-- 统计和清空  如果没有任务了 底部隐藏掉 v-show --><footer class="footer" v-show="list.length > 0"><!-- 统计 --><span class="todo-count">合 计:<strong> {{ list.length }} </strong></span><!-- 清空 --><button @click="clear" class="clear-completed">清空任务</button></footer>
</section><!-- 底部 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>//添加功能//1.通过v-model绑定输入框,实时获取表单元素的内容//2.点击按钮,进行新增,往数组最前面加 unshiftconst app = new Vue({el: '#app',data: {todoName: '',list:[{id: 1, name: '跑步800m'},{id: 2, name: '打球1h'},{id: 3, name: '看半本书'},]},methods: {del(id){this.list = this.list.filter(item => item.id !== id)},add(){if(this.todoName.trim() === ''){alert('请输入任务')return}this.list.unshift({id: +new Date(),name: this.todoName})this.todoName = ''},clear(){this.list = []}},})</script>
</body>
</html>

指令的修饰符

  • @keyup.enter:监听键盘回车事件
    • 相当于帮我们加了e.key === enter这个判断
  • v-model修饰符
    • .trim:去首尾空格
    • .number:尝试转成数字(能转的就转
  • @事件名.stop:阻止冒泡
  • @事件名.prevent:阻止默认行为

v-bind对样式控制的增强

  • 操作class

    • 语法::class="对象/数组"

      • 对象:键就是类名,值就是布尔值。值为true,就有这个类,否则就没有

        <div class="box" :class="{类名1: 布尔值, 类名2: 布尔值}"></div>

      • 使用场景:一个类名,来回切换(京东导航栏

      • 数组:数组中所有的类,都会添加到盒子里,本质是一个class列表

        <div class="box" :class="[类名1, 类名2]"></div>

      • 使用场景:批量添加或删除类

  • 操作style

    • 语法::style="样式对象"

      <div class="box" :style="{css属性名1: css属性值, css属性名2: css属性值}"></div>

    • 使用场景:某个具体属性的动态设置(进度条

计算属性

  • 概念:基于现有的数据,计算出来的新属性。依赖的数据变化,自动重新计算。

  • 语法:

    • 1、声明在computed配置项中,一个计算属性对应一个函数

      computed: {计算属性名 () {基于现有数据,编写求值逻辑return 结果}
      }
      
    • 2、使用起来和普通属性一样:{{ 计算属性名 }}

  • computed vs methods

    • computed作用:封装了一段对于数据的处理,求得一个结果。
      • 缓存特性(提升性能):计算属性会对计算出来的结果缓存,再次使用直接读取缓存。只有依赖项变化了,才会自动重新计算,然后再次缓存。
    • methods作用:给实例提供一个方法,调用以处理业务逻辑。
  • 计算属性默认的缩写,只能读取访问,不能修改。如果要修改,就要写计算属性的完整写法。

    • 执行get会返回求值的结果
    • 被修改赋值时会执行set,修改的值传递给set方法的形参
    computed: {计算属性名: {get(){一段代码逻辑(计算逻辑return 结果},set(修改的值){一段代码逻辑(修改逻辑}}
    }
    

watch监听器

  • 作用:监视数据变化,执行一些业务逻辑或异步操作。

  • 语法:

    • 1.简单写法:简单类型数据,直接监视

      watch:{//该方法会在数据变化时,触发执行数据属性名(newValue, OldValue){一些业务逻辑或异步操作},'对象.属性名'(newValue, OldValue){一些业务逻辑或异步操作}
      }
      
      • oldValue一般不用,可以不写
    • 2.完整写法:添加额外配置项

      • deep: true:对复杂类型深度监视
      • immediate: true:初始化立刻执行一次handler方法
      watch: {监视对象: {deep: true, //监视多个 深度监视immediate: true, //一进入页面就触发handlerhandler(newValue){一些业务逻辑或异步操作}}
      }
      

生命周期

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

    • 1.创建:响应式数据
    • 发送初始化渲染请求(越早越好
    • 2.挂载:渲染模板
    • 操作dom(至少dom要渲染出来
    • 3.更新:数据修改,更新视图(循环多次
    • 4.销毁:销毁实例
  • 生命周期函数(钩子函数):自动运行的一些函数
    在这里插入图片描述

记账清单案例

  • 基本渲染:

    • 1.created请求数据(封装渲染方法)
    • 2.拿到数据,存到data的响应式数据中
    • 3.结合数据进行渲染 v-for
    • 4.消费统计 => 计算属性
            computed: {totalPrice(){return this.list.reduce((sum, item) => sum + item.price, 0)}},async created(){// const res = await axios.get('https://applet-base-api-t.itheima.net/bill', {//   params: {//   creator: 'kk'//   }// })this.list = res.data.datathis.getList()},
    
  • 添加功能:

    • 1.收集表单数据 v-model
    • 2.给添加按钮注册点击事件,发送添加请求
    • 3.重新渲染
             async add(){if(!this.name){alert('請輸入消費名稱')return}if(typeof this.price !== 'number'){alert('请输入正确数字')return}//發送請求const res = await axios.post('https://applet-base-api-t.itheima.net/bill,', {creator: 'kk',name: this.name,price: this.price})//重新渲染this.getList()this.name = ''this.price = ''},
    
  • 删除功能:

    • 1.注册点击事件,传参数id
    • 2.根据id发送删除请求
    • 3.重新渲染
              async del(id){const res = await axios.delete(`https://applet-base-api-t.itheima.net/bill/${id}`)this.getList()}
    
  • 饼图渲染:

    • 1.初始化一个饼图echarts.init(dom) mounted钩子实现
    • 2.根据数据实时更新饼图echarts.setOption({...})
    mounted () {this.myChart = echarts.init(document.querySelector('#main'))this.myChart.setOption({// 大标题title: {text: '消费账单列表',left: 'center'},// 提示框tooltip: {trigger: 'item'},// 图例legend: {orient: 'vertical',left: 'left'},// 数据项series: [{name: '消费账单',type: 'pie',radius: '50%', // 半径data: [// { value: 1048, name: '球鞋' },// { value: 735, name: '防晒霜' }],emphasis: {itemStyle: {shadowBlur: 10,shadowOffsetX: 0,shadowColor: 'rgba(0, 0, 0, 0.5)'}}}]})},async getList(){const res = await axios.get('https://applet-base-api-t.itheima.net/bill', {params: {creator: 'kk'}})this.list = res.data.data//更新图表this.myChart.setOption({// 数据项series: [{data: this.list.map(item => ({value: item.price,name: item.name}))}]})},
    

工程化开发&脚手架Vue CLI

  • Vue CLI是一个全局命令工具,可以快速搭建一个开发Vue的标准化基础架子(集成了webpack配置

  • 使用步骤:

    • 1.全局安装(一次):npm i @vue/cli -gyarn global add @vue/cli

    • 2.查看Vue版本:vue --version

    • 3.创建项目架子:vue create 项目名(不能有中文)

    • 4.启动项目:npm run serveyarn serve

      • 这个不一定都是serve,要去看package.json
        在这里插入图片描述
  • 项目目录介绍
    在这里插入图片描述

组件化开发&根组件

  • 组件化:一个页面被拆分成一个个组件,每个组件都有自己独立的结构、样式、行为
  • 组件分类:普通组件、根组件
  • 根组件:整个应用最上层的组件,包裹所有普通小组件
    • 三部分组成:
      • template:结构(有且只有一个根元素
      • script:js逻辑
      • style:样式(可支持less,需要装包
        • 1.给style加上lang="less"
        • 2.安装依赖包:npm i less less-loader --saveyarn add less less-loader -D

普通组件的注册

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

    • ①创建.vue文件(三个部分

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

      import HmHeader from './components/HmHeader.vue';
      export default {components: {//组件名:组件对象HmHeader: HmHeader}
      }
      
  • 使用:当成html标签使用<组件名></组件名>

  • PS:组件名规范:大驼峰命名法

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

    • ①创建.vue文件

    • main.js中进行全局注册

      //导入代码往顶部编写
      import HmButton from './components/HmButton.vue'
      Vue.config.productionTip = false//进行全局注册
      //Vue.component('组件名', 组件对象)
      Vue.component('HmButton', HmButton)
      

scoped样式冲突

  • 默认情况:写在组件中的样式会全局生效,因此很容易造成多个组件之间的样式冲突问题。
    • 全局样式:默认组件中的样式作用到全局
    • 局部样式:可以给组件加上scoped属性,可以让样式只作用于当前组件
  • scoped原理:
  • 1.给当前组件模板的所有元素,都会被添加上一个自定义属性
    • data-v-hash值 区分不同的组件
  • 2.css选择器后面,会自动处理,添加上属性选择器[data-v-hash值]

data是一个函数

  • 一个组件的data选项必须是个函数,保持每个组件实例,维护独立的一份数据对象。
  • 每次创建新的组件实例,都会新执行一次data函数,得到一个新对象。

组件通信

  • 组件通信:组件与组件之间的数据传递

    • 组件的数据是独立的,无法直接访问其他组件的数据
  • 组件关系:

    • 父子关系
    • 非父子关系
  • 组件通信方案
    在这里插入图片描述

  • 父子通信:

    • 1.父组件通过props将数据传递给子组件
      • 父组件给子组件标签,添加属性的方式,传值xxx
      • 子组件通过props进行接收xxx
      • 渲染使用{{ xxx }}
    • 2.子组件利用$emit通知父组件修改更新
      • $emit触发事件,给父组件发送消息通知
      • 父组件监听事件
      • 提供处理函数,形参中获取参数
        在这里插入图片描述
  • 非父子通信 -event bus事件总线

    • 作用:非父子之间进行简易消息传递。复杂场景还是用Vuex

    • EventBus
      在这里插入图片描述

    • provide&inject:跨层级共享数据
      在这里插入图片描述

props详解

  • 定义:组件上注册的一些自定义属性

  • 作用:向子组件传递数据

    • 可以传递任意数量的prop
    • 可以传递任意类型的prop
  • props校验为组件的prop指定验证要求,不符合的控制台会有错误提示

  • 语法:

    • 类型校验:props: {校验的属性名: 类型},
    • 非空校验
    • 默认值
    • 自定义校验
    //完整写法
    props:{校验的属性名: {type: 类型,required: true, //是否必填default: 默认值,validator(value){//自定义校验逻辑return 是否通过校验}}
    }
    
  • prop&data单向数据流,共同点:都可以给组件提供数据

    • data的数据是自己的,可以随便改
    • prop的数据是外部的,不能直接改,要遵循单向数据流
      • 单向数据流:父组件的prop更新,会单向向下流动,影响到子组件,这个数据的流动是单向的
    • 谁的数据谁负责

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

  • 表单类组件封装

    • 1.父传子:数据应该是从父组件props传递过来的,v-model拆解绑定数据

    • 2.子传父:监听输入,子传父传值给父组件修改

    • 直白地说,子组件没有办法直接使用v-model,因为数据是父组件的。如果要实现这样的功能,就要把语法糖拆开,相当于用了v-model的原理
      在这里插入图片描述

  • 父组件v-model简化代码,实现父组件与子组件数据双向绑定

    • 1.子组件中:props通过value接收,事件触发input
    • 2.父组件中:v-model给组件直接绑定数据 (:value + @input)
      • 子组件已经配置好,才能使用v-model
        在这里插入图片描述

.sync修饰符

  • 作用:可以实现子组件与父组件的双向绑定,简化代码

  • 特点:prop属性名可以自定义,非固定为value

  • 场景:封装弹框类的基础组件,visible属性true显示false隐藏

  • 本质:就是:属性名@update:属性名合写
    在这里插入图片描述

ref 和 $refs

  • 作用:利用ref$refs可以用于获取dom元素或组件实例
  • 特点:查找范围是当前组件,更精确稳定
    • querySelector查找范围是整个页面
  • 用法:
    • 1.获取dom
      • 目标标签 - 添加ref="xxx"属性
      • 通过this.$refs.xxx获取目标标签
    • 2.获取组件
      • 目标组件 - 添加ref="xxx"属性
      • 通过this.$refs.xxx.组件方法()获取目标组件,就可以调用组件对象里面的方法

Vue异步更新、$nextTick

  • 需求:编辑标题,编辑框自动聚焦
    • 1.点击编辑,显示编辑框
    • 2.让编辑框立刻获取焦点
  • 问题:“显示之后”立刻获取焦点是不能成功的!因为Vue是异步更新DOM(提升性能)
  • $nextTick:等DOM更新后,才会触发执行此方法里的函数体
  • 语法:this.$nextTick(函数体)

自定义指令

  • 自己定义的指令,可以封装一些dom操作,扩展额外功能

  • 语法:

    • 全局注册
    • 局部注册
    • inserted会在指令所在的元素,被插入到页面时触发
      在这里插入图片描述
  • 指令的值

    • 语法:在绑定指令时,可以通过等号的形式为指令绑定具体的参数值
    • 通过binding.value可以拿到指令值,指令值修改会触发update函数
    • update钩子可以监听指令值的变化,进行dom更新操作

封装v-loading指令

  • 场景:在开发过程中,发送请求需要时间,在请求的数据未回来的时候,页面会处于空白状态,这样用户体验不好

  • 需求:封装v-loading指令,实现加载中的效果

  • 分析:

    • 1.本质loading效果就是一个蒙层,盖在了盒子上
    • 2.数据请求中,添加蒙层
    • 3.数据请求完毕,移除蒙层
  • 实现:

    • 1.准备一个loading类,通过伪元素定位,设置宽高,实现蒙层
    • 2.添加移除蒙层,本质只需要添加移除类
    • 3.结合自定义指令的语法进行封装复用
    directives: {loading: {inserted(el, binding){binding.value ? el.classList.add('loading') : el.classList.remove('loading')},update(el, binding){binding.value ? el.classList.add('loading') : el.classList.remove('loading')}}}
    

插槽

  • 作用:让组件内部的一些结构支持自定义

  • 插槽分类:

    • 默认插槽:定制一处结构
    • 具名插槽:定制多处结构
  • 作用域插槽是插槽的一个传参语法

  • 默认插槽:一个定制位置

    • 基本语法:

      • 1.在要定制的结构部分,改用<slot></slot>占位

      • 2.使用组件时,<MyDialog></MyDialog>标签内部,传入结构替换slot

    • 后备内容(默认值):封装组件时,可以在<slot>标签内放置内容,作为默认显示内容

  • 具名插槽:一个组件内有多处结构需要外部传入标签

    • 语法:
      • 1.多个slot使用name属性来区分名字
      • 2.template包裹起来,v-slot: 插槽名来分发标签,v-slot: 插槽名可以简化成#插槽名
    • 一旦插槽取名字,就表明是具名插槽,定向分发
  • 作用域插槽:定义slot的同时,是可以传值的。给插槽上可以绑定数据,将来使用组件时可以用。

    • 场景:封装表格组件

      • 1.父传子,动态渲染表格内容
      • 2.利用默认插槽,定制操作列
      • 3.删除或查看都需要使用当前项的id,属于组件内部的数据,通过作用域插槽传值绑定,进而使用
    • 使用步骤:

      • 1.给slot标签,以添加属性的方式传值
      • 2.所有添加的属性都会被收集到一个对象中
      • 3.在template中,通过#插槽名="obj"接收,默认插槽名是default

单页面应用SPA

  • 页面按需更新,这样开发效率高,性能高,用户体验好
  • 按需更新,首先要明确访问路径和组件的对应关系
    在这里插入图片描述

路由

  • Vue中路由:路径和路由的映射关系

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

    • 使用(5 + 2):
    • 1.下载:vue2下载3.x,vue3下载4.x
      • npm i install vue-router@3.6.5
    • 2.引入:import VueRouter from 'vue-router'
    • 3.安装注册:Vue.use(VueRouter)
    • 4.创建路由对象:const router = new VueRouter()
    • 5.注入,将路由对象注入到new Vue实例中,建立关联
    • 2个核心步骤:
    • ①创建需要的组件(views目录),配置路由规则
    • ②配置导航,配置路由出口(路径匹配的组件显示的位置)
    • PS:route 一条路由规则 { path: 路径, component: 组件 }
    • <router-view></router-view>:路由出口 → 匹配的组件所展示的位置
  • 组件分类更易维护

    • src/views存放页面组件-页面展示-配合路由用
    • src/components存放复用组件-展示数据-常用于复用
  • 快速引入组件:基于@代指src目录,从src目录出发找组件

  • Vue路由 - 重定向

    • 问题:网页打开,url默认是/路径,未匹配到组件显示空白
    • 说明:重定向 —-> 匹配path后,强制跳转path路径
    • 语法:path: 匹配路径, redirect: 重定向到的路径
  • Vue路由 - 404

    • 作用:路径找不到匹配时,给出个提示页面
    • 位置:配在路由最后
    • 语法:path: '*'(任意路径), component: NotFound
  • Vue路由 - 模式设置

    • hash路由(默认):会有#
    • history路由(常用):一旦采用history,地址栏就没有#,需要后台配置访问规则
    • 在路由对象mode里面设置

声明式导航

  • 声明式导航router-link,取代a标签

    • ①能跳转,配置to属性必须指定路径,to不需#

    • ②能高亮,默认会自动添加两个高亮类名

      • router-link-active:模糊匹配,用得多
      • 例如:/find,则/find/xxx、/find/one也能匹配
      • router-link-exact-active:精确匹配
      • 例如:/find,则只有/find能匹配
    • 定制两个高亮类名

      const router = new Router({routes: [...],linkActiveClass: "类名1",linkExactActiveClass: "类名2"
      })
      
  • 声明式导航 - 跳转传参

    • 1.查询参数传参(比较适合传多个参数

      • 语法格式:to="/path?参数名=值"
      • 对应页面组件接收传递过来的值:$route.query.参数名
    • 2.控制路由传参(传单个参数方便

      • ①配置动态路由

        const router = new Router({routes: [...,{path: '/search/:参数名',component: Search}],	
        })
        
      • ②配置导航链接:to="/path/参数值"

      • ③对应页面接收传递过来的值:$route.params.参数名

      • 比如:在配置路由path: '/serach/:words',没有传参数会匹配不到组件,显示空白。如果不传参数也希望匹配,就可以加个可选符?,即path: '/serach/:words?'

编程式导航

  • 编程式导航 - 基本跳转

    • path路径跳转(简易方便)

      this.$router.push('路由路径')
      或
      this.$router.push({path: '路由路径'
      })
      
    • name命名路由跳转(适合path路径长的场景):需要给路由取名字

      {name: '路由名', path: '/xxx', component: xxx}
      this.$router.push{name: '路由名'
      }
      
  • 编程式导航 - 路由传参

    • 1.path路径跳转传参

      • query传参的语法格式:

        this.$router.push('/path?参数名1=值1&参数名2=值2')
        this.$router.push({path: '路径',query: {参数名1: '参数值1',参数名2: '参数值2'}
        })
        
      • 对应页面组件接收传递过来的值:$route.query.参数名

      • 动态路由传参(需要配动态路由)的语法格式:

      • PS:push里面是``,不是引号

        this.$router.push(`/path/参数值`)
        this.$router.push({path: '/路径/参数值',
        })
        
      • 对应页面接收传递过来的值:$route.params.参数名

    • 2.name命名路由跳转传参

      • query传参的语法格式:

        this.$router.push({name: '路径名字',query: {参数名1: '参数值1',参数名2: '参数值2'}
        })
        
      • 对应页面组件接收传递过来的值:$route.query.参数名

      • 动态路由传参(需要配动态路由)的语法格式:

        this.$router.push({name: '路由名',params: {参数名:'参数值',}
        })
        
      • 对应页面接收传递过来的值:$route.params.参数名

组件缓存 keep-alive

  • 内置组件,当它包裹动态组件时,会缓存不活动的组件,而不是销毁它们。
  • 它自身不会渲染成一个DOM元素,也不会出现在父组件链中。
  • 优点:在组件切换过程中,把切换出去的组件保存在内存中,防止重复渲染DOM,减少加载时间及性能消耗,提高用户体验。
  • 三个属性:
    • :include="组件名数组":只有匹配的组件会被缓存
      • 如果没有配置name,才会去找文件名作为组件名
      • 被缓存的组件多了两个生命周期钩子
        • activated:激活时,组件被看到触发
        • deactivated:失活时,离开页面组件看不见触发
      • 组件缓存后就不会执行组件的created、mounted、destroyed钩子了
    • exclude:任何匹配的组件都不会被缓存
    • max:最多可以缓存多少组件实例,用==LRU算法==(最久没有被访问的)来替换组件

Vuex

  • vuex是一个状态管理工具,状态就是数据,就是一个插件,帮我们管理vue通用的数据(多组件共享的数据

  • 场景:

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

    • 共同维护一份数据,数据集中化管理
    • 响应式变化
    • 操作简单,vuex提供了一些辅助函数
  • state状态

    • 1.State提供唯一的公共数据源,所有共享的数据都要统一放到Store中的State中存储,在state对象中可以添加我们要共享的数据
    • 2.使用数据:
      • 通过store直接访问(一层一层往下找
        • 模板中:{{ $store.state.xxx }}
        • 组件逻辑中:this.$store.state.xxx
        • js模块中:store.state.xxx
      • 通过辅助函数:mapState能把store中的数据自动映射到组件的计算属性中
        • 导入mapStateimport { mapState } from 'vuex'
        • 数组方式引入state...mapState(['属性'])
        • 展开运算符...映射
  • vuex同样遵循单向数据流,组件中不能直接修改仓库的数据,可以通过mutations来修改数据

    • 通过strict: true可以开启严格模式来检测错误代码
  • mutations:必须是同步的,便于监测数据变化,记录调试

    • 使用:

      • 1.定义mutations对象,对象中存放修改state的方法
      • 2.组件中提交调用mutationsthis.$store.commit('mutations中的方法名')
    • 传参语法

      • 1.提供mutations函数(带参数 - 提交载荷payload

        mutations: {...xxx (state, 参数) {方法逻辑}
        }
        
      • PS:mutations参数有且只能有一个,如果需要多个参数,可以包装成一个对象或数组

      • 2.页面中提交调用mutationsthis.$store.commit('xxx', 参数)

  • mapMutations:把位于mutations中的方法提取出来,映射到组件methods中。相当于把仓库里的数据和方法拿到了当前组件内,就可以直接使用了。

  • actions:处理异步操作

    • 需求:一秒之后,修改statecount

    • 语法:

      • 1.提供actions方法

      • 不能直接操作state,操作state还是需要commit mutation

        actions: {setAsynCount (context, num) {//context 上下文 此处未分模块,可以当成store仓库//setTimeout模拟异步 以后大部分场景是发请求setTimeout (() => {context.commit('方法名', num)}, 1000)}
        }
        
      • 2.页面中dispatch调用:this.$store.dispatch('setAsynCount', 参数)

      • 也有且只能有一个参数

  • mapActions:把位于actions中的方法提取出来,映射到组件methods中。相当于把仓库里的数据和方法拿到了当前组件内,就可以直接使用了。

  • getters:类似于计算属性,需要从state派生出一些状态,这些状态是依赖state的,此时会用到getters

    • 1.定义getters

      getters: {//第一个参数是state//getters函数必须要有返回值,返回的就是getters的值xxx (state) {return xxxx}
      }
      
    • 2.访问getters

      • 通过store{{ $store.getters.xxx }}

      • 通过mapGetters映射

        computed: {...mapGetters(['xxx'])
        }
        {{ xxx }}
        
  • PS:mapMutationsmapActions都是映射方法,而mapStatemapGetters都是映射属性

模块 module

  • 模块 module:由于vuex使用单一状态树,应用的所有状态会集中到一个比较大的对象,当应用变复杂时,store对象就会可能变得很臃肿。
  • 使用模块中的数据:
    • 1.直接通过模块名访问$store.state.模块名.xxx
    • 2.通过mapState映射
      • 默认根级别的映射mapState(['xxx'])
      • 子模块的映射mapState('模块名', ['xxx'])
        • 需要开启命名空间,在子模块的js文件的export加上namespaced: true
  • 分模块后,getters的函数里state参数指的是子模块的state
  • 默认模块中的mutationactions会被挂载到全局,需要开启命名空间,才会挂载到子模块
    • 调用子模块中的mutation
      • 直接store调用:$store.commit('模块名/xxx', 额外参数)
      • 通过mapMutations映射:
        • 根级别:mapMutations(['xxx'])
        • 子模块:mapMutations('模块名', ['xxx'])
    • context上下文,默认提交的是自己模块mutationactions
  • PS:actions跟这个没区别,只不过是直接调用是:$store.dispatch('模块名/xxx', 额外参数)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/521068.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【数据结构】二、线性表:6.顺序表和链表的对比不同(从数据结构三要素讨论:逻辑结构、物理结构(存储结构)、数据运算(基本操作))

文章目录 6.对比&#xff1a;顺序表&链表6.1逻辑结构6.2物理结构&#xff08;存储结构&#xff09;6.2.1顺序表6.2.2链表 6.3数据运算&#xff08;基本操作&#xff09;6.3.1初始化6.3.2销毁表6.3.3插入、删除6.3.4查找 6.对比&#xff1a;顺序表&链表 6.1逻辑结构 顺…

1.2_2 OSI参考模型

文章目录 1.2_2 OSI参考模型一、概述&#xff08;一&#xff09;ISO/OSI参考模型是怎么来的&#xff1f;&#xff08;二&#xff09;ISO/OSI参考模型&#xff08;三&#xff09;ISO/OSI参考模型解释通信过程 二、各层功能及协议&#xff08;一&#xff09;应用层&#xff08;第…

南京观海微电子---PCIe协议(一)

概述 PCIe协议是一种端对端的互连协议&#xff0c;提供了高速传输带宽的解决方案。与传统的并行总线标准如PCI和PCI-X相比&#xff0c;PCIe提供了更低的延迟和更高的数据传输速率。每个连接到主板上的设备都通过独立的点对点连接与之相连&#xff0c;这避免了设备之间因为共享…

关于 Runes 协议及「公开铭刻」发行机制的拓展讨论

撰文&#xff1a;MiX 编辑&#xff1a;Faust&#xff0c;极客 web3 2024 年 3 月 2 日&#xff0c;Runes 生态基础设施项目 Rune alpha 的创始人&#xff0c;在 Github 的公开议题中&#xff0c;与 Runes 协议创始人 Casey 展开了讨论&#xff0c;双方对如何拓展 Runes 协议的…

(学习日记)2024.03.07:UCOSIII第九节:时间戳

写在前面&#xff1a; 由于时间的不足与学习的碎片化&#xff0c;写博客变得有些奢侈。 但是对于记录学习&#xff08;忘了以后能快速复习&#xff09;的渴望一天天变得强烈。 既然如此 不如以天为单位&#xff0c;以时间为顺序&#xff0c;仅仅将博客当做一个知识学习的目录&a…

SSL 证书,了解一下常识

公司的网站、应用怎么才能保证在互联网上安全运行&#xff0c;不被攻击、盗取数据呢&#xff1f; 创业必经之路&#xff0c;一步一步走就对了&#xff0c;可能没赶上红利期&#xff0c;但不做就等于0。 概述 SSL 证书&#xff08;SSL Certificates&#xff09;又称数字证书&am…

网络入侵检测系统之Suricata(九)--Storage实现详解

suricata针对一些小的线程共享空间采用多种storage&#xff0c;比如Host storage&#xff0c;这个数据区就是存储阈值option实现时一些共享数据&#xff1a; threshold option-> type threshold , track by_dst, count 5, seconds 60 代表1分钟内命中5次后才会产生一个告警…

【“双碳”目标】Acrel-2000Z分布式光伏发电监测系统解决方案

1 概述 “十四五”期间&#xff0c;随着“双碳”目标提出及逐步落实&#xff0c;本就呈现出较好发展势头的分布式光伏发展有望大幅提速。就“十四五”光伏发展规划&#xff0c;国家发改委能源研究所可再生能源发展中心副主任陶冶表示&#xff0c;“双碳”目标意味着国家产业结…

学习Java的第四天

目录 一、if选择结构 1、基本if选择结构 语法结构&#xff1a; 流程图&#xff1a; 示例&#xff1a; 2、if-else 选择结构 语法结构&#xff1a; 流程图&#xff1a; 示例&#xff1a; 3、多重if选择结构 语法结构&#xff1a; 流程图&#xff1a; 示例&#xff1a…

小型内衣裤洗衣机哪个牌子好?四款高热度内衣洗衣机力荐

相信很多用户从小就有个观念&#xff0c;内衣裤不能跟其他衣物一起混合洗&#xff0c;否则会感染细菌&#xff0c;所以不少人的内衣裤一直都是自己手洗的&#xff0c;清洗内衣裤不算麻烦&#xff0c;但日常都要换洗&#xff0c;对一个白天上班已经很累的人来说&#xff0c;真是…

【并查集】一种简单而强大高效的数据结构

目录 一、并查集原理 二、并查集实现 三、并查集应用 1. LeetCode并查集相关OJ题 2. 并查集的其他应用及总结 一、并查集原理 并查集&#xff08;Disjoint Set&#xff09;是一种用来管理元素分组和查找元素所属组别的数据结构。它主要支持两种操作&#xff1a;查找&…

Chromium内核浏览器编译记(四)Linux版本CEF编译

转载请注明出处&#xff1a;https://blog.csdn.net/kong_gu_you_lan/article/details/136508294 本文出自 容华谢后的博客 0.写在前面 本篇文章是用来记录编译Linux版本CEF的步骤和踩过的坑&#xff0c;以防止后续再用到的时候忘记&#xff0c;同时也希望能够帮助到遇到同样问…