组件components
组件的组织:通常一个应用会以一棵嵌套的组件树的形式来组织:
定义组件
<script>
const step = {
template:`<div><button @click="n--">-</button>{{n}}<button @click="n++">+</button></div>`,
data(){return {n:1}}
}
</script>
注册组件
const app = Vue.createApp({
components:{step}
})
使用组件
<body>
<step></step>
<step></step>
</body>
结果
props传递参数
传递
<step :num="10"></step>
<step :num="5"></step>
接收
props:{
"num":{type:Number,default:1}
},
使用
data(){return {n:this.num}}
完整代码:
<body>
<div id="app">
<step :num="10"></step>
<step :num="5"></step>
</div>
<script type="text/javascript">
const step = {
template: `<div><button @click="n--">-</button>{{n}}<button @click="n++">+
</button></div>`,
//使用数据
data() { return { n: this.num } },
//接收数据
props: {
"num": { type: Number, default: 1 }
},
}
Vue.createApp({
components: { step },
data() {
return {
}
}
}).mount("#app")
</script>
</body>
页面显示结果:
组件的插槽(嵌套)
和 HTML 元素一样,我们经常需要向一个组件传递内容
我们使用 <slot> 作为我们想要插入内容的占位符 :
<step>
你好,我是嵌套内容
</step>
template:`<div><h1>组件的标题</h1><slot></slot></div>`
作用域插槽
有时让插槽内容能够访问子组件中才有的数据是很有用的。
当一个组件被用来渲染一个项目数组时,这是一个常见的情况,我们希望能够自定义每个项目的渲染方式。
<body>
<div id="app">
<step>
<!-- 自定义格式化渲染 子组件的数据 -->
<!-- 插槽传递过来的数据用scope变量接收 -->
<template v-slot:default="scope">
<i class="fas fa-check">{{scope.index}}</i>
<span class="green">{{ scope.item }}</span>
</template>
</step>
</div>
<script type="text/javascript">
const step = {
template: `<ul><li v-for="( item, index ) in list">
<slot :item="item" :index="index"></slot>
</li></ul>`,
data() { return { list: ["vue", 'react', 'angular'] } }
}
Vue.createApp({
components: { step },
data() {
return {
}
}
}).mount("#app")
</script>
</body>
结果:
动画transition
Vue 提供了内置的过渡封装组件,该组件用于包裹要实现过渡效果的组件。
组件进入和离开 DOM 的钩子 使用内置的 <transition> 组件
<button @click="flag=!flag">切换</button> <br>
<transition name="fade">
<img src="./images/sun.jpeg" alt="" width="120" v-if="flag">
</transition>
在进入/离开的过渡中,会有 6 个 class 切换。
v-enter-from 进入开始 v-enter-to 进入结束 v-enter-active进入整个状态
v-leave-from 离开开始 v-leave-to 离开结束 v-leave-active离开整个状态(类名为固定模式v可改)
可以自己添加样式
<style>
/* 整个进入的过程 整个离开的过程都拥有这两个类 */
.fade-enter-active,.fade-leave-active{
transition: all ease 1s;
}
/* 进入结束的class */
.fade-enter-to{
opacity: 1;
}
/* 进入开始的状态class */
.fade-enter-from{
opacity: 0;
}
/* 离开开始的状态 */
.fade-leave-from{
opacity: 1;
}
/* 离开结束的状态 */
.fade-leave-to{
opacity: 0;
}
</style>
动画-使用关键帧动画
与css一样定义关键帧:
<style>
@keyframes fadeIn{
from{opacity: 0;}
to{ opacity: 1;}
}
@keyframes fadeOut {
0%{ opacity: 1;}
100%{ opacity: 0;}
}
</style>
使用时需要对应类名:
.fade-enter-active{ animation: fadeIn ease 1s;}
.fade-leave-active{ animation: fadeOut ease 1s;}
动画模式
mode="out-in" in-out 先进在出,out-in先出在进
<transition mode="out-in" enter-active-class="animated slideInLeft" leave-active-class="slideOutRight animated">
<button key='a' v-if="flag">A</button>
<button key='b' v-else>B</button>
</transition>
列表过渡
我们会使用 <transition-group> 组件实现列表过渡
<transition-group tag="div" name="slide" >
<div class="item" v-for="item in undoList" :key="item.name">
.....
</transition-group>
<style>
.slide-leave-active{
animation: slideOut ease 1s;
position: absolute;
}
/* transition-group 正在移动中的类名 */
/* 移动中的元素 */
.slide-move{
transition: all ease 1s;
}
</style>
模板引用
ref
可以使用 ref attribute 为子组件或 HTML 元素指定引用 ID
<input type="text" ref="inp">
<body>
<div id="app">
<input type="text" ref="inp"><button @click="say">获取</button>
</div>
<script>
Vue.createApp({
methods: {
say(){
// 获取input标签的文本 refs所有的ref inp对应
var str = this.$refs.inp.value
alert(str)
}
},
}).mount("#app")
</script>
</body>