一.父传子
分析:
1.父组件传值给子组件,需要先找两个组件之间的关联
2.找关联为:组件的调用:<v-child></v-child>
<!-- 1.父传子: 父变,子变,子变,父不变.并且报错 -->
<input type="text" v-model="name">
<div>name的值为:{{name}}</div>
<!-- 2.解决父传子: 父变,子变,子变,父变. 需要传递一个Json-->
<div>父组件的name:{{user.name}}</div>
<!-- 父组件:通过自定义属性向子组件传值 -->
<input type="text" v-model="user.name">
<hr>
<input type="text" v-model="arr[1]">
<div>{{arr[1]}}</div>
<hr>
<!-- 3. 父传子: 父变,子不变,子变,父不变, 需要在子组件中将父组件传递的数据存入到新的人属性中-->
<input type="text" v-model="age">
<div>age的值为:{{age}}</div>
<v-child a="10" b="20" :name="name" :user="user" :arr="arr" :age="age"></v-child>
总结:
1.父组件: 通过自定义属性传递数据
2.子组件: 通过props接收父组件传递的数据
3.父传子: 父变,子变,子变,父不变.并且报错
4.解决父传子: 父变,子变,子变,父变. 需要传递一个Json
5.父传子: 父变,子不变,子变,父不变, 需要在子组件中将父组件传递的数据存入到新的人属性中
- props验证
- 常见数据类型:
Number
String
Array
Object
Boolean
- 常见数据类型:
// 需要做数据验证,props的值是一个json
props:{
name1:{
type:String,
required:true
},
age1:{
type:Number
},
sex1:{
type:String,
default(){
return '女'
}
}
}
二.子传父
子传父:
1.子组件: 通过自定义事件传递,数据, this.$emit('自定义事件名称',[要传递的参数])
2.父组件: 通过触发自定义事件来接收数据
<v-child2 @aa="change" @bb="change1($event)"></v-child2>
父组件:
<template>
<div class="box">
<h1>父组件</h1>
<div>name的值为:{{newName}}</div>
<v-child2 @aa="change" @bb="change1($event)"></v-child2>
</div>
</template>
<script>
import vChild2 from './child2.vue'
export default {
data(){
return {
newName:''
}
},
components:{
vChild2
},
methods:{
change(){
// console.log('事件被触发了');
this.newName = '王一博'
},
change1(name){
// console.log(name);
this.newName = name
}
}
}
</script>
子组件:
<template>
<div class="box">
<h1>子组件</h1>
<input type="text" v-model="name">
<!-- 子传父:需要通过事件传递 -->
<button @click="send">发送</button>
<button @click="send1">发送1</button>
</div>
</template>
<script>
export default {
data(){
return {
name:'王一博'
}
},
methods:{
send(){
// 需要往父组件中传递一个事件
this.$emit('aa')
},
send1(){
this.$emit('bb',this.name)
}
}
}
</script>
三.非父子通信
非父子之间通信有三种方式:
- eventBus A=>B A和B同时存在
- vuex状态管理 缺点:页面刷新之后数据消失
- 本地存储 localStorage sessionStorage
方式一:
main.js
Vue.prototype.event = new Vue;//eventBus
A.vue 通过触发自定义事件
send(){
// this.event就是vue实例
this.event.$emit('aa',this.name)
}
B.vue 挂载完成时监听自定义事件的触发
mounted(){
// 监听自定义事件
this.event.$on('aa',(e)=>{
// console.log(e);
this.name = e
})
}
四.is和ref
1.is
作用:is
用来解决标签固定搭配问题
<template>
<div>
<ul>
//一般我们的ul标签里面必须是li,这是一个固定的嵌套;但我们在这里可以柔和的去将其它的标签放在里面,这个时候我们就要用到is了
<li :is="comName"></li>
</ul>
</div>
</template>
<script>
import vOne from './one.vue'
export default {
data(){
return {
comName:'v-one'
}
},
components:{
vOne
}
}
</script>
<style>
</style>
2.动态组件
<!-- 动态组件 -->
<button @click="comName='v-one'">one</button>
<button @click="comName='v-two'">two</button>
<transition enter-active-class="animate__animated animate__bounceInDown">
<div :is="comName"></div>
</transition>
建议结合animate.css使用
步骤:
1.下载安装
npm i animate.css --save 或者 -S
2.引入animate.css
main.js
import 'animate.css'
3.使用
<transition enter-active-class="animate__animated animate__bounceInDown">
<div :is="comName"></div>
</transition>
3.scoped
是当前组件样式局部有效
<style scoped>
.pink{
background: blue;
color: red;
height: 30px;
line-height: 30px;
}
4.ref
ref被用来给元素或者子组件注册引用信息。引用信息将会注册在父组件的$refs上。如果是普通的DOM元素上使用,引用指向的就是DOM元素;如果用在子组件上,引用就指向子组件的实例。
- 在普通元素上使用ref
- 作用:获取当前元素,对元素进行操作
<template>
<div>
<button @click="change('green')">变绿</button>
<!--在普通元素上有一个ref属性,ref属性的值是自定义的 -->
<div class="red" ref="myDiv"></div>
</div>
</template>
<script>
export default {
methods:{
change(color){
// 将div的背景改成绿色
// console.log(this.$refs.myDiv);
this.$refs.myDiv.style.background = color;
}
}
}
</script>
<style scoped>
.red{
width: 100px;
height: 100px;
background: red;
}
</style>
- 在子组件上使用ref
- 作用:可以调用子组件的数据和方法
<template>
<div>
<button @click="change('green')">变绿</button>
<!--在普通元素上有一个ref属性,ref属性的值是自定义的 -->
<div class="red" ref="myDiv"></div>
<hr>
<!-- 在子组件上有一个ref属性,ref属性值是自定义 -->
<button @click="change1">one</button>
<v-one ref="myOne"></v-one>
</div>
</template>
<script>
import vOne from './one.vue'
export default {
methods:{
change(color){
// 将div的背景改成绿色
// console.log(this.$refs.myDiv);
this.$refs.myDiv.style.background = color;
},
change1(){
// console.log(this.$refs.myOne);
// this.$refs.myOne.name = '刘劲'
this.$refs.myOne.fn()
}
},
components:{
vOne
}
}
</script>
<style scoped>
.red{
width: 100px;
height: 100px;
background: red;
}
</style>
五.jquery
1.安装
npm i jquery --save
1.局部使用jquery
当前所使用的组件直接引入即可
<template>
<div>
<h1>jquery的使用</h1>
<button class="show">显示</button>
<button class="hide">隐藏</button>
<div class="green"></div>
</div>
</template>
<script>
// 局部引入
import $ from 'jquery'
export default {
mounted(){
// 使用jquery的三要素: 先获取 加事件 再操作
$('.show').click(()=>{
$('.green').slideDown(300)
})
$('.hide').click(()=>{
$('.green').slideUp(300)
})
}
}
</script>
<style scoped>
.green{
width: 200px;
height: 200px;
background: greenyellow;
}
</style>
2.全局使用jquery
在main.js中引入即可
// 引入jquery
import $ from 'jquery'
Vue.prototype.$ = $;
<template>
<div>
<h1>jquery的使用</h1>
<button class="show">显示</button>
<button class="hide">隐藏</button>
<div class="green"></div>
</div>
</template>
<script>
export default {
mounted(){
// 使用jquery的三要素: 先获取 加事件 再操作
// 全局使用
this.$('.show').click(()=>{
this.$('.green').slideDown(300)
})
this.$('.hide').click(()=>{
this.$('.green').slideUp(300)
})
}
}
</script>
<style scoped>
.green{
width: 200px;
height: 200px;
background: greenyellow;
}
</style>
六.插槽slot
1.匿名槽口
在子组件中留有插槽
<template>
<div>
<!-- 匿名插槽 -->
<p>今夕何夕</p>
<slot></slot>
</div>
</template>
2.具名槽口
在子组件中设置槽口的名字
<template>
<div>
<!-- 具名插槽 -->
<slot name="man"></slot>
<p>今天星期五</p>
<slot name="women"></slot>
</div>
</template>
父组件中使用具名插槽
<v-two>
<ul slot="man">
<li>刘劲</li>
<li>杨一</li>
<li>刘泽松</li>
<li>王达生</li>
</ul>
<ol slot="women">
<li>杨延琴</li>
<li>陶甜也</li>
<li>田文渊</li>
<li>苟燕</li>
</ol>
</v-two>
3.插槽的作用域
指外部向插槽内部传递数据
子组件中:通过自定义属性传递要遍历的数组
<template>
<div>
<ul>
<li v-for="item in arr" :key="item">
<!-- 在此处不展示数据,将数据给到父组件中,在父组件中展示数据 -->
<!-- 通过自定义属性传递数据 -->
<slot :row="item"></slot>
</li>
</ul>
</div>
</template>
<script>
export default {
data(){
return {
arr:['vue','react','angular']
}
}
}
</script>
<style>
</style>
在父组件中,通过slot-scope或者v-slot接受数据
<v-three>
<!-- 使用子组件给父组件传递的数据 -->
<!-- 原生写法 -->
<!-- <template slot-scope="data">
<p>{{data.row}}</p>
</template> -->
<!-- 现代写法 -->
<template v-slot="data">
<p>{{data.row}}</p>
</template>
</v-three>