回顾
```
监听器:
{
data:{
msg:"",
obj:{
a:10,
b:20
}
},
watch:{
msg(newVal,oldVal){
// 只要 data中 msg 变化了,此函数自动触发
},
'obj.a'(newVal,oldVal){
// obj a属性值变化 触发
},
obj:{
handler(newVal,oldVal){
// 只要obj任意一个属性的值变化,都会触发
},
deep:true
}
}
}
计算属性
使用一个值,需要处理一下才能使用
{
data:{
msg:'hello world'
},
computed:{
msg2(){
return this.msg.split('').reverse().join('');
// 简写 相当于只用get
},
msg3:{
get(){
return this.msg.split('').reverse().join('');
},
set(val){
// 计算属性最好不要去修改
// 如果要修改,计算属性,需要些 set,在set中去修改依赖
this.msg = val;
}
}
}
}
ref:获取dom
实例的 $refs属性是一个对象
{
box:div//dom对象
}
this.$refs['box']
组件:
页面的独立 的区域
全局
let CommonHead = {
template:`
`
data(){
return {
}
},
methods,
watch,
computed
}
Vue.component('组件名 推荐大驼峰或者 -',CommonHead)
局部
let CommonHead = {
template:`
`
data(){
return {
}
},
methods,
watch,
computed,
components:{
组件名:{
template,
data,
watch,
....
}
}
}
```
## 组件间的关系
由于组件间的嵌套使用,组件互相有了关系 如:父子、兄弟...
## 不同组件之间的通信
### 父向子通信
props通信
```
子组件中 新增props属性,属性值,时数组,数组中 放 待接收参数列表(定义参数名字)
注意:
1,props中定义的参数名会自动 编译成 实例(组件),属性(同data中的属性以及计算属性中的属性)
2,props名字不能和data中以及methods和计算属性, 不能重名的
// 子组件
let CommonTitle = {
props:['title','arr'], //properties props 父向子 传入的数据列表
template:`
这是标题
{{ title }}
-
{{item}}
`
}
// 父组件
let Home = {
template:`
home页内容
`,
data(){
return {
title:"我是home页111"
}
},
components:{
CommonTitle
}
}
总结:
props值是一个数组
问题?
没有限制 props 传入的数据类型 (存在风险)
```
props验证
对于props类型做了验证
```
type
required
default
props:{
propa:String, //只验证type(类型)可以直接写类型预定义的值
propb:[String,Number] //type是多个类型中的一个 []
propc:{
type:String,
required:true
},
propd:{
type:String,
default:'xxx'
}
}
注意:
1,props中定义的参数名会自动 编译成 实例(组件),属性(同data中的属性以及计算属性中的属性)
2,props名字不能和data中以及methods和计算属性, 不能重名的
3,如果默认值是 数组或者对象,需要一个函数返回这个默认值
4,props能否被改变 props保持 单向的 父向子 (子不能改变),易于维护
type的值:
String
Number
Boolean
Array
Object
Date
Function
Symbol
```
### 子向父通信
自定义事件 触发
```
子组件中
this.$emit("自定义事件名",携带参数)
在父组件中
<子组件
@自定义事件="fn"
>子组件>
{
methods:{
fn(msg){ //msg 携带数据
// 当子组件的 $emit触发时 自动调用
}
}
}
```
### 兄弟组件传参
```
事件总线
Vue实例
$emit("自定义事件",携带参数)
$on("监听的事件名",fn)
注意:
谁emit就由谁on监听
利用第三方实例,
emit
和
on监听
```
## 另外三种不常用通信 (用于面试)
### ref 通信
```
在父组件的
this.$refs.child 就是这个子组件实例
注意:
不建议直接通过ref操作子组件
```
### $children $parent
```
$children 组件中 获取当前组件所有的子组件 (数组)
$parent 获取当前组件的父组件
```
### provide inject
```
父组件中
{
provide:{
msg:'1234',
num:12
},
data,
template,
methods
}
子组件中
{
inject:['msg','num']
// 挂载到了 子组件的 实例的 属性上 注意不要和data或者props或者计算属性或methods重名
}
```
## 插槽
占位符
实现 组件,在不同父组件中使用,内部可以有不一样 代码块(布局(html))
```
子组件
{
template:`
我是子组件
下面结构在不同的组件中使用 不一样
}
在父组件中
template:`
home页内容
我是插槽对应的内容
aaa
`,
具名插槽 命名插槽
实现 可以在子组件中 定义多个插槽,且每个插槽,有自己名字(在传入代码时,指定传入哪个插槽)
子组件
{
template:`
我是子组件
下面结构在不同的组件中使用 不一样
`
}
父组件
{
template:`
home页内容
我是小明
`
}
```
回顾:
```
mvvm 渐进式 前端 用于 构建用户界面的 js框架
mvvm
m v vm(数据改变视图自动刷新)
数据驱动
new Vue({
el:"#app", // 挂载vue 到html上
data:{
msg:123
},
methods:{
change(){
this.msg=""
}
}
})
{{}}
模板 在视图 渲染数据
1,js环境
2,里面的变量 或者 方法 自动去 寻找当前 视图 所在的组件这个实例的属性或者方法
3,js全局 变量或者方法 不通用 (白名单)
4,能写表达式 语句不行
指令:
v-model 表单值 与 实例中 某个数据进行双向绑定
.lazy 将 原来 input触发 改为change触发
.trim 去除首尾空格
.number 过滤成数字 (parseFloat)
v-html 解析富文本数据
v-bind:属性 属性的值 就会与 实例中的数据绑定
简写: :属性
v-on:事件 将原生事件,变成vue事件(事件函数 找实例上的方法)
@事件
事件对象
$event
修饰符
.stop 取消冒泡
.prevent 阻止 默认 行为
.capture 事件在捕获阶段就提前触发
.self 只能自己才能触发,后代元素无法触发
.once 只触发一次
总结:
指定 写法 是标签属性,注意:指令 引号中 引号中是一个js环境 可以写表达式
条件渲染
v-if
v-else (作为 if指令所在标签或者组件的下一个兄弟)
v-show
v-if v-show区别:
1,都是控制元素 显示隐藏
2,if移除元素 show display:none
3,初始值为false v-if是不加载
使用场景:
v-show适用于频繁切换
v-if适用于 初始不加载 (切换频率也不高)
列表渲染
v-for
:key="xx"
>
:key="xx"
>
mvvm原理
Object.defineProperty(target,属性,{
get(){},
set(){}
})
初始化一个实例(组件),vue会自动去遍历data中的所有的属性,用get/set劫持
加入 监听器,只要数据变化,set就会立即通知。监听者,自动调用render函数,生成新的虚拟dom,和上一次(每一次render调用都会缓存虚拟dom)虚拟dom进行比较,diff算法,最小程度操作dom
key:给每一层 虚拟dom节点,加了一个 标记(两个虚拟dom,就会按照,同一层同key进行比较)
侦听器
watch
{
data(){
return {
msg:12,
obj:{
a:10,
b:20
}
}
},
watch:{
msg(newVal,oldVal){
// 逻辑代码
},
"obj.a"(newVal,oldVal){
// 逻辑代码
},
obj:{
handler(newVal,oldVal){
// 逻辑代码
},
deep:true
}
}
}
计算属性
解决 在 模板中写过多业务逻辑
一个数据 使用时候需要处理一下,在使用
{
data(){
return {
msg:'hello world'
}
},
computed:{
msg2(){ //不修改 计算属性的值
return this.msg.split('').reverse().join("")
},
msg3:{
get(){
return this.msg.split('').reverse().join("")
},
set(val){
// val 设置计算属性的值,在这里去修改它的依赖
}
}
}
}
注意:
1,不要和data以及methods,props重名
2,根据 属性所 依赖的值 缓存,如果多次使用,依赖没有变化,计算属性不会重新调用
```