子组件补充
子组件案列
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset='UTF-8'>
<title>子组件案例</title>
<style>
.wrap {
width: calc(200px * 4 + 80px);
margin: 0 auto;
user-select: none;
}
.box {
width: 200px;
height: 360px;
/*border: 1px solid black;*/
background-color: rgba(10, 200, 30, 0.5);
border-radius: 10px;
float: left;
margin: 10px;
}
.box img {
width: 100%;
/*height: 200px;*/
border-radius: 50%;
/*width:10%;*/
/*height:15%;*/
float:right;
/*margin-left:20px;*/
}
.b1{
text-align: center;
}
</style>
</head>
<body>
<div id="app">
<div class="wrap"></div>
<my-tag1 ></my-tag1>
<my-tag2 ></my-tag2>
<my-tag3 ></my-tag3>
<my-tag4 ></my-tag4>
</div>
</body>
<script src="js/vue.js"></script>
<script>
let Title = {
template: `
<p class="b1">前女友</p>
`
};
let myTag1 = {
template:`
<div class="box">
<img src="img/111.jpg" alt="">
<Title></Title>
<p class="b1" @click="fn">抱了{{ num }}次</p>
</div>
`,
components: {
Title
},
data(){
return {
num: 0
}
},
methods:{
fn(){
this.num ++
}
}
};
let myTag2 = {
template:`
<div class="box">
<img src="img/222.jpg" alt="">
<Title></Title>
<p class="b1" @click="fn">抱了{{ num }}次</p>
</div>
`,
components:{
Title
},
data(){
return {
num: 0
}
},
methods:{
fn(){
this.num ++
}
}
};
let myTag3 = {
template:`
<div class="box">
<img src="img/333.jpg" alt="">
<Title></Title>
<p class="b1" @click="fn">抱了{{ num }}次</p>
</div>
`,
components:{
Title
},
data(){
return {
num: 0
}
},
methods:{
fn() {
this.num ++
}
}
};
let myTag4 = {
template:`
<div class="box">
<img src="img/444.jpg" alt="">
<Title></Title>
<p class="b1" @click="fn">抱了{{ num }}次</p>
</div>
`,
components:{
Title
},
data(){
return {
num: 0
}
},
methods:{
fn(){
this.num ++
}
}
};
new Vue({
el:'#app',
components:{
myTag1,
myTag2,
myTag3,
myTag4
}
})
</script>
</html>
案列二
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title></title>
<style>
.wrap {
width: calc(200px * 4 + 80px);
margin: 0 auto;
user-select: none;
}
.box {
width: 200px;
height: 260px;
/*border: 1px solid black;*/
background-color: rgba(10, 200, 30, 0.5);
border-radius: 10px;
float: left;
margin: 10px;
}
.box img {
width: 100%;
/*height: 200px;*/
border-radius: 50%;
}
.box p {
text-align: center;
}
</style>
</head>
<body>
<div id="app">
<div class="wrap">
<tag></tag>
<tag></tag>
<tag></tag>
<tag></tag>
</div>
</div>
</body>
<script src="js/vue.js"></script>
<script>
let titleTag = {
template: `
<p>
<b>
清纯妹
</b>
</p>
`,
};
let tag = {
template: `
<div class="box">
<img src="img/111.jpg" alt="">
<title-tag />
<p @click="fn">
锤它:<b>{{ num }}下</b>
</p>
</div>
`,
// 能被复用的组件(除了根组件),数据都要做局部化处理,因为复用组件后,组件的数据是相互独立的
// data的值为绑定的方法的返回值,返回值是存放数据的字典
data () {
return {
num: 0
}
},
methods: {
fn() {
this.num ++
}
},
components: {
titleTag,
}
};
new Vue({
el: '#app',
components: {
tag,
}
});
`
class P:
num = 0
def __init__(n):
this.n = n
p1 = P()
p2 = P()
P.num = 10
p1.num
p2.num
`
</script>
</html>
组件传参--父传子
数据交互--父传子--通过绑定属性的方式
1.父组件提供数据
2.在父组件模板中,为子组件标签设置自定义属性,且自定义属性绑定的值由父组件提供
3.在子组件实例中,用过props实例成员获得自定义属性,然后就可以使用父组件的数据
使用父组件的数据,在子组件的模板上进行渲染步骤流程:
1.先创建子组件;
2.在父组件中注册子组件(components)
3.在父组件模板中渲染出子组件,且为子组件标签设置自定义属性,自定义属性值由父组件提供
4.在子组件实例中,通过props实例成员获得自定义属性,便可使用父组件提供的数据
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset='UTF-8'>
<title>父传子</title>
<style>
.wrap {
width: calc(200px * 4 + 80px);
margin: 0 auto;
user-select: none;
}
.box {
width: 200px;
height: 260px;
/*border: 1px solid black;*/
background-color: rgba(10, 200, 30, 0.5);
border-radius: 10px;
float: left;
margin: 20px;
}
.box img {
width: 100%;
height: 160px;
border-radius: 50%;
margin: 0 auto;
display: block;
}
.box p {
text-align: center;
}
</style>
</head>
<body>
<div id="app">
<son v-for="photo in photos" v-bind:photo="photo"></son>
</div>
</body>
<script src="js/vue.js"></script>
<script>
let photos = [
{title: '女友1号', img:'img/111.jpg',},
{title: '女友2号', img:'img/222.jpg',},
{title: '女友3号', img:'img/333.jpg',},
{title: '女友4号', img:'img/444.jpg',},
{title: '女友1号', img:'img/111.jpg',},
{title: '女友2号', img:'img/222.jpg',},
{title: '女友3号', img:'img/333.jpg',},
{title: '女友4号', img:'img/444.jpg',},
];
let son = {
// 在组件内部就可以通过设置的自定义属性,拿到外部选择子组件提供给属性的的值
props:['photo'],
template: `
<div class="box">
<img :src="photo.img" alt="">
<p>{{ photo.title }}</p>
<p @click="fn">亲亲{{ num }}下</p>
</div>
`,
data(){
return{
num: 0
}
},
methods:{
fn(){
this.num ++
}
}
};
new Vue({
el:'#app',
data:{
photos,
},
components: {
son
}
});
/**
* 1.数据在父组件中产生
* 2.在父组件中渲染组件,子组件绑定自定义属性,附上父组件中的数据
* 3.子组件自定义属性在子组件中的props成员中进行声明(采用字符串发射机制)
* 4.在子组件内部,就可以用props声明的属性(直接作为变量)来使用父组件的数据
*/
</script>
</html>
<style>
.info {
text-align: center;
width: 200px;
padding: 3px;
box-shadow: 0 3px 5px 0 pink;
float: left;
margin: 5px;
}
.info img {
width: 200px;
}
</style>
<div id="app">
<!-- 2) 在父组件模板中,为子组件标签设置自定义属性,绑定的值由父组件提供 -->
<info v-for="info in infos" :key="info.image" :myinfo="info"></info>
</div>
<script src="js/vue.js"></script>
<script>
let infos = [
{
image: 'img/001.png',
title: '小猫'
},
{
image: 'img/002.png',
title: '蛋糕'
},
{
image: 'img/003.png',
title: '蓝糕'
},
{
image: 'img/004.png',
title: '恶犬'
},
];
//局部组件
let info = {
template: `
<div class="info">
<img :src="myinfo.image" alt="">
<p><b>{{ myinfo.title }}</b></p>
</div>
`,
// 3) 在子组件实例中,通过props实例成员获得自定义属性
props: ['myinfo']
};
//父组件
new Vue({
el: '#app',
components: {
info,
},
data: {
infos, // 1) 父组件提供数据
}
})
</script>
组件交互--子传父(由子组件传递数据)
组件交互--子传父
1.数据由子组件提供
2.子组件内部通过触发系统事件,发送一个自定义事件,将数据携带出来
3.父组件为子组件标签的自定义属性通过方法实现,就可以通过参数拿到子组件传递处理的参数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset='UTF-8'>
<title>作业</title>
<style>
.box {
width: 200px;
height: 260px;
/*border: 1px solid black;*/
background-color: rgba(10, 200, 30, 0.5);
border-radius: 10px;
float: left;
margin: 20px;
}
.box img {
width: 100%;
height: 160px;
border-radius: 50%;
margin: 0 auto;
display: block;
}
</style>
</head>
<body>
<div id="app">
<p><button @click="fn('tv')">电视</button></p>
<p><button @click="fn('phone')">手机</button></p>
<!--<div v-for="da in das">-->
<!--<img :src="da.img"/>-->
<!--<p>{{ da.title }}</p>-->
<!--</div>-->
<tag v-for="tv in das" :tv="tv" @change="changeFn"></tag>
<h2 style="color: red;">{{ index }}</h2>
</div>
</body>
<script src="js/vue.js"></script>
<script>
let ad_data = {
tv: [
{title: 'tv1', img:'img/111.jpg',},
{title: 'tv2', img:'img/222.jpg',},
{title: 'tv3', img:'img/333.jpg',},
{title: 'tv4', img:'img/444.jpg',},
],
phone:[
{title: 'phone1', img:'img/111.jpg',},
{title: 'phone2', img:'img/222.jpg',},
{title: 'phone3', img:'img/333.jpg',},
{title: 'phone4', img:'img/444.jpg',},
]
};
let tag = {
props: ['tv'],
template: `
// 1.点击触发子组件该事件
<div class="box" @click="choiceFn">
<img :src="tv.img" alt="">
<p>{{ tv.title }}</p>
</div>
`,
methods:{
choiceFn(){
// 2.自行触发,提供数据,将数据用事件形式传给父组件
// 注意:$emit()中第一个参数是自定义的属性名,不是函数名)
this.$emit('change',this.tv)
}
}
};
new Vue({
el:'#app',
data:{
das: ad_data['tv'],
index: '未选任何广告'
},
methods:{
fn(ad){
this.das = ad_data[ad]
},
// 3.接收子组件提供的数据,触发子组件提供的事件
changeFn(dat){
console.log(dat);
this.index = dat.title
}
},
components:{
tag
}
})
// console.log(data)
</script>
</html>
<style>
.close:hover {
cursor: pointer;
color: red;
}
</style>
<div id="app">
<p>
<input type="text" v-model="userMsg">
<button @click="sendMsg">留言</button>
</p>
<ul>
<!-- 2) 子组件内部通过触发系统事件,发送一个自定义事件,将数据携带出来 -->
<msg-li @remove_msg="removeAction" v-for="(msg, i) in msgs" :msg="msg" :index="i" :key="msg"></msg-li>
</ul>
</div>
<script src="js/vue.js"></script>
<script>
let msgLi = {
template: `
<li>
<span class="close" @click="deleteMsg(index)">x </span>
<span>第{{ index + 1 }}条:</span>
<span>{{ msg }}</span>
</li>
`,
props: ['msg', 'index'],
methods: {
// 最先触发系统的click事件
deleteMsg(i) {
// 1) 数据由子组件提供
// $emit('自定义事件名', 参数们)
this.$emit('remove_msg', i);
}
}
};
new Vue({
el: '#app',
data: {
msgs: [],
userMsg: ''
},
methods: {
sendMsg() {
if (this.userMsg) {
this.msgs.push(this.userMsg);
this.userMsg = "";
}
},
// 3) 父组件位子组件标签的自定义属性通过方法实现,就可以通过参数拿到子组件传递处理的参数
removeAction(i) {
this.msgs.splice(i, 1)
}
},
components: {
msgLi
}
})
</script>