像原始的html元素都有自己的一些属性,而我们自己创建的组件,也可以通过prop来添加自己的属性。这样别人在使用你创建的组件的时候就可以传递不同的参数了。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<button_list v-bind:books="books"> </button_list>
</div>
</body>
</html>
<!--vue引入 必须联网-->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
//组件
Vue.component('button_list',{
//给组件添加属性 propertys 关键字
props:['books'],
template:`
序号
标题
{
{index+1}}
{
{book.title}}
`, //button_list中封装的内容模板就是这句
data:function(){
//这里的data写法不同于new vue中的data
return {
//这里需要{}
count:0
}
}
})
new Vue({
el:"#app",
data:{
books:[
{
'title':"python","id":1},
{
'title':"java","id":2},
{
'title':"php","id":3},
]
}
})
</script>
如果自定义的组件中,会出现很多html元素,那么根元素必须只能有一个,其余的元素必须包含在这个根元素中。比如以下是一个组件中的代码,会报错:
子组件中添加事件跟之前的方式是一样的,然后如果发生某个事件后想要通知父组件,那么可以使用this.$emit函数来实现。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<button_list v-for="book in books" v-bind:book="book" @check_change="checks"></button_list>
<div v-for="cbook in component_book">
{
{
cbook.title}}
</div>
</div>
</body>
</html>
<!--vue引入 必须联网-->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
//组件
Vue.component('button_list',{
//给组件添加属性 propertys 关键字
props:['book'],
template:`
{
{book.title}}
`, //button_list中封装的内容模板就是这句
methods:{
Oncheck:function(){
this.$emit('check_change', this.book)
}
}
})
new Vue({
el:"#app",
data:{
books:[
{
'title':"python","id":1},
{
'title':"java","id":2},
{
'title':"php","id":3},
],
component_book:[],
},
methods:{
checks:function(book){
console.log(book)
var index=this.component_book.indexOf(book) //indexOf 返回的是book的下标
if(index >= 0){
this.component_book.splice(index,1) //删除一个下标为index的元素
}else{
this.component_book.push(book)
}
}
}
})
</script>
一个组件上的v-model默认会利用名为value的prop(属性)和名为input的事件,但是像单选框、复选框等类型的输入控件可能会将value特性用于不同的目的。这时候我们可以在定义组件的时候,通过设置model选项可以用来实现不同的处理方式。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<stepper v-model:value="goods_count"></stepper>
</div>
</body>
</html>
<!--vue引入 必须联网-->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
//计步器
Vue.component('stepper',{
//给组件添加属性 propertys 关键字
props:['count'],
model:{
//代表什么情况下触发这个v-model的行为
event:'count_change',
prop:'count'
},
template:`
{
{count}}
`, //button_list中封装的内容模板就是这句
methods:{
sub:function(){
this.$emit('count_change', this.count-1)
},
add:function(){
this.$emit('count_change', this.count+1)
}
}
})
new Vue({
el:"#app",
data:{
goods_count:0,
},
})
</script>
其中的props定义的属性分别是给外面调用组件的时候使用的。model中定义的prop:'count’是告诉后面使用v-model的时候,要修改哪个属性;event:'count-chang’是告诉v-model,后面触发哪个事件的时候要修改属性。
我们定义完一个组件后,可能在使用的时候还需要往这个组件中插入新的元素或者文本。这时候就可以使用插槽来实现。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<new_link v-bind:url="url">
个人中心
</new_link>
</div>
</body>
</html>
<!--vue引入 必须联网-->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
//计步器
Vue.component('new_link',{
//给组件添加属性 propertys 关键字
props:['url'],
template:`
`,
})
new Vue({
el:"#app",
data:{
url:"https://www.baidu.com",
},
})
</script>
当组件渲染的时候,将会被替换为“个人中心”。插槽内可以包含任何模板代码,包括HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<new_link v-bind:url="url">
个人中心
{
{
name}}
<template v-slot:header>这是header</template>
<template v-slot:main>这是main</template>
<div></div>
</new_link>
</div>
</body>
</html>
<!--vue引入 必须联网-->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
//计步器
Vue.component('new_link',{
//给组件添加属性 propertys 关键字
props:['url'],
template:`
`,
data:function(){
return {
name:"zzz",
}
}
})
new Vue({
el:"#app",
data:{
url:"https://www.baidu.com",
},
})
</script>
如果没有包含一个元素,则该组件起始标签和结束标签之间的任何内容都会被抛弃。
生命周期函数代表的是Vue实例,或者是Vue组件,在网页中各个生命阶段所执行的函数。生命周期函数可以分为创建阶段和运行期间以及销毁期间。
以下是官方文档给到的一张图,从这种图中我们可以了解到每个部分执行的函数。
创建期间:
beforeCreate:
Vue或者组件刚刚实例化,data、methods都还没有被创建。
created:
此时data和methods已经被创建,可以使用了。模板还没有被编译。
beforeMount:
created的下一阶段。此时模板已经被编译了,但是并没有被挂在到网页中。
mounted:
模板代码已经被加载到网页中了。此时创建期间所有事情都已经准备好了,网页开始运行了。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<p id="username">{
{
username}}</p>
</div>
</body>
</html>
<!--vue引入 必须联网-->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
Vue.component('content',{
template:`
`,
data:function(){
return {
navs:["1","2","3"]
}
}
}),
new Vue({
el:"#app",
data:{
username:"yyy"
},
methods:{
demo:function(){
return "hello"
}
},
//beforeCreate:Vue或者组件刚刚实例化,data、methods都还没有被创建
beforeCreate(){
// console.log(this.username);
// console.log(this.demo);
// console.log(123);
// console.log("----------------------");
},
//此时data和methods已经被创建,可以使用了。模板还没有被编译。
created(){
// console.log(this.username);
// console.log(this.demo);
// console.log(123);
// console.log("----------------------");
},
// created的下一阶段。此时模板已经被编译了,但是并没有被挂在到网页中。
beforeMount(){
//console.log(document.getElementById('username').innerText)
},
mounted(){
console.log(document.getElementById('username').innerText) //获取文本信息
}
})
</script>
运行期间:
beforeUpdate:
在网页网页运行期间,data中的数据可能会进行更新。在这个阶段,数据只是在data中更新了,但是并没有在模板中进行更新,因此网页中显示的还是之前的。
updated:
数据在data中更新了,也在网页中更新了。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<p id="username">{
{
username}}</p>
<!-- v-model双向绑定,修改username的值 -->
<input type="text" v-model="username">
</div>
</body>
</html>
<!--vue引入 必须联网-->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
Vue.component('content',{
template:`
`,
data:function(){
return {
}
}
}),
new Vue({
el:"#app",
data:{
username:"yyy"
},
methods:{
demo:function(){
return "hello world"
}
},
mounted(){
// console.log(document.getElementById('username').innerText) //获取文本信息
},
// 数据在data中更新了,也在网页中更新了
update(){
console.log(document.getElementById('username').innerText)
}
})
</script>
销毁期间:
beforeDestroy:
Vue实例或者是组件在被销毁之前执行的函数。在这一个函数中Vue或者组件中所有的属性都是可以使用的。
destroyed:
Vue实例或者是组件被销毁后执行的。此时Vue实例上所有东西都会解绑,所有事件都会被移除,所有子元素都会被销毁。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<p id="username">{
{
username}}</p>
<!-- v-model双向绑定,修改username的值 -->
<input type="text" v-model="username">
<error-view v-bind:message="message" v-if="message"></error-view>
<button @click="message=' ' ">点击</button>
</div>
</body>
</html>
<!--vue引入 必须联网-->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
Vue.component('error-view',{
props:['message'],
template:`
{
{message}}
`,
methods:{
},
data:function(){
return {
}
},
beforeDestroy(){
console.log('hello')
},
}),
new Vue({
el:"#app",
data:{
username:"yyyyyyyyyy",
message:"错误信息",
},
methods:{
demo:function(){
return "hello world"
}
},
mounted(){
// console.log(document.getElementById('username').innerText) //获取文本信息
},
// 数据在data中更新了,也在网页中更新了
update(){
console.log(document.getElementById('username').innerText)
}
})
</script>