vue的组件,通信,插槽及周小结
1:监听器:
{ 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 } } }
2:计算属性
使用一个值,需要处理一下才能使用
{ 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; } } } }
3:ref:获取dom
<div ref="box"> //实例的 $refs属性是一个对象 { box:div//dom对象 } this.$refs['box']
组件:
页面的独立 的区域\
1:全局组件
let CommonHead = { template:` <div> </div> ` data(){ return { } }, methods, watch, computed } Vue.component('组件名 推荐大驼峰或者 -',CommonHead)
2:局部组件
let CommonHead = { template:` <div> </div> ` data(){ return { } }, methods, watch, computed, components:{ 组件名:{ template, data, watch, .... } } }
## 组件间的关系
由于组件间的嵌套使用,组件互相有了关系 如:父子、兄弟...
## 不同组件之间的通信
1:父向子通信
子组件中 新增props属性,属性值,时数组,数组中 放 待接收参数列表(定义参数名字)
注意:
1,props中定义的参数名会自动 编译成 实例(组件),属性(同data中的属性以及计算属性中的属性)
2,props名字不能和data中以及methods和计算属性, 不能重名的
// 子组件 let CommonTitle = { props:['title','arr'], //properties props 父向子 传入的数据列表 template:` <div> 这是标题 <h2> {{ title }} </h2> <ul> <li v-for="item in arr" :key="item"> {{item}} </li> </ul> </div> ` } // 父组件 let Home = { template:` <div> <!-- <common-title title="我是首页"></common-title> --> <common-title :title="title" :arr="0"></common-title> home页内容 </div> `, 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
2:子向父通信
自定义事件 触发
子组件中
this.$emit("自定义事件名",携带参数)
在父组件中
<子组件
@自定义事件="fn"
></子组件>
{ methods:{ fn(msg){ //msg 携带数据 // 当子组件的 $emit触发时 自动调用 } } }
3:兄弟组件传参
事件总线
Vue实例
$emit("自定义事件",携带参数)
$on("监听的事件名",fn)
注意:
谁emit就由谁on监听
利用第三方实例,
emit
和
on监听
## 另外三种不常用通信 (用于面试)
### ref 通信
```
<child ref="child"/>
在父组件的
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:` <div> <h2>我是子组件</h2> 下面结构在不同的组件中使用 不一样 <slot></slot> </div> } //在父组件中 template:` <div> home页内容 <child> <!-- 子组件 自定义标签的内容 会自动 灌入 子组件内部的slot中 --> <h5> 我是插槽对应的内容 </h5> <p>aaa</p> </child> </div> `,
1:具名插槽 命名插槽
实现 可以在子组件中 定义多个插槽,且每个插槽,有自己名字(在传入代码时,指定传入哪个插槽
//子组件 { template:` <div> <h2>我是子组件</h2> <slot name="xm"></slot> <p>下面结构在不同的组件中使用 不一样</p> <slot name="xq"></slot> </div> ` } //父组件 { template:` <div> home页内容 <common-title> <div slot="xq"> slot属性 的值,对应插槽 name <button>我是小明</button> </div> <div slot="xm"> <h3>我是小明</h3> </div> </common-title> </div> ` }
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
<li v-for="item in arr"
:key="xx"
>
<li v-for="(item,index) in arr"
: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,根据 属性所 依赖的值 缓存,如果多次使用,依赖没有变化,计算属性不会重新调用

浙公网安备 33010602011771号