1.Event 深入
@click
单击事件可以绑定到标签上,但绑定到 组件上是没有反应的,需要添加.native
,即 @click.native
来触发原生DOM
事件
App.vue
文件
<template>
<div>
<button @click="handler">原生事件</button>
<Event1 @click="handler2"></Event1>
</div>
</template>
<script>
import Event1 from "./components/Event1.vue";
export default {
name: "App",
components: {
Event1,
},
methods: {
handler() {
console.log("原生的单击事件触发了");
},
handler2() {
console.log("组件的单击事件触发了");
},
},
};
</script>
<style></style>
Event1.vue
文件
<template>
<div>
<h1>我是h1 标签</h1>
<span>我是span</span>
</div>
</template>
<script>
export default {
name: "Event1",
};
</script>
<style scoped>
div {
background-color: #ccc;
}
</style>
可以看到 绑定到组件上并没有什么反应,这种绑定到组件上的事件,如果不加 .native
都是自定义事件
下面是加了.native
后
<!-- 加了 .native就变成原生的DOM 事件 -->
<Event1 @click.native="handler2"></Event1>
这种加了.native
实际上就是绑定到了 <template>
下面的 根<div>
,因为我们不管点击哪一块区域都会触发事件,
即给子组件的根节点绑定了点击事件—利用到事件委派
如果 我们绑定 @click
事件 又不想使用 .native
来触发事件,就需要使用到 $emit
来触发自定义事件了
使用方式如下:
在Event1
组件中绑定自定义事件
Event1.vue
<template>
<div>
<h1>我是h1 标签</h1>
<span>我是span</span>
<button @click="$emit('click','我是参数')">我是Event1 组件中的button按钮</button>
</div>
</template>
App.vue
<template>
<div>
<button @click="handler">原生事件</button>
<Event1 @click="handler2"></Event1>
</div>
</template>
<script>
import Event1 from "./components/Event1.vue";
export default {
name: "App",
components: {
Event1,
},
methods: {
handler() {
console.log("原生的单击事件触发了");
},
handler2(params) {
console.log("组件的单击事件触发了",params);
},
},
};
</script>
<style></style>
2.v-model 深入
v-model
的正常使用
v-model
的原理就 :value + @input
的结合使用
父子组件通信也可以利用v-model
实现
父组件
给子组件标签一个是传过去的数据,一个是自定义事件,注意:原生事件的$event
是事件对象,但是我们给组件使用的事件是 自定义事件 所以$event
是那边传过来的数据(参数)
子组件
在子组件这边才是真正的单向绑定value
➕input
事件
上面的写法可以简化为如下:
<!-- <vmodel :value="msg" @input="msg = $event" /> -->
<vmodel v-model="msg" />
结合上述内容,我们可以看到 很多组件库都大量应用到了v-model
,举例:
3.属性修饰符sync
要让父子数据同步,实现父子数据通信,以前的方法,采用props
传过来数据,再来一个自定义事件,在子组件修改这个数据并回传数据给父组件,其原理跟v-model
的实现原理很类似
父组件
子组件
使用 .sync
修饰符,加在传过来的数据后面,这样一加有两个作用,一个是props过来了一个数据,你可以接受,一个是会给你自动加上一个update
开头后面取决于你的数据名叫什么的自定义事件
4.$attrs 和 $listeners
封装一个button
组件,并且具备鼠标移入会有提示功能。
父组件
子组件
子组件不必使用props
一个一个来进行传递 父组件的属性,可以利用v-bind="$attrs"
(绝对不能是简写形式)
效果如下:
$attrs
是绑定 父给子的属性,而$listeners
则是 绑定 父给子 的自定义事件
使用方式:v-on="$linteners"
,同样不能是简写形式
父组件
子组件接收,不用一个一个进行 $emit
触发 只需要原样传递给elementui
的 el-button
即可
5. $children和 $parent
实现功能,父组件 App.vue
点击了 按钮后,子组件的数据要同步更改
例如。点击 找儿子借200
后,App.vue
中的数据增加200
,son.vue
中的数据,减少200
方式一: 利用ref
来实现,ref
给原生DOM
是获取这个DOM
节点,但是给到组件标签就会获取到这个vc实例组件实例对象
方式二:利用 $children
获取当前组件下的所有 子组件,以数组的形式展示,里面是每一个vc实例,l例如:当前组件为App.vue
,子组件为 son.vue
和daughter.vue
注意虽然是数组,但是最好不要用下面的形式来写,因为它里面的每个组件实例对象是不按顺序来的,你也不知道哪个是第一个
$parent
的使用 :当我们点击子组件里面的借钱,子组件会增加200
,同时父组件减少200
,这个时候也用到一个api
,$parent
可以获取到当前组件的父组件
6.混合 mixins
当我们结构一样那就是复用,当我们js
一样那就是mixin
混合
先复习一下混合,一个单独的文件夹,一个js文件,里面直接暴露相同的配置项,只要是能写在js
里面的都可以放进来,比如这里son.vue
和daughter.vue
都有相同的methods
,看下图
抽取 methods
在son.vue
和 daughter.vue
中使用mixins
配置混入,注意,是数组写法,但不需要引号
tip:混入 分为 全局混入和局部混入
下图为全局混入:
他们的执行顺序为,全局混入—>局部混入—>组件自身的方法 例如上图中我们抽取了 formFather()
,假设 我们在全局,局部,组件都有一个formFather()
方法,那么最终以组件自身的formFather()
为主,因为组件在执行顺序的最后
7.插槽
7.1 默认插槽
7.2 具名插槽
顾名思义,具有名字的插槽
7.3 作用域插槽(重点)scope-slot
作用域插槽:子组件的数据来源于父组件,但是子组件决定不了自身结构与外观。
子组件接收到父组件的数据后,需要回传给父组件,父组件来决定 结构 和样式