1 作用域插槽
含义
作用域插槽就是父组件在调用子组件的时候给子组件传了一个插槽,这个插槽为作用域插槽,该插槽必须放在template标签里面,同时声明从子组件接收的数据放在一个自定义属性内,并定义该数据的渲染方式。通过下列展示作用域插槽的使用方式。
场景
多个相同子组件需要不同的渲染方式的情况下使用
注意
只要出现多个插槽,请始终为所有的插槽使用完整的基于 的语法
示例
<body>
<div id='app'>
<child>
<template v-slot:default='slotProps'>
<h1>{{slotProps.user.username}}</h1>
</template>
<template v-slot:other='slotProps'>
<h5>{{slotProps.user.username}}</h5>
</template>
</child>
</div>
<script>
Vue.component('child', {
data: function () {
return {
user: {
username: 'wust',
password: '456'
}
}
},
template: `
<div>
<slot v-bind:user='user'>{{user.password}}</slot>
<slot v-bind:user='user' name='other'>{{user.password}}</slot>
</div>
`
})
var vm = new Vue({
el: '#app',
data: {
user: {
username: 'ljs',
password: '123'
}
}
})
</script>
</body>
结果
动态插槽名
如果要使用动态插槽名,需要在父组件上和v-slot处做相应处理。比如给父组件的data增加一个dynamicname属性且值为other后,v-slot:[dynamicname]='slotProps’就会渲染出上例一样的效果。
2 过渡
2.1 过渡模式
以按钮滑动过渡为例
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>vue过渡模式</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<script src="vue.js"></script>
<style>
/* 1 仅仅透明度变化 2 滑动+透明度 */
/* .fade-enter-active,
.fade-leave-active {
transition: opacity 0.5s;
}
.fade-enter,
.fade-leave-to {
opacity: 0;
} */
.fade-enter {
transform: translateX(20px);
}
.fade-leave-to {
transform: translateX(-20px);
}
.fade-enter,
.fade-leave-to {
opacity: 0;
}
.fade-enter-active,
.fade-leave-active {
transition: all 1s;
}
</style>
</head>
<body>
<div id="app">
<transition name="fade" mode="out-in">
<button v-if="show" key="on" @click="show=!show">on</button>
<button v-else="" key="off" @click="show=!show">off</button>
</transition>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
show: true
}
})
</script>
</body>
</html>
2.2 多个组件过渡
采用动态组件实现
<style>
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.5s;
}
.fade-enter,
.fade-leave-to {
opacity: 0;
}
</style>
<div id='app'>
<input type='radio' name='choice' @click='view="childOne"' />A
<input type='radio' name='choice' @click='view="childTwo"' />B
<transition name='fade' mode='out-in'>
<component :is="view"></component>
</transition>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
view: 'childOne'
},
components: {
'childOne': {
template: '<div>childOne</div>'
},
'childTwo': {
template: '<div>childTwo</div>'
}
}
})
</script>
2.3 FLIP动画多维网格过渡
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.14.1/lodash.min.js"></script>
<style>
#wrapper {
display: flex;
flex-wrap: wrap;
width: 75px;
}
.cell {
width: 20px;
height: 20px;
padding: 1px;
border: 1px solid black;
display: flex;
justify-content: space-around;
align-items: center;
}
.fade-move {
transition: transform 1s;
}
</style>
<div id="container">
<button @click="shuffle">shuffle</button>
<transition-group name="fade" tag="div" id="wrapper">
<div class="cell" v-for="item in cells" :key="item.id">
{{ item.number }}
</div>
</transition-group>
</div>
<script>
new Vue({
el: '#container',
data: {
cells: Array.apply(null, {
length: 9
}).map(function(current, index) {
return {
id: index,
number: (index % 9) + 1
}
})
},
methods: {
shuffle: function() {
this.cells = _.shuffle(this.cells)
}
}
})
</script>
记录:
- 设置了flex布局之后发现还是单列形式,结果最后发现问题在于元素选择错误,把按钮也包括进去了。
- 这里cells的生成方式是比较规范的一种,Array.apply(null,{length:9}).map(function(current,index){return {id:index,number:index%9+1}}),采用Array.apply生成的数组与直接new Array()得到的数组是不一样的,后者只有length:9,相当于分配了空间,而前者却是0-8每个元素值都为undefined。