本文共 29170 字,大约阅读时间需要 97 分钟。
组件化
React
的组件化最为彻底天然分层
jQuery
时代的代码大部分情况下是面条代码,耦合严重MVC
、MVP
还是MVVM
模式都能帮助我们进行分层,代码解耦更易于读写生态
UI
库都有成熟的解决方案Vue
(读音 /vjuː/,类似于 view
),不要读错
Vue
是一个渐进式
的框架 渐进式
意味着你可以将Vue
作为你应用的一部分嵌入其中,带来更丰富的交互体验Vue
实现,那么Vue
的核心库以及其生态系统,比如Core+Vue-router+Vuex
,也可以满足你各种各样的需求Vue
有很多特点和Web
开发中常见的高级功能 解耦视图和数据
可复用的组件
前端路由技术
状态管理
虚拟DOM
数据驱动界面更新
, 无需操作DOM来更新界面
只需要关心如何获取数据, 如何处理数据, 如何编写业务逻辑代码
将处理好的数据交给Vue, Vue就会自动将数据渲染到模板中(界面上)
组件化开发
,我们可以将网页拆分成一个个独立的组件来编写拼接成一个完整的网页
npm install vue
npm install --global vue-cli
Vue对象
的时候,传入了一些选项options:{}
{}
中包含了el
属性: Vue对象
挂载到哪一个元素上id
为app
的元素上{}
中包含了data
属性:该属性中通常会存储一些数据
message
这样网络
,从服务器加载的浏览器执行代码的流程
HTML
Vue实例
,并且对原HTML进行解析和修改
数据响应式
的{ {message}}
数据列表
HTML
中HTML
代码中,使用v-for
指令JavaScript
代码中完成DOM
的拼接相关操作数据响应式
的 当我们数组中的数据发生改变时,界面会自动改变
- { {item}}
methods
Vue
对象中定义方法
@click
用于监听某个元素的点击事件
当发生点击时,执行的方法
(方法通常是methods
中定义的方法)计数器:{ {count}}
MVVM
MVVM
思想 View
依然是我们的DOM
Model
就是我们我们抽离出来的obj
ViewModel
就是我们创建的Vue
对象实例ViewModel
通过Data Binding
让obj
中的数据实时的在DOM
中显示ViewModel
通过DOM Listener
来监听DOM
事件,并且通过methods
中的操作,来改变obj
中的数据View
层: 视图层
DOM
层给用户展示各种信息
展示数据, 与用户交互
Model
层: 数据层
保存数据, 处理数据业务逻辑
ViewModel
层: 视图模型层
View
和Model
沟通的桥梁Data Binding
,也就是数据绑定
,将Model
的数据改变状态实时的反应到View
中DOM Listener
,也就是DOM
监听,当DOM
发生一些事件(点击、滚动、touch
等)时,可以监听到,并在需要的情况下改变对应的Data
数据的双向传递
M -> VM -> V
V -> VM -> M
被控制的区域
: View
Vue实例对象
: View Model
实例对象中的data
: Model
Vue
实例的时候,传入了一个对象options
options
中可以包含哪些选项呢? el
: string | HTMLElement
Vue
实例会管理哪一个DOM
需要控制界面上的哪个区域
data
: Object | Function
(组件当中data
必须是一个函数)Vue
实例对应的数据对象被控制区域的数据是什么
methods
: { [key: string]: Function }
Vue
的一些方法,可以在其他地方调用,也可以在指令中使用插值表达式
,使用{ { }}
将js代码包裹,使js中的数据属性值
进行展示,也称为Mustache语法
data中的属性名
数字
字符串
布尔值
对js的数据属性进行运算
{ {message}}
{ {message}}, 李银河!
{ {firstName + lastName}}
{ {firstName + ' ' + lastName}}
{ {firstName}} { {lastName}}
{ {counter * 2}}
Vue
的v-once
指令不需要跟任何表达式
(比如之前的v-for
后面是由跟表达式的)元素和组件只渲染一次,不会随着数据的改变而改变
{ {message}}
{ {message}}
HTML
代码 { {}}
来输出,会将HTML
代码也一起输出HTML
格式进行解析,并且显示对应的内容HTML
展示 可以使用v-html
指令 - 该指令后面往往会跟上一个string
类型 - 会将string
的html
解析出来并且进行渲染{ {url}}
v-text
作用和Mustache
比较相似:都是用于将数据显示在界面中v-text
通常情况下,接受一个string
类型v-text
不够灵活,会将标签中的文本内容覆盖
{ {message}}, Vue.js!
, Vue.js!
v-pre
用于跳过这个元素和它子元素的编译过程
,用于显示原本的Mustache
语法第一个h2
元素中的内容会被编译解析出来对应的内容第二个h2
元素中会直接显示{ {message}}
{ {message}}
{ {message}}
Vue 数据绑定过程
问题
在最终的HTML被生成渲染之前会先显示模板内容
如果用户网络比较慢或者网页性能比较差, 那么用户会看到模板内容
v-cloak
配合 [v-cloak]:{display: none}
默认先隐藏未渲染的界面
等到生成HTML渲染之后再重新显示
v-cloak 指令作用
数据渲染之后自动显示元素
{ {message}}
什么是 v-bind 指令
元素
"绑定数据
, 我们可以使用{ {}}, v-text, v-html
元素的属性
"绑定数据
, 就必须使用v-bind
专门用于给"元素的属性"绑定数据的
a
元素的href
属性img
元素的src
属性v-bind 格式
v-bind:属性名称="绑定的数据"
:属性名称="绑定的数据"
v-bind 特点
任意一个合法的JS表达式
:属性名称="age + 1"
v-bind
用于绑定一个或多个属性值
,或者向另一个组件传递props
值链接src
、网站的链接href
、动态绑定一些类
、样式
等等Vue
实例中的data
绑定元素的src
和href
对象语法
:class
后面跟的是一个对象
## 用法一:直接通过{}绑定一个类Hello World
## 用法二:也可以通过判断,传入多个值Hello World
## 用法三:和普通的类同时存在,并不冲突注:如果isActive和isLine都为true,那么会有title/active/line三个类Hello World
## 用法四:如果过于复杂,可以放在一个methods或者computed中注:classes是一个计算属性Hello World
举例
Title { {message}}
{ {message}}
数组语法
:class
后面跟的是一个数组
## 用法一:直接通过[]绑定一个类Hello World
## 用法二:也可以传入多个值Hello World
## 用法三:和普通的类同时存在,并不冲突注:会有title/active/line三个类Hello World
## 用法四:如果过于复杂,可以放在一个methods或者computed中注:classes是一个计算属性Hello World
举例
Title { {message}}
{ {message}}
- { {m}}
v-bind
给 style
属性绑定CSS内联样式
数据 对象
中 :style="{color:'red','font-size':'50px'}"
Model对象
中obj: { color: 'red', 'font-size': '80px',}
注意点
驼峰式 (camelCase) fontSize
-
, 那么必须用引号括起来
需要绑定Model中的多个对象
, 可以放到一个数组
中赋值对象语法
style
后面跟的是一个对象类型
key
是CSS
属性名称value
是具体赋的值,值可以来自于data
中的属性{ {messages}}
数组语法
style
后面跟的是一个数组类型
多个值以,分割即可
v-if
、v-else-if
、v-else
JavaScript
的条件语句if
、else
、else if
类似Vue
的条件指令可以根据表达式的值在
DOM中渲染或销毁元素或组件
什么是 v-if 指令
条件渲染
如果 v-if 取值是 true 就渲染元素, 如果不是就不渲染元素
v-if 特点
如果条件不满足根本就不会创建这个元素(重点)
v-if 注意点
v-if 可以从模型中获取数据
v-if 也可以直接赋值一个表达式
v-if 的原理
v-if
后面的条件为false
时,对应的元素以及其子元素不会渲染
不会有对应的标签
出现在DOM
中v-else 指令
v-else 指令可以和 v-if 指令配合使用, 当 v-if 不满足条件时就执行 v-else 就显示 v-else 中的内容
v-else 注意点
v-else 不能单独出现
v-if 和 v-else 中间不能出现其它内容
v-else-if 指令
v-else-if 可以和 v-if 指令配合使用
当v-if 不满足条件时就依次执行后续 v-else-if, 哪个满足就显示哪个
v-else-if 注意点
和 v-else一样
案例
优秀
良好
及格
不及格
什么是 v-show 指令
v-show
和 v-if
的能够一样都是条件渲染
取值为 true 就显示, 取值为 false 就不显示
v-if 和 v-show 区别
v-if
: 只要取值为false就不会创建元素
v-show
: 哪怕取值为false也会创建元素, 只是如果取值是false会设置元素的display为none
v-if 和 v-show 应用场景
每次 v-if 都会创建和删除元素
不会反复创建和删除
, 只是修改display的值
频繁切换元素显示隐藏
, 那么推荐使用 v-show, 否则使用 v-if
我要不要显示呢
什么是v-for指令
相当于JS中的for in循环, 可以根据数据多次渲染元素
item in items
v-for 特点
数组, 字符, 数字, 对象
案例
不需要使用索引值
v-for="movie in movies"
movies
中取出movie
,并且在元素的内容中,我们可以使用Mustache
语法,来使用movie
需要使用数组中的索引值
v-for=(item, index) in items
index
就代表了取出的item
在原数组的索引值
- { {item}}
- { {index+1}}.{ {movie}}
v-for
可以遍历对象
:
- { {value}}-{ {key}}-{ {index}}
v-for 注意点
就地复用
”策略数据混乱
举例
key
先判断 key 是否相同
如果相同则复用
如果不同则重新创建
key 属性注意点
index
的作为key
,因为当列表的内容新增或者删除时index都会发生变化
- { {index}} --- { {person.name}}
v-for
时,给对应的元素或组件添加上一个:key属性
key属性
呢? Vue
的虚拟DOM
的Diff
算法有关系React’s diff algorithm
中的一张图来简单说明一下: Diff
算法默认执行起来是这样的key
来给每个节点做一个唯一标识
Diff
算法就可以正确的识别此节点
找到正确的位置区插入新的节点
key
的作用主要是为了高效的更新虚拟DOM
Vue
是数据响应式
的当数据发生变化
时,Vue
会自动检测数据变化
,视图会发生对应的更新
Vue
中包含了一组观察数组编译的方法,使用它们改变数组也会触发视图的更新methods: { updateData: function(){ // 响应式数组方法 // 1. push方法 this.names.push('xxx','zs') // 2. pop方法 this.names.pop() // 3. unshift方法 this.names.unshift('xxx','zs') // 4. shift方法 this.names.shift() // 5. splice方法 // 传递一个参数(index):将对应index,以及后面的所有数据删除掉 this.names.splice(2) // 6. sort排序数据 this.names.sort() // 7. reverse反转数据 this.names.reverse() // 注意: 通过索引值修改数组中的元素(不可响应式) this.letters[0] = 'bbbbbb'; // 通过以下方法 this.letters.splice(0, 1, 'bbbbbb') // set(要修改的对象, 索引值, 修改后的值) Vue.set(this.letters, 0, 'bbbbbb')
什么是 v-on 指令?
专门用于给元素绑定监听事件
v-on 指令格式
v-on:事件名称="回调函数名称"
@事件名称="回调函数名称"
v-on 注意点:
v-on 绑定的事件被触发之后, 会去 Vue 实例对象的 methods 中查找对应的回调函数
v-on
来绑定监听事件, 那么在指定事件名称的时候不需要写on
v-on
来绑定监听事件, 那么在赋值的时候必须赋值一个回调函数的名称
v-on:click="counter++”
methods
中定义的函数点击次数: { {counter}}
v-on 修饰符
事件冒泡,事件捕获, 阻止默认行为
等v-on修饰符
来处理常见修饰符
.stop
- 调用 event.stopPropagation()
.prevent
- 调用 event.preventDefault()
.{keyCode | keyAlias}
- 只当事件是从特定键触发时才触发回调
.self
- 只当事件是从侦听器绑定的元素本身触发时才触发回调
.capture
- 添加事件侦听器时使用 capture 模式
.native
- 监听组件根元素的原生事件
.once
- 只触发一次回调
什么是按键修饰符
通过按键修饰符监听特定按键触发的事件
例如
按键修饰符分类
methods
中定义方法,以供@click
调用时,需要注意参数问题情况一
不需要额外参数
,那么方法后的()
可以不添加方法本身中有一个参数
,那么会默认将原生事件event
参数传递进去同时传入某个参数
,同时需要event
时,可以通过$event
传入事件自定义全局指令
自定义全局指令语法
vue.directive('自定义指令名称', { 生命周期名称: function (el) { 指令业务逻辑代码 }});
指令生命周期方法
一定要明确指令的业务逻辑代码更适合在哪个阶段执行
自定义指令注意点
v-
, 而在自定义时不需要加上v-
我是段落
自定义指令参数
v-model="name"
获取自定义指令传递的参数
保存了指令传递过来的参数
我是段落
自定义全局指令的特点
在任何一个Vue实例控制的区域中都可以使用
自定义局部指令的特点
只能在自定义的那个Vue实例中使用
如何自定义一个局部指令
directives: { // key: 指令名称 // value: 对象 'color': { bind: function (el, obj) { el.style.color = obj.value; } }}
举例
我是段落
我是段落
插值语法特点
{ {}}
中编写合法的JavaScript表达式在插值语法中编写JavaScript表达式缺点
没有代码提示
语句过于复杂不利于我们维护
如何解决?
对于任何复杂逻辑,你都应当使用计算属性
注意点
通过一个函数返回的数据
不能在计算属性名称后面加上()
是一个属性不是一个函数(方法)
{
{name}}{
{age + 1}}{
{msg.split("").reverse().join("")}}{
{msg2}}
计算属性和函数
区别
呢? 函数"不会"将计算的结果缓存起来, 每一次访问都会重新求值
计算属性"会"将计算的结果缓存起来, 只要数据没有发生变化, 就不会重新求值
计算属性的特点
返回的结果没有发生变化
, 那么计算属性就只会被执行一次
应用场景
比较适合用于计算不会频繁发生变化的的数据
总价格: { {totalPrice}}
{
{msg2}}{
{msg2}}{
{msg2}}
getter
和一个setter
在上面的例子中,我们只是使用getter
来读取 在某些情况下,你也可以提供一个setter
方法(不常用) 在需要写setter
的时候,代码如下:computed: { fullName: { set: function(newValue) { // console.log('-----', newValue); const names = newValue.split(' '); this.firstName = names[0]; this.lastName = names[1]; }, get: function () { return this.firstName + ' ' + this.lastName } },}
methods
和computed
区别 computed
会进行缓存,如果多次使用时,计算属性只会调用一次
methods
会多次调用{ {fullName}}{ {fullName}}{ {fullName}}{ {getFullName()}}{ {getFullName()}}{ {getFullName()}}
computed: { fullName(){ console.log('执行fullName的计算属性'); return this.firstName + ' ' + this.lastName; }},methods: { getFullName(){ console.log('执行getFullName的方法'); return this.firstName + ' ' + this.lastName; }}
Vue
中使用v-model
指令来实现表单元素和数据的双向绑定
input
中的v-model
绑定了message
,所以会实时将输入的内容传递给message
,message
发生改变message
发生改变时,因为上面我们使用Mustache
语法,将message
的值插入到DOM
中,所以DOM
会发生响应的改变v-model
实现了双向的绑定v-model
用于textarea
元素{ {message}}
v-model
其实是一个语法糖,它的背后本质上是包含两个操作: v-bind
绑定一个value
属性v-on
指令给当前元素绑定input
事件## 等于下面代码
v-model: radio
当存在多个单选框时
您选择的性别是: { {sex}}
v-model: checkbox
单个勾选框
和多个勾选框
单个勾选框
: v-model
即为布尔值
input
的value
并不影响v-model
的值多个复选框
: data
中属性是一个数组input
的value
添加到数组中是否选中: {
{checked}}您选中的爱好: {
{hobbies}}
v-model:select
checkbox
一样,select
也分单选和多选两种情况v-model
绑定的是一个值option
中的一个时,会将它对应的value
赋值到mySelect
中v-model
绑定的是一个数组option
对应的value
添加到数组mySelects
中您选择的水果是: { {mySelect}}
您选择的水果是: { {mySelects}}
value
赋值而已 input
的时候直接给定的input
的值可能是从网络获取
或定义在data
中的v-bind:value
动态的给value
绑定值lazy
修饰符 v-model
默认是在input
事件中同步输入框的数据
的data
中的数据就会自动发生改变
lazy
修饰符可以让数据在失去焦点或者回车时才会更新
number
修饰符 number
修饰符可以让在输入框中输入的内容自动转成数字类型
trim
修饰符 trim
修饰符可以过滤内容左右两边的空格
{ {message}}
{ {age}}-{ {typeof age}}
您输入的名字:{ {name}}
什么是过滤器?
处理数据
的过滤器一般用于格式化插入的文本数据
如何自定义全局过滤器
Vue.filter("过滤器名称", 过滤器处理函数):
如何使用全局过滤器
{ { msg | 过滤器名称 }}
:value="msg | 过滤器名称"
过滤器注意点
插值语法
和v-bind
中使用过滤器可以连续使用
{
{name | formartStr1 | formartStr2}}
自定义全局过滤器的特点
任何一个Vue实例控制的区域
中都可以使用自定义局部过滤器的特点
只能在自定义的那个Vue实例
中使用如何自定义一个局部指令
给创建Vue实例时传递的对象添加
filters: { // key: 过滤器名称 // value: 过滤器处理函数 'formartStr': function (value) { }}
{
{name | formartStr}}{
{name | formartStr}}
利用过滤器对时间进行格式化
{
{time | dateFormart("yyyy-MM-dd")}}
学生管理系统
27-Vue-综合小练习
transition
组件中 当transition组件中的元素显示时会自动查找.v-enter/.v-enter-active/.v-enter-to类名
当transition组件中的元素隐藏时会自动查找.v-leave/ .v-leave-active/.v-leave-to类名
只需要在.v-enter和.v-leave-to中指定动画动画开始的状态
在.v-enter-active和.v-leave-active中指定动画执行的状态,即可完成过渡动画
只能放一个元素, 多个元素无效
如果想给多个元素添加过渡动画, 那么就必须创建多个transition组件
transition添加appear属性
的方式第一次进入就需要显示动画
如果有多个不同的元素需要执行不同的过渡动画
给transition指定name的方式
进入之前/进入之后/进入过程中, 离开之前/离开之后/离开过程中
"对应的类名不同的元素执行不同的过渡动画
transition+类名
的方式确实能够实现过渡效果并不能保存动画之后的状态
动态绑定类名, 过程完成之后删除类名
因为删除了类名, 所以不能保存最终的效果
JS钩子
来实现过渡动画钩子函数 | 含义 |
---|---|
v-on:before-enter=“beforeEnter” | 进入动画之前 |
v-on:enter=“enter” | 进入动画执行过程中 |
v-on:after-enter=“afterEnter” | 进入动画完成之后 |
v-on:enter-cancelled=“enterCancelled” | 进入动画被取消 |
v-on:before-leave=“beforeLeave” | 离开动画之前 |
v-on:leave=“leave” | 离开动画执行过程中 |
v-on:after-leave=“afterLeave” | 离开动画完成之后 |
v-on:leave-cancelled=“leaveCancelled” | 离开动画被取消 |
el.offsetWidth
或者el.offsetHeight
enter
和leave
方法中必须调用done
方法, 否则after-enter
和after-leave
不会执行添加初始动画
, 那么需要把done
方法包裹到setTimeout
方法中调用第三方框架
实现过渡动画钩子函数
中编写Velocity动画
默认类名(v-xxx)
来指定过渡动画自定义类名前缀(yyy-xx)
来指定过渡动画(transition name=“yyy”)JS钩子函数
来指定过渡动画以外自定义类名
的方式来指定过渡动画enter-class | 进入动画开始之前 |
---|---|
enter-active-class | 进入动画执行过程中 |
enter-to-class | 进入动画执行完毕之后 |
leave-class | 离开动画开始之前 |
leave-active-class | 离开动画执行过程中 |
leave-to-class | 离开动画执行完毕之后 |
Animate.css
实现过渡动画 导入Animate.css库
绑定需要的类名
transition
可以给单个元素添加过渡动画
transition-group
来添加transition-group
和transition
的用法一致 单个元素
添加动画多个元素
添加动画而已
- { {index}} --- { {person.name}}
transition-group
会将动画的元素放到span标签
中tag属性
来指定将动画元素放到什么标签中v-for就地复用导致
的保证所有数据key永远是唯一的即可
{ {index}} --- { {person.name}}
拆分
为多个小的界面, 每一个小的界面就是一个组件
功能块
,而每一个组件又可以进行细分
将大界面拆分成小界面就是组件化
组件化的好处
简化Vue实例的代码
提高复用性
Vue.js
中的重要思想 组件树
组件化思想的应用
方便组织和管理
,并且扩展性也更强
创建组件构造器
注册组件
使用组件
注意点
模板只能有一个根元素
Vue.extend()
Vue.extend()
创建的是一个组件构造器
template
代表我们自定义组件的模板
HTML
代码Vue2.x
的文档中几乎已经看不到了,它会直接使用下语法糖,但是在很多资料还是会提到这种方式,而且这种方式是学习后面方式的基础Vue.component()
Vue.component()
是将刚才的组件构造器注册
为一个组件,并且给它起一个组件的标签名称
参数
: 注册组件的标签名
组件构造器
组件
必须挂载
在某个Vue
实例下,否则它不会生效
传入一个组件构造器
以外, 还可以直接传入一个对象
字符串模板
中编写以外, 还可以像过去的art-template
一样在script
中编写script
中编写以外, vue还专门提供了一个编写模板的标签template
我是描述信息
Vue.component()
注册组件时,组件的注册是全局
的任意Vue示例
下使用全局组件
我是描述信息
挂载
在某个实例中, 那么就是一个局部
组件局部组件
我是描述信息
data
和methods
data
和methods
不能像在vue实例中一样直接使用data
必须通过返回函数的方式来使用data
{
{appMsg}}{
{abcMsg}}
自定义组件中的data为什么是一个函数
复用
, 为了保证复用时每个组件的数据都是独立
的, 所以必须是一个函数
不是通过函数返回
的, 那么多个组件就会共用一份数据
, 就会导致数据混乱
通过函数返回
的, 那么每创建一个新的组件
, 都会调用一次这个方法
将这个方法返回的数据和当前创建的组件绑定在一起
, 这样就有效的避免了数据混乱
{
{number}}
v-if
来实现切换v-if
来实现切换组件的本质就是一个自定义元素
我是首页
v-if/v-else-if/v-else
确实能够切换组件
component
我们称之为动态组件
, 也就是你让我显示谁我就显示谁component
可以配合keep-alive
来保存被隐藏组件隐藏之前的状态
我是首页
单个组件就使用transition
多个组件就使用transition-group
默认情况下进入动画和离开动画是同时执行的
如果想一个做完之后再做另一个, 需要指定动画模式
我是首页
父子组件
局部组件就是最简单的父子组件
, 因为我们说过可以把Vue实例看做是一个大组件
自定义组件中再定义其它组件
子标签
的形式在Vue
实例中使用 components
时,Vue
会编译好父组件
的模块父组件
将要渲染的HTML
(相当于父组件
中已经有了子组件
中的内容了)<son></son>
是只能在父组件
中被识别的<son></son>
是会被浏览器忽略的我是父组件
我是子组件
从上层传递到下层
父组件
)将数据传递给小组件(子组件
)Vue
官方提到 props
向子组件传递数据事件
向父组件发送消息父子组件数据传递?
子组件是不能访问父组件的数据的
父组件传递
如何传递数据
v-bind 传递数据
传递格式
v-bind:自定义接收名称 = "要传递数据"
在子组件中通过props 接收数据
接收格式
props: ["自定义接收名称"]
props
来声明需要从父级
接收到的数据props
的值有两种方式: 字符串数组
数组中的字符串就是传递时的名称
对象
对象可以设置传递时的类型,也可以设置默认值等
显示信息:{ {message}}
props
选项是使用一个数组
数组
之外,我们也可以使用对象
,当需要对props
进行类型等验证
时,就需要对象
写法验证
都支持哪些数据类型呢? String
Number
Boolean
Array
Object
Date
Function
Symbol
自定义构造函数
时,验证也支持自定义的类型
vue.component('my-component',{ props: { // 基础的类型检查(`null`匹配任何类型) propA: Number, // 多个可能的类型 propB: [String,Number], // 必填的字符串 propC: { type: String, required: true }, // 带有默认值的数字 propD: { type: Number, default: 100 }, // 带有默认值的对象 propE: { type: Object, // 对象或数组默认值必须从一个工厂函数获取 default: function(){ return { message: 'hello' } } }, // 自定义验证函数 propF: { validator: function(value){ // 这个值必须匹配下列字符串中的一个 return ['success','warning','danger'].indexOf(value) !== -1 } } } })
function Person (firstName,lastName) { this.firstName = firstName this.lastName = lastName}vue.component('blog-post',{ props: { author: Person }})
驼峰处
用-
代替{ {cInfo}}
{ {childMyMessage}}
const cpn = { template: '#cpn', props: { cInfo: { type: Object, default() { return { } } }, childMyMessage: { type: String, default: '' } } }
父子组件方法传递?
子组件是不能访问父组件的方法的
通过父组件传递
如何传递方法
v-on
传递方法传递格式
v-on:自定义接收名称 = "要传递方法"
在子组件中自定义一个方法
this.$emit('自定义接收名称');
触发传递过来的方法注意点
如果传递的是方法, 那么在子组件中不需要接收
需要在子组件中自定义一个方法
在子组件中直接使用自定义的方法
即可在子组件自定义的方法中通过this.$emit("自定义接收的名称")的方法
来触发父组件传递过来的方法father
son
如何将子组件数据传递给父组件
父组件的方法传递给子组件
子组件中调用父组件中的方法
在调用方法的时候给方法传递参数
传递的参数, 就是我们需要传递的数据
子组件传递数据或事件到父组件中
自定义事件
来完成v-on
不仅仅可以用于监听DOM
事件,也可以用于组件间的自定义事件
自定义事件的流程
子组件
中,通过$emit()
来触发事件父组件
中,通过v-on
来监听子组件事件点击次数:{ {total}}
如果儿子想使用爷爷的数据, 必须一层一层往下传递
如果儿子想使用爷爷的方法, 必须一层一层往下传递
{
{name}}{
{gfname}}{
{fname}}
父组件直接访问子组件
,子组件直接访问父组件
,或者是子组件访问根组件
父组件访问子组件
:使用$children
或$refs
reference(引用)子组件访问父组件
:使用$parent
$children
的访问 this.$children
是一个数组
类型,它包含所有子组件对象
message
状态我是子组件1
我是子组件2
Vue.component('parent-cpn',{ template: '#parentCpn', methods: { showChildCpn() { for(let i = 0; i < this.$children.length; i++) { console.log(this.$children[i].message) } } }}
$children
的缺陷: $children
访问子组件时,是一个数组类型
,访问其中的子组件必须通过索引值
子组件过多
,我们需要拿到其中一个时,往往不能确定它的索引值
,甚至还可能会发生变化其中一个特定的组件
,这个时候就可以使用$refs
$refs
的使用: $refs
和ref
指令通常是一起使用的
ref
给某一个子组件绑定一个特定的ID
this.$refs.ID
就可以访问到该组件showRefsCon() { console.log(this.$rsfs.child1.message); console.log(this.$rsfs.child2.message);}
子组件中直接访问父组件
,可以通过$parent
注意事项
Vue
开发中,我们允许通过$parent
来访问父组件,但是在真实开发中尽量不要这样做
子组件应该尽量避免直接访问父组件的数据
,因为这样耦合度太高
$parent
直接修改父组件的状态,那么父组件中的状态将变得飘忽不定,很不利于调试和维护
Vue.component('parent-cpn',{ template: '#parentCpn', data() { return { message: '我是父组件‘ } }, components: { 'child-cpn': { template: '#childCpn', methods: { showParent() { console.log(this.$parent.message); } } } }})
非父子关系
呢?非父子组件关系
包括多个层级的组件,也包括兄弟组件
的关系Vue1.x
的时候,可以通过$dispatch
和$broadcast
完成 $dispatch
用于向上级派发事件$broadcast
用于向下级广播事件Vue2.x
都被取消了Vue2.x
中,有一种方案是通过中央事件总线
,也就是一个中介来完成 Vuex
的状态管理方案还是逊色很多Vuex
提供了更多好用的功能不会被渲染
的子组件中有部分内容是使用时才确定
的, 那么我们就可以使用插槽
插槽就是在子组件中放一个"坑", 以后由父组件来"填"
slot
翻译为插槽
目的
是让我们原来的设备具备更多的扩展性
组件的插槽
封装
的组件更加具有扩展性
导航栏
nav-bar
组件复用
了 抽取共性,保留不同
将共性抽取到组件中,将不同暴露为插槽
预留插槽
,就可以让使用者根据自己的需求
,决定插槽中插入什么内容
slot
? <slot>
就可以为子组件开启一个插槽
该插槽插入什么内容取决于父组件如何使用
<slot>
中的内容表示,如果没有在该组件中插入任何其他内容,就默认显示该内容
我是替换插槽的内容
我是一个插槽的默认内容
指定名称
的, 默认情况下如果没有指定名称, 我们称之为匿名插槽
匿名插槽
, 会利用使用者指定的内容替换整个插槽
指定默认数据
没有填这个坑
, 那么就会显示默认数据
填了这个坑
, 那么就会利用使用者填坑的内容替换整个插槽
匿名插槽的特点
有多少个匿名插槽, 填充的数据就会被拷贝几份
只写一个匿名插槽
我是追加的内容1我是追加的内容2我是追加的内容3我是头部我是默认数据 我是底部
这导致了所有插槽中填充的内容都是一样的
不同的插槽中填充不同的内容
怎么办呢?具名插槽
name属性
给插槽指定名称
slot="name"
方式, 指定当前内容用于替换哪一个插槽
注意点
如果没有指定要替换哪个插槽中的内容, 则不会被替换
标题 左边 中间 右边
v-slot 指令
是Vue2.6中用于替代 slot 属性
的一个指令 slot属性
告诉Vue当前内容填充到哪一个具名插槽v-slot指令
告诉Vue当前内容填充到哪一个具名插槽注意点
v-slot 指令只能用在template标签上
可以使用#号替代v-slot:
我是追加的内容1我是追加的内容11我是追加的内容2我是追加的内容22我是头部我是one默认内容 我是two默认内容 我是底部
带数据的插槽
让父组件在填充子组件插槽内容时也能使用子组件的数据
slot
中通过 v-bind:数据名称="数据名称"
方式暴露数据
父组件
中通过 <template slot-scope="作用域名称">
接收数据
父组件
的<template></template>
中通过 作用域名称.数据名称
方式使用数据
{ {name}} 我是头部 { {names}}我是默认内容 { {names}} 我是底部
具名插槽
和作用域插槽
引入了一个新的统一的语法 (即 v-slot 指令
)v-slot 指令取代了 slot 和 slot-scope
v-slot指令
告诉Vue内容要填充到哪一个具名插槽中
v-slot指令
告诉Vue如何接收作用域插槽暴露的数据
v-slot:插槽名称="作用域名称"
{ {name}} 我是头部 { {names}}我是默认内容 { {names}} 我是底部
转载地址:http://tjqwi.baihongyu.com/