组件
一、子组件
<head>
<meta charset="UTF-8">
<title></title>
<style>
.wrap {
calc(200px * 4 + 80px);
margin: 0 auto;
user-select: none;
}
.box {
200px;
height: 260px;
background-color: salmon;
border-radius: 10px;
float: left;
margin: 10px;
}
.box img {
100%;
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/001.jpg" alt="">
<title-tag/>
<p @click="fn">
摸它<b>{{ num }}下</b>
</p>
</div>
`,
data (){
return {
num:0
}
},
methods: {
fn(){
this.num ++
}
},
components: {
titleTag,
}
};
new Vue({
el: '#app',
components: {
tag,
}
})
</script>
注意:
1.能被复用的组件(除了根组件),数据都要做局部化处理,因为复用组件后,组件的数据是相互独立的。
2.data的值为绑定的方法的返回值,返回值是存放数据的字典。
二、父组件向子组件传参
在组件内部可以通过设置的自定义属性,拿到外部选择子组件提供给属性的值。
<head>
<meta charset="UTF-8">
<title></title>
<style>
.wrap {
calc(200px * 4 + 80px);
margin: 0 auto;
user-select: none;
}
.box {
200px;
height: 260px;
background-color: aqua;
border-radius: 10px;
float: left;
margin: 10px;
}
.box img {
height: 160px;
border-radius: 50%;
margin: 0 auto;
display: block;
}
.box p {
text-align: center;
}
</style>
</head>
<body>
<div id="app">
<div class="wrap">
<tag v-for="dog in dogs" v-bind:dog="dog" :a="1" b="2" />
</div>
</div>
</body>
<script src="js/vue.js"></script>
<script>
let dogs = [
{title: '1号哈哈', img: 'img/1.jpg'},
{title: '2号哈哈', img: 'img/2.jpg'},
{title: '3号哈哈', img: 'img/3.jpg'},
{title: '4号哈哈', img: 'img/4.jpg'},
{title: '1号哈哈', img: 'img/1.jpg'},
{title: '2号哈哈', img: 'img/2.jpg'},
{title: '3号哈哈', img: 'img/3.jpg'},
{title: '4号哈哈', img: 'img/4.jpg'},
];
let tag= {
props: ['dog', 'a', 'b', 'c'],
template:`
<div class='box'>
<img :src="dog.img" alt="">
<p>
<b>
{{ dog.title }}
</b>
</p>
</div>
`,
data (){
return {
num: 0,
}
},
methods: {
fun(){
this.num ++
}
},
};
new Vue({
el: '#app',
data: {
dogs,
},
components: {
tag,
}
});
</script>
总结 :
1.数据在父组件中产生 。
2.在父组件中渲染子组件,子组件绑定自定义属性,附上父组件中的数据 。
3.子组件自定义属性在子组件的props成员中进行声明(采用字符串发射机制) 。
4.在子组件内部,就可以用props声明的属性(直接作为变量)来使用父组件中的数据 。
三、子组件向父组件传参
示例一:
<head>
<meta charset="UTF-8">
<title></title>
<style>
ul {
list-style: none;
}
.d-btn {
font-size: 12px;
15px;
display: inline-block;
}
.d-btn:hover {
color: red;
cursor: pointer;
}
</style>
</head>
<body>
<div id="app">
<input type="text" v-model="msg">
<button @click="send_comment">留言</button>
<ul>
<tag v-for="(v, i) in comments" :msg="v" :index="i" @f1="deleteMsg"/>
</ul>
</div>
</body>
<script src="js/vue.js"></script>
<script>
let tag= {
props: ['msg', 'index'],
template:`
<li>
<i class="d-btn" @click="fn">x</i>
<b>{{ msg }}</b>
</li>
`,
methods: {
fn () { this.$emit('f1', this.index);}
}
};
new Vue({
el: '#app',
data: {
msg: '',
comments: localStorage.comments ? JSON.parse(localStorage.comments) : [],
},
components: { tag },
methods: {
send_comment(){
if (this.msg) {
this.comments.push(this.msg);
this.msg = '';
localStorage.comments = JSON.stringify(this.comments);
}
},
deleteMsg(index) {
this.comments.splice(index, 1);
localStorage.comments = JSON.stringify(this.comments);
}
}
})
</script>
<script>
localStorage.arr = JSON.stringify([1, 2, 3]);
let res = JSON.parse(localStorage.arr);
console.log(res, res[2]);
</script>
注意:localStorage,sessionStorage不能直接存储数组和对象,需要序列化为json。
示例二:
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="app">
<h1> {{ title }}</h1>
<tag @self_action="changeTitle"/>
</div>
</body>
<script src="js/vue.js"></script>
<script>
let tag = {
template: `
<div>
<input v-model="sub_title" />
</div>
`,
data() {
return {
sub_title: ''
}
},
watch: {
sub_title() {
this.$emit('self_action', this.sub_title)
}
}
};
new Vue({
el: '#app',
components: {
tag,
},
data: {
title: '父级初始标题'
},
methods: {
changeTitle(sub_title) {
this.title = sub_title ? sub_title : '父级初始标题'
}
}
})
</script>