官网文档:组件使用v-model
v-model本质上是 value属性和input事件的一层包装
v-model的作用:提供数据的双向绑定
数据发生了改变,页面会自动变 v-bind:value
页面输入改变 , 数据会自动变化 v-on:input
v-model是语法糖, v-model等价于 给一个input框提供了 :value属性以及 @input事件
很显然如果每次使用input框,都需要提供value和input事件,比较麻烦,所以使用v-model
App.vue
根组件App.vue
我们经常遇到一种场景:
父组件提供一个数据给子组件使用(父传子)
子组件又需要修改父组件传过来的这个数据,所以需要子传父把值传给父组件。
这种场景可以使用v-model进行简写。
定义组件的时候,注意接收的值叫value, 子传父触发的事件叫 input
如果父传子的props值叫 value, 且 子传父触发的事件叫 input 。 那么这两个功能就可以使用v-model来简写
官方文档:API — Vue.js
ref作用:在vue中操作dom元素或组件vm实例
vue不推荐我们直接操作dom。如果真的要在vue中操作dom,可以使用ref语法
说人话 : vue不能直接操作dom,真的要操作也要按vue规定的语法来。(ref语法)
每个 vue 的组件实例上,都包含一个$refs 对象,里面存储着对应的DOM 元素或组件的引用。
ref语法使用流程语法
(1)给标签添加自定义属性red :
vue会自动把页面所有的ref属性,挂载到vue实例的$ref对象中
(2)通过
vm.$refs.属性名获取该标签
一定要注意: vue在mounted勾子中完成页面真实DOM渲染,所以最早能获取dom的就是mounted钩子
ref易错点
1.添加的的时候是:
ref2.获取的时候是:
$refs
1 给需要获取的 dom 元素或者组件, 添加 ref 属性
根组件App.vue
我是div盒子
2 通过 this.$refs.xxx 获取, 拿到组件可以调用组件的方法
子组件代码Goods.vue
我是子组件
需求1: 点击按钮, 切换显示输入框
需求2: 显示输入框的同时, 要获取焦点
当文本框展示出来之后,如果希望它立即获得焦点,则可以为其添加 ref 引用,并调用原生 DOM 对象的.focus() 方法即可。
直接调用会报错, 因为 vue 是 异步dom更新的 (提升渲染效率), this.showInput = true 执行完时, 实际的 dom 还没渲染出来
fn () {
this.isShowInput = true
this.$refs.inp.focus()
}
组件的 $nextTick(callback) 方法,会把 callback 回调推迟到下一个 DOM 更新周期之后执行。
通俗的理解是:等组件的DOM 刷新之后,再执行 callback 回调函数。从而能保证 callback 函数可以操作到最新的 DOM 元素。
什么是动态组件: 让多个组件使用同一个挂载点,并动态切换,这就是动态组件。
混淆点解读:动态组件 看起来和v-if v-else功能有些类似,但其实两者是不同的。
v-if v-else : 只是根据条件来决定渲染哪一个盒子,不能像组件那样复用。
动态组件:通过设置组件名,让一个挂载点可以切换不同的组件
App.vue
动态组件的演示
UserAccount.vue
UserInfo.vue
官方文档:自定义指令 — Vue.js
1.复习指令作用 : 给标签添加额外的功能
2.复习指令本质 : 行内自定义属性
3.自定义指令作用 : 给标签添加 vue没有的,额外的功能
局部注册:只能在当前组件使用
需求:
1.添加一个自定义指令 v-focus,作用是让input表单自动聚焦
2.添加一个自定义指令v-color,作用是设置标签文本颜色
根组件
我是p标签,我使用了自定义指令v-red
全局注册: 在main.js中注册,任何地方可用
// 全局指令 - 任何组件内"直接"使用
Vue.directive("focus", {
inserted(el) {
el.focus() // 触发标签的事件方法
}
})
插槽作用:
父组件 传递结构给子组件官网文档:
插槽使用2个步骤
第一步:在
子组件中定义一个插槽默认值:如果父组件没有传递则默认显示 第二步:在
父组件中传递结构:<子组件>父组件需要传递的结构子组件>
子组件goods.vue
我是子组件
商品名称
我是默认值
父组件App.vue
我是父组件
注意
插槽的作用是什么让父组件传递什么到子组件中?
html结构
插槽的默认值写哪里?
官方文档:具名插槽
1.插槽作用: 父组件 传递html结构 给子组件
给所有slot分发相同内容
2.具名插槽作用: 父组件 传递多个html结构 给子组件
给不同slot分发不同内容
具名插槽语法如下
1.给子组件的
添加name属性 : name="插槽名"2.父组件使用
v-slot:插槽名: 给指定的插槽传递结构
注意:这个v-slot指令必须要写在
标签中,否则会报错
是HTML5新增的一个语义化标签,模板的意思。 这个标签本身不会被渲染,因此最终在页面是看不见的。 这个标签类似于div,就是一个空盒子容器。 与div唯一的区别就是它不会渲染。
vue中并不是所有的指令都能简写,有简写符号的指令主要有三个
v-on 指令 可以简写成
@v-bind指令 可以简写成
:v-slot指令 可以简写成
#
课外思考? : 为什么具名插槽v-slot一定要写在
cell.vue
我是标题 我是内容 我是图标
App.vue
我是父组件
我是h3 标题内容 我是链接 |
官网文档:作用域插槽
1.插槽与props的异同点
相同点: 都是父传子
不同点:
props: 传递的是数据
插槽:传递的是html结构
2.作用域插槽和$emit异同点
相同点:都是子传父
不同点:
$emit : 子传父的数据通过事件来接收
作用域插槽:子传父的数据是通过插槽v-slot接收 (子传父的数据,只能给插槽用)
1.插槽作用:父组件 传递 html结构 给 子组件
2.具名插槽作用:父组件 传递 多个html结构 给 子组件
3.作用域插槽作用:父组件 给 子组件 传递插槽 时,可以使用子组件内部的数据
作用域插槽语法如下
1.给子组件的
添加一个自定义属性 : 2.给父组件的添加v-slot属性接收数据:
父组件使用子组件内部数据语法:
对象名.属性名
注意点: 不要把具名插槽语法和作用域插槽语法搞混淆具名插槽:
作用域插槽:
App.vue
{{ obj.a }}
{{ obj.b }}
{{ obj.c }}
scope.vue
学习作用域插槽
插槽默认内容
作用域插槽实际开发应用:Element - The world's most popular Vue UI framework
需求:
页面需要展示两个功能不同的表格
第一个表格:显示用户头像
第二个表格:显示删除按钮
给大家捋一下这个按钮完整流程是咋样的。(因为作用域插槽涉及到两个知识点:组件传值 + 插槽)
作用域插槽类似于 子传父,不同的是: 作用域插槽子组件传递数据,不是传给父组件的。而是传给父组件那个插槽的。(相当于只有插槽才能用子组件传递过来的数据)
(1) App.vue 有一个list数组
(2) 通过props父传子, 把App.vue的list传递给 student.vue的arr
(3) student.vue 渲染arr,把数组的数据渲染到页面表格中
(4)现在遇到问题了 : 有时候,student.vue组件希望表格的td能显示学生的头像。 有时候,student.vue组件希望表格的td能显示操作按钮 (同一个组件呈现不同的功能)
(5)怎么解决这个问题呢? : 使用插槽来解决
父组件App.vue 通过插槽把需要展示的结构 传递给 子组件student.vue
(6) 又遇到问题了。 图片的话,需要路径怎么办? 按钮的话,点击需要获取id怎么办?
因为这个v-for指令是在子组件里面用到的, 这个obj也是子组件内部的数据。 父组件App.vue肯定是拿不到的。(父组件只是把数组子组件了,至于子组件内部怎么处理,App.vue是不知道的)
(7)解决方案: 子组件在渲染td的时候,通过作用域插槽,把当前渲染的obj传递给父组件。 这样父组件在传递html结构的时候,就可以把obj里面需要用到的数据也一并放在html结构中,传递给子组件了。
作用域插槽本质: 子组件把自己当前数据 传递给 父组件插槽 。
只能父组件插槽内部使用,而不是任何地方都能用。作用域一词因此而来
App.vue
我是父组件
显示头像
头像 ![]()
显示操作按钮
操作
student.vue
序号 姓名 年龄 表头 {{ index+1 }} {{ item.name }} {{ item.age }} 内容