浅谈插槽和修饰符
程序员文章站
2022-05-15 17:38:49
...
事件修饰符
- @click.stop=“事件处理函数”
- 作用:阻住事件冒泡的修饰符
- @link.prevent=“事件处理函数”
- 作用:阻住a链接的跳转(自动跳转),表单的提交按钮(自动刷新)
- @click.capture=“事件处理函数”
- 默认的情况下:事件处于冒泡阶段(事件冒泡和捕获只能存在一个)
- 作用: @click.capture 使得事件处于捕获阶段! 于是先打印 我是爸爸 然后打印 我是儿子
- @click.once = “事件处理函数”
- 作用:添加了这个之后,事件只能触发一次
- @click.self=“事件处理函数”
- 作用:只当事件在改元素本身(比如不是子元素)触发时触发回调
阻住冒泡事件
<div id="app">
<div class="father" @click="fatherClick">
<div class="son" @click.stop="sonClick">
</div>
</div>
</div>
<script src="../vue.js"></script>
<script>
//分析:对父亲和儿子两个盒子绑定相同的事件,存在冒泡事件,点击子元素的时候,会冒泡到父元素!
//解决冒泡事件: @click.stop= "事件处理函数" 这是给子元素添加的,防止冒泡上去!
let data = {
msg1: "父亲",
msg2: "儿子"
}
let methods = {
fatherClick() {
alert("我是父亲")
},
sonClick() {
alert("我是儿子")
}
}
const vm = new Vue({
el: "#app",
data,
methods
})
</script>
阻住a链接的跳转,或者表单的提交(存在自动刷新)
<div id="app">
<a href="http://www.baidu.com" @click.prevent="links">去百度</a>
<form action="" @click.prevent="postSubmit">
<input type="text" name="username">
<input type="text" name="pwd">
<input type="submit" value="提交按钮">
</form>
</div>
<script src="../vue.js"></script>
<script>
let date = {
}
let methods = {
links() {
console.log("我要去百度"); //原本要跳转到百度的,只不过使用了事件修饰符,就阻住了!
},
postSubmit() {
console.log("表单提交被阻住"); //原本点击会提交,把表单的name属性值当做参数传递过去 阻住后就打印:表单提交被阻住
}
}
const vm = new Vue({
el: "#app",
date,
methods
})
</script>
事件捕获
<div id="app">
<div class="father" @click.capture="Fclick">
<div class="son" @click=Sclick></div>
</div>
</div>
<script src="../vue.js"></script>
<script>
//默认的情况下:事件处于冒泡阶段(事件冒泡和捕获只能存在一个)
//添加了 @click.capture 使得事件处于捕获阶段! 于是先打印 我是爸爸 然后打印 我是儿子
let data = {
son: "我是儿子",
father: "我是爸爸"
}
let methods = {
Fclick() {
console.log(this.father);
},
Sclick() {
console.log(this.son);
}
}
const vm = new Vue({
el: "#app",
data,
methods
})
</script>
Vue插槽
- 作用:就是占据一个位置,然后使用者可以根据自己需求,去显示相应的内容!
- 组件插槽:
- 组件插槽是为了让我们组件封装的时候,更具有扩展性
- 让使用者可以决定组件内容是以什么内容显示!
简单的插槽使用
- 需求:
- 1:定义一个组件,上面和中间固定,下面预留一个位置,根据需求,显示
- 显示按钮 显示我是右侧 显示我是段落
- 1:定义一个组件,上面和中间固定,下面预留一个位置,根据需求,显示
<body>
<div id="app">
<com-a>
<button>按钮</button>
</com-a>
<com-a>
<p>我是右侧</p>
</com-a>
<com-a>
<p>我是段落</p>
</com-a>
</div>
<script src="../vue.js"></script>
<script>
Vue.component("comA", {
template: `
<div>
<h1>我是组件comA</h1>
<p>我是左侧</p>
<p>我是中间</p>
<slot></slot>
</div>
`
})
new Vue({
el: "#app",
data: {},
})
</script>
默认插槽的使用
-
就是一个插槽内,若是有着多个默认显示的内容,比如一个按钮,那么就需要默认插槽了!
- 在slot标签里面,自定义一个按钮,显示按钮内容,这样的话,在使用的时候,你没有添加标签去替换的话,那么就显示默认插槽
- 注意点:就是在引用组件的时候,若是里面有很多标签,那么都会直接替换掉这个slot插槽 || 默认插槽
-
需求:
<body>
<div id="app">
<com-a>
<p>我是右侧</p>
</com-a>
<com-a>
<p>我是段落</p>
<p>我是段落2</p>
<button>我是按钮</button>
</com-a>
</div>
<script src="../vue.js"></script>
<script>
// <slot>
// 默认插槽:若是引用组件的时候,没有添加替换的内容,那么就显示按钮
// <button>按钮</button>
// </slot>
// 注意点:就是在引用组件的时候,若是里面有很多标签,那么都会直接替换掉这个slot插槽 || 默认插槽
// <slot></slot>
Vue.component("comA", {
template: `
<div>
<h1>我是组件comA</h1>
<p>我是左侧</p>
<p>我是中间</p>
<slot>
<button>按钮</button>
</slot>
<slot></slot>
</div>
`
})
new Vue({
el: "#app",
data: {},
})
</script>
具名插槽的使用
- 需求:封装一个具名插槽,可以根据需求,替换左侧 替换中间 替换右侧等!
<body>
<div id="app">
<com-a></com-a>
<com-a>
<span slot="left">我是替换左侧</span>
</com-a>
<com-a>
<input slot="center" value="我是替换中间"></input>
</com-a>
<com-a>
<button slot="right">我是替换右侧</button>
</com-a>
<template v-slot:left="slotProp">
<span>{{slotProp.title}}</span>
</template>
</div>
<script src="../vue.js"></script>
<script>
Vue.component("comA", {
template: `
<div>
<slot name="left">左侧</slot>
<slot name="center">中间</slot>
<slot name="right">右侧</slot>
</div>
`
})
new Vue({
el: "#app",
data: {
slotProp: "我是!!!"
},
})
</script>
作用域插槽
- 作用:子组件内数据可以被父页面拿到(解决了数据只能从父页面传递给子组件)
编译时的作用域
- 所谓作用域:就是假设在app这个引用 子组件后,是在app这个组件内执行的,那么变量的作用域就是在app这个组件之中,会在app中的data查询数据,而不是去子组件之中!
- 这个isShow是根据 父组件中的isShoe变量来决定显示还是隐藏的 vm.isShow=false 在浏览器之中修改后,隐藏了!
<div id="app">
<!-- 这个isShow是根据 父组件中的isShoe变量来决定显示还是隐藏的 vm.isShow=false 在浏览器之中修改后,隐藏了! -->
<!-- 所谓作用域:就是在app这个引用 子组件后,是在app这个组件内执行的,那么变量的作用域就是在app这个组件之中,去app中的data查询数据 -->
<com-a v-show="isShow"></com-a>
</div>
<script src="../vue.js"></script>
<script>
const comA = {
template: `
<div>
<p>我是子组件</p>
<button v-show="isShow"></button>
</div>`,
// 在这边 button是不会显示的,因为在子组件作用域之中 isShow为false
data() {
return {
isShow: false
}
}
}
const vm = new Vue({
el: "#app",
data: {
isShow: true
},
components: {
comA
}
})
</script>
作用域插槽 之旧版本
- 子组件向父组件传值,但是父组件想要根据需求,展示自己的样式,那么就需要作用域插槽来实现数据的传递和修改!
<div id="app">
<com-a></com-a>
<!-- 根据需要 就子组件展示的内容 需要作出调整的时候,那么需要使用要作用域插槽了! -->
<com-a>
<!-- 使用template 来获取子组件的数据 slot-scope来拿去slot插槽 slot.data => slot自定义属性的数据-->
<template slot-scope="slot">
<!-- 遍历插槽slot自定义的属性 里面含有数据! -->
<span v-for="item in slot.data.join('-')">{{item}}</span>
</template>
</com-a>
<com-a>
<!-- 使用template 来获取子组件的数据 slot-scope来拿去slot插槽 slot.data => slot自定义属性的数据-->
<template slot-scope="slot">
<span v-for="item in slot.data.join('*')">{{item}}</span>
</template>
</com-a>
</div>
<script src="../vue.js"></script>
<script>
const comA = {
// 子组件 自定义属性 向父组件传递数据
template: `
<div>
<slot :data="dataList">
<ul>
<li v-for="item in dataList">{{item}}</li>
</ul>
</slot>
</div>`,
data() {
return {
dataList: ["ppp", "www", "ccc", "aaa"]
}
}
}
const vm = new Vue({
el: "#app",
data: {
isShow: true
},
components: {
comA
}
})
</script>
插槽 之新版本
- 官网:
https://cn.vuejs.org/v2/guide/components-slots.html
默认插槽
<div id="app">
<com-a></com-a>
<com-a>
<template v-slot:default>
我要替换!
</template>
</com-a>
<!-- 输出的是
我是默认插槽
我要替换!-->
</div>
<script src="../vue.js"></script>
<script>
const comA = {
// 子组件 自定义属性 向父组件传递数据
template: `
<div>
<slot>
我是默认插槽
</slot>
</div>`,
}
const vm = new Vue({
el: "#app",
data: {
isShow: true
},
components: {
comA
}
})
</script>
具名插槽
<div id="app">
<com-a></com-a>
<com-a>
<template v-slot:left>
我要替换左侧!
</template>
</com-a>
<com-a>
<template v-slot:right>
我要替换右侧!
</template>
</com-a>
<!-- 结果:
左侧 中间 右侧
我要替换左侧! 中间 右侧
左侧 中间 我要替换右侧! -->
</div>
<script src="../vue.js"></script>
<script>
const comA = {
// 子组件 自定义属性 向父组件传递数据
template: `
<div>
<slot name="left">
左侧
</slot>
<slot name="center">
中间
</slot>
<slot name="right">
右侧
</slot>
</div>`,
}
const vm = new Vue({
el: "#app",
data: {
},
components: {
comA
}
})
</script>
作用域插槽
<div id="app">
<com-a></com-a>
<com-a>
<template v-slot:coma="slotProps">
<span v-for="item in slotProps.dataList.join(' - ')">{{item}}</span>
</template>
</com-a>
<com-a>
<!-- 定义一个作用域插槽 从coma组件拿数据 后面的slotProps 随意定义 只不过 通过这个slotProps 来拿到子组件的数据! -->
<template v-slot:coma="slotProps">
<span v-for="item in slotProps.dataList.join(' * ')">{{item}}</span>
</template>
</com-a>
</div>
<script src="../vue.js"></script>
<script>
const comA = {
// 子组件 自定义属性 向父组件传递数据 需要定义好这个子组件的name属性 便于从这个组件拿到数据
template: `
<div>
<slot name="coma" :dataList="dataList">
<ul>
<li v-for="item in dataList">{{ item }} </li>
</ul>
</slot>
</div>`,
data() {
return {
dataList: ["ppp", "www", "ccc", "aaa"]
}
}
}
const vm = new Vue({
el: "#app",
data: {
isShow: true
},
components: {
comA
}
})
</script>
上一篇: vue.js 常用指令用法
推荐阅读