书接上回:
所有组件写在src的components中
组件包含的主要内容:
1.组件传值
1.1父子传值(子调用父中的数据)
父子传值只要分为三大类:
1.父变子变 子组件直接通过props接收即可
2.子变父不变 但是子报错 把父组件传递过来的值在自己的mounted中进行重新复制,再渲染到页面即可解决
3.父变子变 子变父变 父组件传递json对象给子组件,子组件通过props接收后直接渲染即可
1.父变子变 子组件直接通过props接收即可
父组件写法:
<v-child :msg='msg'></v-child>
//这是子组件写法 通过prop接收 直接渲染到页面
props:['a','b','msg','json'],
2.子变父不变 但是子报错 把父组件传递过来的值在自己的mounted中进行重新复制,再渲染到页面即可解决
mounted(){
console.log(this.msg);
this.mydata = this.msg
}
3.父变子变 子变父变 父组件传递j对象给子组件,子组件通过props接收后直接渲染即可
data() {
return {
msg:'data',
json:{
name:'father',
age:20,
}
};
},
全部代码:
// 父组件
<template>
<div class="parent">
<p>這是父組件的数据:{{msg}} {{json.name}}</p>
{{msg}}
<input type="text" v-model='msg'>
<hr>
<v-child a='10' b="20" :msg='msg'></v-child>
<v-child :json='json'></v-child>
</div>
</template>
<script>
import vChild from './child'
export default {
components: {
vChild
},
data() {
return {
msg:'data',
json:{
name:'father',
age:20,
}
};
},
methods: {},
mounted() {},
};
</script>
<style>
.parent{
width: 400px;
padding: 20px;
border: 1px solid blue;
}
</style>
//子组件
<template>
<div>
这是子组件接受的父组件数据:{{mydata}}
<input type="text" v-model = 'msg'>
<hr>
<input type="text" v-model = 'mydata'>
<!-- <p>{{a}}{{b}}</p> -->
<div>这是传递的json</div>
<input type="text" v-model = 'json.name'>
</div>
</template>
<script>
// 总结:父传子:在父组件中定义,子组件通过props接收 然后子组件就可以使用
export default {
props:['a','b','msg','json'],
components:{
},
data () {
return {
mydata:''
}
},
methods:{
},
// 挂载完成
mounted(){
console.log(this.msg);
this.mydata = this.msg
}
}
</script>
<style scoped>
</style>
1.1.1父子传值案例
这里实现的是页面实现老师数据,每一个老师信息是一个组件。
1.拆分组件(需要确定哪些样式是固定的,哪些数据是活的)
2.父组件 a.需要引入对应子组件,把需要的所有数据放到父组件中,通过循环添加子组件的个数,需要拿到每一项数据
b.向子组件传值,渲染子组件样式,这个需要用到父子传值,子组件需要用props接收
父组件:以一个为例:
<template>
<div>
这是java讲师
<v-card v-for='item in teachers' :key='item.id' :teachers='item'></v-card>
<!-- <v-card></v-card>
<v-card></v-card> -->
</div>
</template>
<script>
import vCard from './card'
export default {
components:{
vCard,
},
data () {
return {
teachers:[
{
id:1,
img:'http://www.ujiuye.com/uploadfile/2019/0109/20190109110959719.jpg',
name:'张老师',
job:'java'
},
{
id:2,
img:'http://www.ujiuye.com/uploadfile/2019/0109/20190109105513572.jpg',
name:'李老师',
job:'java'
},
{
id:3,
img:'http://www.ujiuye.com/uploadfile/2019/0109/20190109105409469.jpg',
name:'杨老师',
job:'java'
},
{
id:4,
img:'http://www.ujiuye.com/uploadfile/2019/0516/20190516093549100.jpg',
name:'孙老师',
job:'java'
}
]
}
},
}
子组件:
<div class="card">
<img :src="teachers.img" alt="">
<p >{{teachers.name}}</p>
<p>{{teachers.job}}</p>
</div>
//js中:
props:['teachers'],
2.使用jquery
1.安装 npm i jquery --save
2.在mian.js中导入同时配置原型,是$为全局对象
3.在需要文件中直接import $ from 'jquery'
4.直接使用jq的方法
3.is使用
3.1解决标签的固定搭配问题
这里的li被替换成组件的内容
<ul>
<!-- 1.可以替换标签的固定搭配 -->
<li is='v-one'></li>
</ul>
3.2动态组件
v-one和v-two是组件名称
<button @click="name='v-one'">one</button>
<button @click="name='v-two'">two</button>
<div :is='name'></div>
js:
import vOne from './one'
import vTwo from './tow'
import $ from 'jquery'
export default {
components: {
vOne,
vTwo
},
data() {
return {
name:'v-one'
};
},
4.子传父
4.1子传父知识点
点击子组件的按钮,可以改变父组件中的内容
//子组件
<template>
<div>
this is child
//这里点击之后调用change方法
<button @click="change">修改父组件数据</button>
</div>
</template>
//方法
methods:{
//change方法去调用父组件中子组件调用时的方法。
change(){
this.$emit('addn')
}
},
<template>
<div>
<p>{{num}}</p>
//上面的change会调用这里的方法,这里会调用父组件中的add方法
<v-child @addn = 'add'></v-child>
</div>
add方法
methods:{
add(){
this.num++;
}
},
4.2子传父案例
实现点击显示遮罩层,点击遮罩层 会隐藏遮罩层 全程通过的是改变父组件中的show的值进行遮罩层的显示和隐藏。
代码:
// 显示页面
<template>
<div>
<h3>子传父案例</h3>
<button @click="show=true">点击弹框</button>
<v-mask v-if='show' @cancel = "show=false"></v-mask>
</div>
</template>
<script>
import vMask from './mask'
export default {
components:{
vMask
},
data () {
return {
show:false
}
},
methods:{
},
mounted(){
}
}
</script>
<style scoped>
</style>
// 遮罩层
<template>
<div class="mask" @click="cancel">
this is mask
</div>
</template>
<script>
export default {
components:{
},
data () {
return {
}
},
methods:{
cancel(){
this.$emit('cancel')
}
},
mounted(){
}
}
</script>
<style scoped>
.mask{
width: 100vw;
height: 100vh;
background: rgba(0,0,0,0.5);
position: fixed;
top: 0;
left: 0;
}
</style>
5.slot插槽
作用:可以展示组件标签内部的内容
5.1无名插槽
可以直接写
//无名插槽
<v-one>
我是从one过来的
</v-one>
5.2具名插槽
通过子组件的 ‘<slot name = "name1"></slot>’
标签,并且命名和父组件的<div slot="name1">我是我自己</div>
标签中设置slot属性机型设置。
可以实现显示在子组件的不同地方。
总结:如果使用具名插槽,所有内容均需要指定插槽名字,否则不展示 下列中的
我是后来的
不会展示具体代码如下
//子组件
<template>
<div>
<slot name = "name1"></slot>
<h2>我是h2</h2>
<slot name = "name2"></slot>
</div>
</template>
<script>
export default {
}
</script>
<style>
</style>
//父组件
<template>
<div>
<v-one>
<div slot="name1">我是我自己</div>
<div slot="name2">我还是我自己</div>
</v-one>
<!-- <v-two></v-two> -->
</div>
</template>
<script>
import vTwo from "./two"
export default {
components: {
vOne,
}
}
</script>
<style>
</style>
6.非父子传值
1.首先在vue的原型上增加一个自定属性(Event)
2.如果a组件想要给b组件传值,那么需要用$emit()绑定方法,在b中通过$on() 就行
3.此种方法需要手动触发才能传值
//这是a中
send(){
this.Event.$emit('sendA',this.data)
}
//这是b中
mounted() {
this.Event.$on("sendA", (e) => {
console.log(e);
this.amsg = e
});
},