目录
什么是组件: 组件的出现,就是为了拆分Vue实例的代码量的,能够让我们以不同的组件,来划分不同的功能模块,将来我们需要什么样的功能,就可以去调用对应的组件即可。
模块化:是从代码逻辑的角度进行划分的;方便代码分层开发,保证每个功能模块的职能单一
组件化:是从UI界面的角度进行划分的;前端的组件化,方便UI组件的重用
在父组件中给引用的子组件注册一个事件(这个事件的名字是自定义的)
.(1)父组件这个方法没有自定参数,在父组件的方法直接加这个参数就可以拿到
(2)父组件有自定义参数,可以传入$event也可以拿到子组件传递的数据。通过$event只能传递第一个参数。
将评论发表做成一个组件,发表后保存到localStorage中
首先获取已经保存的数据(localStorage.getItem('key')).
在把数据保存到localStorage中(localStorage.setItem('key','value'))
给dom节点记上ref属性,可以理解为给dom节点起了个名字。
通过vue实例的$refs属性拿到这个组件的引用,之后可以通过这个引用调用子组件的方法,或者获取子组件的数据。
后端路由:对于普通的网站,所有的超链接都是URL地址,所有的URL地址都对应服务器上对应的资源
在单页面应用程序中,这种通过hash改变来切换页面的方式,称作前端路由(区别于后端路由)
引入js文件,这个js需要放在vue的js后面,自动安装(提供了一个VueRouter的构造方法)
创建路由new VueRouter(),接受的参数是一个对象
在实例化的对象里配置属性routes:[],这个数组里的对象包含path属性和component属性
path属性是url的地址,component属性就是显示的组件(传组件的对象)
声明路由的时候设置children,这是children是一个数组,数组里是路由对象
我们之前只能一个地址对应一个组件,现在可以一个地址对应多个组件
给router-view设置名字,这个名字和components组件名字是对应的
监听keyup知道input什么时候改变了,在这里就可以获取完整的名字
今日任务
掌握组件父子之间的传值
掌握路由的使用
实现经典布局
定义vue组件
什么是组件: 组件的出现,就是为了拆分Vue实例的代码量的,能够让我们以不同的组件,来划分不同的功能模块,将来我们需要什么样的功能,就可以去调用对应的组件即可。
组件化和模块化的不同:
-
模块化:是从代码逻辑的角度进行划分的;方便代码分层开发,保证每个功能模块的职能单一
-
组件化:是从UI界面的角度进行划分的;前端的组件化,方便UI组件的重用
1.1 父组件传值子组件
-
接受父组件传值
设置props属性就可以接受父组件传值
-
属性的继承和传递
属性继承的特征:
父组件的属性会覆盖子组件的属性
class 和 style 会进行合并,不会覆盖
设置禁用继承
加在子组件上的属性,使用了这个属性之后会阻止组件继承父组件的属性,但是class和style除外
inheritAttrs: false
在组件内可以使用$attrs获取父组件传过来的属性
-
注意事项
data和props的区别
data是组件私有的,props是父组件传过来的
data是可以修改的,props是只读的
示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title></title>
<script src="../vue-2.4.0.js"></script>
<script src="../axios.js"></script>
</head>
<body>
<div id='app'>
<father formapp="来自app传值"> </father>
<father></father>
</div>
<template id="father">
<div>
father{
{msg}}
{
{formapp}}
<son add="随意"></son>
<son></son>
</div>
</template>
<template id="son">
<div>
son{
{add}}
</div>
</template>
<script>
Vue.component("father",{
template:"#father",
data(){
return {
msg:'hello'
}
},
//接受父组件传值
props:{
formapp:{
type:[String,Number],
default:'fromappfather'
},
},
created(){
console.log(this.formapp);
},
})
Vue.component("son", {
template: "#son",
data(){
return {
}
},
props:{
add:{
type:[String,Number],
default(){
return 'suiyi'
}
}
}
})
const vm = new Vue({
el: '#app',
data: {
},
methods: {
}
})
</script>
</body>
</html>
1.2 子组件传值父组件
子组件调用父组件的方法
-
在父组件中给引用的子组件注册一个事件(这个事件的名字是自定义的)
-
子组件可以触发这个事件$emit('事件名字')
子组件给父组件传递数据
-
$emit方法第二个参数可以定义子组件给父组件传递的内容
-
在父组件中怎么拿到这内容
.(1)父组件这个方法没有自定参数,在父组件的方法直接加这个参数就可以拿到
(2)父组件有自定义参数,可以传入$event也可以拿到子组件传递的数据。通过$event只能传递第一个参数。
示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title></title>
<script src="../vue-2.4.0.js"></script>
<script src="../axios.js"></script>
</head>
<body>
<div id='app'>
<father></father>
</div>
<template id="father">
<div>
子组件调用父组件的方法
1、在父组件中给引用的字组件注册一个事件 (这个事件的名字是自定义的)
2、子组件可以触发这个事件$emit(‘自定义事件’,传递参数)
father
<br>
子传父:{
{fromsondata}}
<br>
<son @myson="fromson"></son>
</div>
</template>
<template id="son">
<div>
son
<button @click="toofather">点我传参</button>
</div>
</template>
<script>
Vue.component("father",{
template: "#father",
data(){
return{
msg: 'hello',
fromsondata:""
}
},
methods:{
//data就是子组件传的值
fromson(data){
console.log(data);
this.fromsondata = data
}
}
})
Vue.component("son",{
template: "#son",
data(){
return {
}
},
created(){
// 触发子传父 this$enit('自定义事件',传递参数)
// this.$emit('myson', '这是来自子组件的参数')
},
methods:{
toofather(){
//子传父
this.$emit('myson','这是子组件的参数')
}
}
})
const vm = new Vue({
el: '#app',
data: {
},
methods: {
}
})
</script>
</body>
</html>
1.3评论列表案例
-
将评论发表做成一个组件,发表后保存到localStorage中
-
获取用户输入的值
-
构造一个对象
-
把数据存起来(localStorage)
首先获取已经保存的数据(localStorage.getItem('key')).
把数据添加进去
在把数据保存到localStorage中(localStorage.setItem('key','value'))
-
子组件更新后父组件同步更新
-
子组件更新数据后,通知父组件
1.1 父组件引用子组件的时候注册一个事件
1.2子组件更新完数据之后调用$emit方法通知父组件
示例1:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title></title>
<link rel="stylesheet" href="../bootstrap-3.4.1-dist/css/bootstrap.min.css">
<script src="../vue-2.4.0.js"></script>
</head>
<body>
<div id='app'>
<div class="container">
<div class="panel panel-info">
<div class="panel-heading">
<h3 class="panel-title">留言板</h3>
</div>
<div class="panel-body">
<form action="" method="POST" role="form">
<div class="form-group">
<label for="">姓名</label>
<input type="text" class="form-control" id="" placeholder="Input field">
</div>
<div class="form-group">
<label for="">留言</label>
<input type="text" class="form-control" id="" placeholder="Input field">
</div>
<button type="submit" class="btn btn-primary" @click="addComment">发布评论</button>
</form>
<br>
<ul class="list-group">
<li class="list-group-item" v-for="(item,index) in list" :key="index">
{
{item.comment}}
<span class="badge">评论人:{
{item.name}}</span>
</li>
</ul>
</div>
</div>
</div>
</div>
<script>
const vm = new Vue({
el: '#app',
data: {
name:'',
comment:'',
list:[],
},
methods: {
addComment(){
this.list.push({
name:this.name,
comment:this.comment
})
}
}
})
</script>
</body>
</html>
示例2子传父:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title></title>
<link rel="stylesheet" href="../bootstrap-3.4.1-dist/css/bootstrap.min.css">
<script src="../vue-2.4.0.js"></script>
</head>
<body>
<div id='app'>
<div class="container">
<!-- 引入子组件 -->
<son @getlist="fr