Vue基础 (黑马程序员讲解)

Vue2.x技术精讲

目录:

1. Vue 快速上手
    vue概念/创建实例/插值表达式/响应式特性/开发者工具
2. Vue 指令
    v-html/v-show/v-if/v-else/v-on/v-bind/v-for/v-model
3. 综合案例-小黑记事本
    列表渲染/删除功能/添加功能/底部统计/清空

一、vue是什么

概念:Vue 是一个用于构建用户界面的渐进式框架

1. 构建用户界面基于数据渲染 出用户看到的页面。

Vue基础 (黑马程序员讲解)_第1张图片


2. 渐进式: 循序渐进 (学一点用一点)

Vue基础 (黑马程序员讲解)_第2张图片


Vue的两种使用方式:

  • Vue 核心包开发

    • 场景:局部模块改造

  • Vue 核心包 & Vue插件 工程化开发

    • 场景:整体开发


3. 框架:一套完整的项目解决方案

优点:大大提升开发效率 (70%)

缺点:需要理解记忆规则 -> 官网


二、创建一个vue实例

核心步骤:

1. 准备容器
2. 引包 (官网) - 开发版本 / 生产版本
3. 创建 Vue 实例 new Vue()
4. 指定配置项 -> 渲染数据(哪个容器,哪个数据)
    + el 指定容器
    + data 提供数据

引包:

Vue2 网址:v2.cn.vuejs.org

Vue基础 (黑马程序员讲解)_第3张图片



{{msg}}

{{count}}


三、插值表达式

插值表达式是一种 Vue 的模板语法

{{ msg }}

data: {
    msg: 'Hello 黑马'
}

1. 作用:利用表达式进行插值,渲染到页面中

  • 表达式:是可以被求值的代码,JS 引擎会将其计算出一个结果。

money + 100
money - 100
money * 10
money / 10
price >= 100 ? '真贵' : '还行'
obj.name
arr.name
arr[0]
fn()
obj.fn()

2. 语法: {{ 表达式 }}

{{ title }}

{{ nickname.toUpperCase }}

{{ age >= 18? '成年' : '未成年' }}

3. 注意点:

  • 使用的数据必须存在

  • 支持的是表达式,而非语句,比如:if、for...

  • 不能在标签属性中使用 {{ }} 插值

Vue基础 (黑马程序员讲解)_第4张图片


{{msg}}

{{msg.toUpperCase()}}

{{msg + 'Nice to meet you'}}

{{ age >= 18 ? '成年' : '未成年' }}


四、响应式特性

我们已经掌握了基础的模板渲染,其实除了基本的模板渲染,Vue背后还做了大量工作。

比如:数据的响应式处理

  • 响应式:数据变化,视图自动更新

Vue基础 (黑马程序员讲解)_第5张图片


{{ msg }}

Vue核心特征:响应式

数据改变,试图会自动更新

Vue基础 (黑马程序员讲解)_第6张图片


五、开发者工具安装

安装 Vue开发者工具:装插件调试 Vue 应用

(1) 通过谷歌应用商店安装 (国外网站)

(2) 极简插件:搜索 vue (选择第一个) ->下载 -> 开发者模式 -> 拖拽安装 -> 插件详情允许访问文件

极简插件_Chrome扩展插件商店_优质crx应用下载

(3) 打开 Vue 运行的页面,调试工具中 Vue 栏,即可查看修改数据,进行调试。

开发者模式

Vue基础 (黑马程序员讲解)_第7张图片


插件详情允许访问文件

Vue基础 (黑马程序员讲解)_第8张图片


六、Vue指令

Vue 会根据不同的 [ 指令 ],针对标签实现不同的 [功能]

指令:带有 v- 前缀 的特殊 标签属性




...
...

(一) 指令初始 v-html

作用:设置元素的 innerHTML

语法:v-html = "表达式"

div id="app">
    

(二) 指令 v-show 和 v-if

v-show

1. 作用:控制元素显示隐藏

2. 语法:

v-show = "表示式"  表达式值 true 显示,false 隐藏

3. 底层原理:切换 CSS 的 display: none 来控制显示隐藏

4. 场景:频繁切换显示隐藏的场景


v-if

1. 作用:控制元素显示隐藏 (条件渲染)

2. 语法:

3. 底层原理: 根据判断条件 控制元素的创建和移除

4. 场景: 要么显示,要么隐藏,不频繁切换的场景

v-if = "表达式"	表达式值 true 显示,false 隐藏

我是v-show控制的盒子
我是v-if控制的盒子

(三) 指令v-else和v-else-if

1. 作用:辅助 v-if 进行判断渲染

2. 语法:v-else v-else-if = "表达式"

3. 注意: 需要紧挨着 v-if 一起使用

Vue基础 (黑马程序员讲解)_第9张图片


<
div id="app">
    

性别:男

性别:女


成绩评定为A: 奖励电脑一台

成绩评定为B: 奖励周末郊游

成绩评定为C: 奖励零食礼包

成绩评定为D: 惩罚一周不能玩手机


(四) 指令 v-on

1. 作用: 注册事件 = 添加监听 + 提供处理逻辑

2. 语法:

方式1. v-on: 事件名 = "内联语句"		// 内联语句:可执行代码
方式2. v-on: 事件名 = "methods中的函数名"

3. 简写:@事件名

button v-on:click="count++"> 按钮 
button @click="count++"> 按钮 

(1) 第一种事件注册方式

// v-on: 可以用 @ 替换 {{ count }} // v-on: 可以用 @ 替换

(2) 第二种注册事件方式

button @click="fn">-

const app = new Vue({
        el: '#app',
        data: {
        	// 提供数据
            count: 100
        },
        methods: {
        	// 提供处理逻辑函数
        	fn() {
        		console.log('提供逻辑代码')
        	}
        }
    })

黑马程序员

4. 注意:methods 函数内的 this 执行Vue 实例


(3) Vue指令v-on调用传参

Vue基础 (黑马程序员讲解)_第10张图片


小黑自动售货机

银行卡余额: {{ money }}


(五) 指令 v-bind

1. 作用: 动态设置 html的 标签属性 -> src、url、title ...

2. 语法: v-bind:属性名= "表达式"

3. 注意:简写形式::属性名="表达式"


案例-波仔的学习之旅

核心思路分析:

  1. 数组存储图片路径 -> [图片1,图片2,图片3,...]

  2. 准备下标 index,数组 [下标] -> v-bind设置 src展示图片 -> 修改下标切换图片


(六) 指令 v-for

1. 作用:基于数据循环,多次渲染整个元素 -> 数组、对象、数字 ...

Vue基础 (黑马程序员讲解)_第11张图片


2. 遍历数组语法:

v-for = "(item,index) in 数组"

  • item 每一项,index 下标

  • 省略 index,: v-for = "item in 数组"

  • {{ item }}

案例-小黑的书架

明确需求:

  1. 基本渲染 -> for

  2. 删除功能


Vue基础 (黑马程序员讲解)_第12张图片


小黑的书架

  • {{ item.name }} {{item.author}}

(七) 指令 v-for的key

1. 语法: key属性 = "唯一标识"

2. 作用: 给列表项添加的唯一标识。便于Vue进行列表项的正确排序复用

v-for 的默认行为会尝试 原地修改数据 (就地复用)

  • 3. 注意点:

    • key的值只能是字符串或数字类型

    • key的值必须具有唯一性

    • 推荐使用 id作为 key (唯一),不推荐使用index作为 key (会变化,不对应)


    (八) 指令 v-model

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

    1. 数据变化 -> 视图自动更新
    2. 视图变化 -> 数据自动更新

    2. 语法: v-model = '变量'

    账户:

    密码:


    综合案例 - 小黑记事本

    功能需求:

    1. 列表渲染

    2. 删除功能

    3. 添加功能

    4. 底部统计和清空

    Vue基础 (黑马程序员讲解)_第13张图片


    Vue代码

    
    

    小黑记事本

    • {{ index + 1 }}
    合计: {{ list.length }}

    七、指令补充

    (一) 指令修饰符

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

    1. 按键修饰
    	@keyup.enter  -> 键盘回车监听
    2. v-model修饰符
    	v-model.trim   -> 去除首尾空格
    	v-model.number   ->转数字
    3.事件修饰符
    	@事件名.stop	->   组织冒泡
    	@事件名.prevent   -> 阻止默认行为

    @keyup.enter - > 监听键盘回车事件


    (二) v-bind操作class

    v-bind对于样式控制的增强

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

    语法:

    :class="对象/数组"

    1. 对象 -> 键就是类名,值是布尔值。如果值为 true,有这个类,否则没有这个类

    适合场景:一个类名,来回切换


    2. 数组 -> 数组中所有的类,都会添加到盒子上,本质就是一个 class 列表

    适合场景:批量添加或删除类


    黑马程序员
    黑马程序员

    案例:京东秒杀 tab 导航高亮


    核心思路:

    1. 基于数据动态渲染 tab -> v-for

    2. 准备下标记录高亮的是哪一个 tab -> activeIndex

    style.css


    
    
    

    (三) v-bind操作style

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


    使用场景:某个具体属性的动态设置


    (四) v-model应用于其他表单元素

    常见的表单元素都可以用 v-model 绑定关联 -> 快速获取 或 设置表单元素的值。

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

    Vue基础 (黑马程序员讲解)_第14张图片


    小黑学习网

    性名:

    是否单身:

    性别:

    所在城市:

    自我描述:



    八、computed计算属性

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

    Vue基础 (黑马程序员讲解)_第15张图片


    (一) 计算属性用法

    语法:

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

    2. 使用起来和普通属性一样使用 {{ 计算属性名 }}

    Vue基础 (黑马程序员讲解)_第16张图片


    小黑的礼物清单

    名字 数量
    {{ item.name }} {{ item.num }}个

    礼物总数:{{ totalCount }} 个


    (二) 计算属性与methods方法

    1. computed 计算属性:

    作用:封装了一段对于数据的处理,求得一个结果

    语法:

    1. 写在 computed配置项中

    2. 作为属性,直接使用 -> this.计算属性 {{计算属性}}


    2. methods 方法:

    作用:给实例提供一个方法,调用以处理业务逻辑

    语法:

    1. 写在 methods配置项中

    2. 作为方法,需要调用 -> this.方法名() {{方法名()}} @事件名 = "方法名"


    3. computed 优势

    在 methods 中也可以封装 computed属性,求得一个结果,不过,computed存在缓存特性.

    4. 缓存特性 (提升性能):

    计算属性会对计算出来的结果缓存,再次使用直接读取缓存,依赖项变化了,会自动重新计算 -> 并再次缓存

    小黑的礼物清单{{ totalCount() }}

    名字 数量
    {{ item.name }} {{ item.num }}个

    礼物总数:{{ totalCount() }} 个


    (三) 计算属性完整写法

    计算属性默认的简写,只能读取访问,不能 "修改"

    如果要"修改" -> 需要写计算属性的完整写法。

    Vue基础 (黑马程序员讲解)_第17张图片


    姓: + 名: = {{ funllName }}


    综合案例 - 成绩案例

    Vue基础 (黑马程序员讲解)_第18张图片


    Vue基础 (黑马程序员讲解)_第19张图片


    编号 科目 成绩 操作
    {{ index+1 }} {{ item.subject }} {{ item.score }} 删除
    暂无数据
    总分:{{ totalScore }} 平均分:{{ averageScore }}
    科目:
    分数:

    九、watch 侦听器 (监视器)

    (一) watch 监视器用法

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

    Vue基础 (黑马程序员讲解)_第20张图片


    语法:

    1. 简单写法 -> 简单类型数据,直接监视

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

    Vue基础 (黑马程序员讲解)_第21张图片


    翻译成的语言:
    ⌨️文档翻译
    {{result}}

    (二) watch 监视器完整写法

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

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

    2. immediate: true 初始化立即执行一次handler 方法


    语法:

    data: {
    	obj: {
    		words: '苹果',
    		lang: 'italy'
    	},
    },
    
    watch: {
    	// watch完整写法
    	数据属性名: {
    		deep: true,	// 深度监视
    		handler(newValue) {
    			console.log(newValue)
    		}
    	}
    }


    翻译成的语言:
    ⌨️文档翻译
    {{result}}

    Vue2 核心技术与实战

    目录:

    1. 生命周期
    	生命周期 & 生命周期四个阶段 / 生命周期钩子 / 生命周期案例
    2.综合案例: 小黑记账清单
    	列表渲染(请求) /添加 /删除 /饼图渲染
    3.工程化开发入门
    	工程化开发和脚手架 /项目运行流程 /组件化 /组件注册
    4.综合案例: 小兔鲜首页
    	拆分模块-局部注册 /结构样式完善 /拆分组件-全局注册

    一、Vue生命周期和生命周期四个阶段

    思考:

    1. 什么时候可以发送初始化渲染请求?  (越早越好)
    2. 什么时候可以操作dom?  (至少dom得渲染出来)

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

    生命周期四个阶段:

    1 创建    2 挂载    3 更新    4 销毁

    Vue基础 (黑马程序员讲解)_第22张图片


    二、Vue生命周期函数 (钩子函数)

    Vue生命周期过程中,会自动运行一些函数,被称为 [生命周期钩子] —> 让开发者可以在 [特定阶段] 运行自己的代码。

    Vue基础 (黑马程序员讲解)_第23张图片


    Vue基础 (黑马程序员讲解)_第24张图片


    {{ title }}

    {{ count }}

    (一) created 应用

    created:响应式数据准备好了,可以开始发送初始化渲染请求。

    Vue基础 (黑马程序员讲解)_第25张图片


    • {{ item.title }}
      {{ item.source}} {{ item.time }}

    (二) mounted 应用

    mounted:模块渲染完成,可以开始操作DOM了

    要求:获取焦点

    Vue基础 (黑马程序员讲解)_第26张图片



    案例 - 小黑记账清单

    编号 消费名称 消费价格 操作
    {{ index + 1}} {{ item.name }} {{ item.price.toFixed(2) }} 删除
    消费总计: {{ totalPrice.toFixed(2) }}

    工程化开发入门

    开发 Vue 的两种方式:

    1. 核心包传统开发模式: 基于 html/css/js 文件,直接引入核心包,开发 Vue。
    2. 工程化开发模式: 基于构建工具 (例如:webpack) 的环境中开发 Vue。

    Vue基础 (黑马程序员讲解)_第27张图片


    问题:

    1. webpack 配置不简单
    2. 雷同的基础配置
    3. 缺乏统一标准

    因此需要一个工具,生成标准化的配置 (Vue CLI)


    一、脚手架Vue CLI

    基本介绍:

    Vue CLI 是Vue官方提供的一个全局命令工具

    可以帮助我们快速创建一个开发Vue项目的标准化基础架子。【集成了webpack配置】


    好处:

    1. 开箱即用,零配置

    2. 内置babel等工具

    3. 标准化的webpack配置

    使用步骤:

    1. 按 win+r ,输入 cmd,按回车

    2. 输入:npm config set registry https://registry.npm.taobao.org,按回车

    3. 全局安装(只需安装一次即可) yarn global add @vue/cli 或者 npm i @vue/cli -g

    4. 查看vue/cli版本:vue --version

    5. 创建项目架子:vue create project-name(项目名不能使用中文)

    6. 启动项目:yarn serve 或者 npm run serve(命令不固定,找package.json)


    二、项目目录介绍和运行流程

    1.项目目录介绍

    Vue基础 (黑马程序员讲解)_第28张图片

    虽然脚手架中的文件有很多,目前咱们只需认识三个文件即可

    1. main.js 入口文件

    // 作用:导入App.vue,基于App.vue创建结构渲染index.html 
    // 1.导入 Vue 核心包
    import Vue from 'vue'
    // 2. 导入App.vue根组件
    import App from './App.vue'
    // 提示:当前处于什么环境 (生产环境 / 开发环境)
    Vue.config.productionTip = false	// false 无提示
    
    // 3. Vue 实例化,提供render方法 -> 基于 App.vue创建结构渲染index.html
    new Vue({
     // el: '#app',作用:和 $mount('选择器')作用一致,用于指定Vue所管理容器
     //简化写法: render: h => h(App),
     // 完整写法:
     // 基于App创建元素结构,将App.vue渲染到 index.html容器中
     render:(createElement) => {
     	return createElement(App)
     }
    }).$mount('#app')		
    

       2.  App.vue App根组件

        3. index.html 模板文件

    
      
      
     
       
      

    2.运行流程

    Vue基础 (黑马程序员讲解)_第29张图片

    三、组件化开发

    组件化: 一个页面 可以拆分成一个个组件,每个组件有着自己独立的结构、样式、行为。

    好处:便于维护,利于复用 → 提升开发效率。

    组件分类:普通组件、根组件。

    比如:下面这个页面,可以把所有的代码都写在一个页面中,但是这样显得代码比较混乱,难易维护。咱们可以按模块进行组件划分

    Vue基础 (黑马程序员讲解)_第30张图片


    四、根组件 App.vue

    1.根组件介绍

    整个应用最上层的组件,包裹所有普通小组件

    Vue基础 (黑马程序员讲解)_第31张图片


    2.组件是由三部分构成

    Vue基础 (黑马程序员讲解)_第32张图片


    • 语法高亮插件

    • 三部分构成

      • template:结构 (有且只能一个根元素)

      • script: js逻辑

      • style: 样式 (可支持less,需要装包)

    • 让组件支持less

      (1) style标签,lang="less" 开启less功能

      (2) 装包: yarn add less less-loader -D 或者npm i less less-loader -D


    五、普通组件的注册使用

    Vue基础 (黑马程序员讲解)_第33张图片


    组件注册的两种方式:

    1. 局部注册:只能在注册的组件内使用
       + 创建 .vue 文件 (三个组成部分)
       + 在使用的组件内导入并注册
    2. 全局注册:所有组件内都能使用

    (一) 局部注册

    特点

    只能在注册的组件内使用

    步骤

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

    2. 在使用的组件内先导入再注册,最后使用

    使用方式

    当成html标签使用即可 <组件名>

    注意

    组件名规范 —> 大驼峰命名法, 如 HmHeader

    语法

    Vue基础 (黑马程序员讲解)_第34张图片


    // 导入需要注册的组件
    import 组件对象 from '.vue文件路径'
    import HmHeader from './components/HmHeader'
    
    export default {  // 局部注册
      components: {
       '组件名': 组件对象,
        HmHeader:HmHeaer,
        HmHeader
      }
    }
    
    

    6.练习

    在App组件中,完成以下练习。在App.vue中使用组件的方式完成下面布局

    Vue基础 (黑马程序员讲解)_第35张图片


    
    
    

    将下方组件写入到components文件夹内


    
    
    
    
    

    
    
    
    
    
    
    
    
    
    
    

    如果 HmFooter + tab 出不来 (< HmFooter>< /HmFoooter>) -> 需要配置 vscode ,在设置中搜索 trigger on tab -> 勾选第一个

    Vue基础 (黑马程序员讲解)_第36张图片


    (二) 全局注册

    特点:

    全局注册的组件,在项目的 任何组件 中都能使用

    步骤

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


    • main.js中进行全局注册

    Vue基础 (黑马程序员讲解)_第37张图片


    使用方式

    当成HTML标签直接使用

    <组件名>

    ​​​​​​​


    注意

    组件名规范 —> 大驼峰命名法, 如 HmHeader

    5.语法

    Vue.component('组件名', 组件对象)

    例:

    // 导入需要全局注册的组件,往代码的顶部编写(规范)
    import HmButton from './components/HmButton'
    // 进入全局注册 -> 在所有的组件范围内都能直接使用
    Vue.component('HmButton', HmButton)

    6.练习

    在以下3个局部组件中是展示一个通用按钮

    Vue基础 (黑马程序员讲解)_第38张图片

    HmFooter.vue



    main.js

    import Vue from 'vue'
    import App from './App.vue'
    ​// 导入全局注册的组件
    import HmButton from './components/HmButton'
    
    vue.config.productionTip = false
    ​
    // 进行全局注册
    Vue.component('HmButton',HmButton)
    ​
    new Vue({
        render: (createElement) => {
            // 基于App创建元素结构
            return createElement(App)
        }
    })

    HmHeader.vue


    HmMain.vue


    目录

    1. 组件的三大组成部分 (结构 /样式 /逻辑)
    	scoped样式冲突 / data是一个函数
    2. 组件通信
    	组件通信语法 /父传子 /子传父 /非父子(扩展)
    3. 综合案例:小黑记事本(组件版)
    	拆分组件 /渲染 /添加 /删除 /统计 /清空 /持久化
    4. 进阶语法
    	v-model原理	/v-model应用于组件 /sync修饰符 /ref 和 $refs /$nextTick

    六、组件注意点说明

    组件的三大组成部分

    Vue基础 (黑马程序员讲解)_第39张图片


    (一) scoped样式冲突

    默认情况

    写在组件中的样式会 全局生效 → 因此很容易造成多个组件之间的样式冲突问题。

    1. 全局样式: 默认组件中的样式会作用到全局,任何一个组件中都会受到此样式的影响

    1. 局部样式: 可以给组件加上scoped 属性,可以让样式只作用于当前组件


    代码演示

    BaseOne.vue

    
    
    
    

    BaseTwo.vue

    
    
    
    
    

    App.vue

    
    
    

    scoped原理

    1. 当前组件内标签都被添加data-v-hash值 的属性

    2. css选择器都被添加 [data-v-hash值] 的属性选择器

    最终效果: 必须是当前组件的元素, 才会有这个自定义属性, 才会被这个样式作用到


    (二) data是一个函数

    data为什么要写成函数

    一个组件的 data 选项必须是一个函数。目的是为了:保证每个组件实例,维护独立的一份数据对象

    每次创建新的组件实例,都会重新执行一次data 函数,得到一个新对象。

    Vue基础 (黑马程序员讲解)_第40张图片


    代码演示

    BaseCount.vue

    
    
    
    
    

    App.vue

    
    
    
    
    

    组件通信

    一、什么是组件通信?

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

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

    • 想使用其他组件的数据,就需要组件通信


    组件之间如何通信

    Vue基础 (黑马程序员讲解)_第41张图片


    思考:

    1. 组件之间有哪些关系?

    2. 对应的组件通信方案有哪几类?


    二、组件关系分类

    1. 父子关系

    2. 非父子关系


    Vue基础 (黑马程序员讲解)_第42张图片


    通信解决方案

    Vue基础 (黑马程序员讲解)_第43张图片


    三、父子通信流程

    1. 父组件通过 props 将数据传递给子组件

    2. 子组件利用 $emit 通知父组件修改更新

    Vue基础 (黑马程序员讲解)_第44张图片


    父向子传值步骤

    1. 给子组件以添加属性的方式传值

    2. 子组件内部通过props接收

    3. 模板中直接使用 props接收的值

    Vue基础 (黑马程序员讲解)_第45张图片


    父向子通信代码示例

    父组件通过 props 将数据传递给子组件

    父组件App.vue

    
    
    
    
    

    子组件Son.vue

    
    
    
    
    

    子向父传值步骤

    1. $emit触发事件,给父组件发送消息通知

    2. 父组件监听$emit触发的事件

    3. 提供处理函数,在函数的性参中获取传过来的参数


    子向父通信代码示例

    子组件利用 $emit 通知父组件,进行修改更新

    Vue基础 (黑马程序员讲解)_第46张图片


    父组件App.vue

    
    
    
    
    

    子组件 Son.vue:

    
    
    
    
    

    四、props详解

    1. Props 定义

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


    2. Props 作用

    向子组件传递数据


    3. 特点

    1. 可以 传递 任意数量 的prop

    2. 可以 传递 任意类型 的prop

    Vue基础 (黑马程序员讲解)_第47张图片


    4. 代码演示

    父组件App.vue

    
    
    
    
    

    子组件UserInfo.vue

    
    
    
    
    

    props校验

    1. 思考

    组件的props可以乱传吗

    2. 作用

    为组件的 prop 指定验证要求,不符合要求,控制台就会有错误提示 → 帮助开发者,快速发现错误

    3. 语法

    • 类型校验

    • 非空校验

    • 默认值

    • 自定义校验

    Vue基础 (黑马程序员讲解)_第48张图片


    4. 代码演示

    App.vue

    
    
    
    
    

    BaseProgress.vue

    
    
    
    
    

    props校验完整写法

    1.语法

    props: {
      校验的属性名: {
        type: 类型,  // Number String Boolean ...
        required: true, // 是否必填
        default: 默认值, // 默认值
        validator (value) {
          // 自定义校验逻辑
          return 是否通过校验
        }
      }
    },

    2. 代码实例


    3.注意

    1.default 和 required 一般不同时写(因为当时必填项时,肯定是有值的)

    2.default 后面如果是简单类型的值,可以直接写默认。如果是复杂类型的值,则需要以函数的形式return一个默认值


    四、props&data、单向数据流

    1.共同点

    都可以给组件提供数据


    2.区别

    • data 的数据是 自己 的 → 随便改

    • prop 的数据是 外部 的 → 不能直接改,要遵循 单向数据流


    3.单向数据流:

    父级props 的数据更新,会向下流动,影响子组件。这个数据流动是单向的


    4.代码演示

    App.vue

    
    
    
    
    

    BaseCount.vue

    
    
    
    
    

    Vue基础 (黑马程序员讲解)_第49张图片


    五、非父子通信-event bus 事件总线

    1.作用

    非父子组件之间,进行简易消息传递。(复杂场景→ Vuex)

    2.步骤

    1. 创建一个都能访问的事件总线 (空Vue实例)—> utils/EventBus.js

      import Vue from 'vue'
      const Bus = new Vue()
      export default Bus

    2. A组件(接受方),监听Bus的 $on事件

      created () {
        Bus.$on('sendMsg', (msg) => {
          this.msg = msg
        })
      }

    3. B组件(发送方),触发Bus的$emit事件

      Bus.$emit('sendMsg', '这是一个消息')
      Vue基础 (黑马程序员讲解)_第50张图片

    3.代码示例

    EventBus.js

    import Vue from 'vue'
    const Bus  =  new Vue()
    export default Bus

    BaseA.vue(接受方)

    
    
    
    
    

    BaseB.vue(发送方)

    
    
    
    
    

    App.vue

    
    
    
    
    

    六、非父子通信-provide&inject

    1.作用

    跨层级共享数据


    2.场景

    Vue基础 (黑马程序员讲解)_第51张图片


    3.语法

    1. 父组件 provide提供数据

    export default {
      provide () {
        return {
           // 普通类型【非响应式】
           color: this.color, 
           // 复杂类型【响应式】
           userInfo: this.userInfo, 
        }
      },
        data () {
            return {
                color: 'pink',	// 简单类型
                userInfo: {		// 复杂类型
                    name: 'zs',
                    age: 19
                }
            }
        }
    }

    2.子/孙组件 inject获取数据

    export default {
      inject: ['color','userInfo'],
      created () {
        console.log(this.color, this.userInfo)
      }
    }

    4.注意

    • provide提供的简单类型的数据不是响应式的,复杂类型数据是响应式。(推荐提供复杂类型数据)

    • 子/孙组件通过inject获取的数据,不能在自身组件内修改


    v-model原理

    1.原理:

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

    Vue基础 (黑马程序员讲解)_第52张图片


    2.作用:

    提供数据的双向绑定

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

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


    3.注意

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


    4.代码示例

    
    
     
    

    5.v-model使用在其他表单元素上的原理

    不同的表单元素, v-model 在底层的处理机制是不一样的。比如给checkbox 使用 v-model

    底层处理的是 checked属性和change事件。

    不过咱们只需要掌握应用在文本框上的原理即可


    一、表单类组件封装

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

    Vue基础 (黑马程序员讲解)_第53张图片


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

    Vue基础 (黑马程序员讲解)_第54张图片


    需求目标

    实现 子组件父组件 数据的双向绑定 (实现App.vue中的selectId和子组件选中的数据进行双向绑定)


    代码演示

    App.vue

    
    
    
    
    

    BaseSelect.vue

    
    
    
    
    

    二、v-model简化代码

    1.目标:

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


    2.如何简化:

    v-model其实就是 :value和@input事件的简写

    • 子组件:props通过value接收数据,事件触发 input

    • 父组件:v-model直接绑定数据


    3.代码示例

    子组件

    
    props: {
      value: String
    },
    methods: {
      handleChange (e) {
        this.$emit('input', e.target.value)
      }
    }

    父组件


    .sync修饰符

    1.作用

    可以实现 子组件父组件数据双向绑定,简化代码

    简单理解:子组件可以修改父组件传过来的props值


    2.特点

    prop属性名,可以自定义,非固定为 value


    3.场景

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

    Vue基础 (黑马程序员讲解)_第55张图片


    4.本质

    .sync修饰符 就是 :属性名 和 @update:属性名 合写

    5.语法

    父组件

    //.sync写法
    
    --------------------------------------
    //完整写法
    

    子组件

    props: {
      visible: Boolean
    },
    
    this.$emit('update:visible', false)

    6.代码示例

    App.vue

    
    
    
    
    

    BaseDialog.vue

    
    
    
    
    

    ref和$refs

    1.作用

    利用 ref$refs 可以用于 获取 dom 元素组件实例


    2.特点:

    查找范围 → 当前组件内(更精确稳定)

    获取 dom:

    • 目标标签 - 添加 ref 属性

    我是渲染图表的容器
    • 恰当时机,通过 this.$refs.xxx(ref名),获取目标标签

    mounted(){
    	console.log(this.$refs.chartRef)
    },

    代码示例

    App.vue

    
    
    
    
    

    BaseChart.vue

    
    
    
    
    
    
    

    获取组件:

    • 目标组件 - 添加 ref 属性

    • 恰当时机,通过 this.$refs.xxx,获取目标组件,就可以调用组件对象里面的方法

    this.$refs.baseForm.组件方法()

    代码实例:

    App.vue