Vue-组件(Component)
组件的作用:用来减少Vue实例对象中代码量,日后在使用Vue开发过程中,可以根据 不能业务功能将页面中划分不同的多个组件,然后由多个组件去完成整个页面的布局,便于日后使用Vue进行开发时页面管理,方便开发人员维护。
组件的使用
全局组件
全局组件,注册给vue实例,日后可以在任意的vue的实例的范围内使用该组件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>全局组件</title>
</head>
<body>
<div id="app">
<!-- 使用userLogin组件,在vue中组件的驼峰命名会将大写字母转化为小写字母并添加 - -->
<user-login></user-login>
<!-- 所以这个组件是无效的-->
<userLogin></userLogin>
</div>
<!--引入vue-->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
<!-- 通过注册给Vue实例,可以在全局使用-->
//全局组件注册 参数1:组件名称 参数2:组件配置对象 template: 用来书写组件的html代码(注意:在template中必须存在一个容器)
Vue.component('userLogin',{
template: '<div><h1>user-login</h1></div>'
});
const app = new Vue({
el:"#app",
data:{},
methods:{},
});
</script>
</body>
</html>
1.Vue.component用来开发全局组件 参数1: 组件的名称 参数2: 组件配置{} template:’'用来书写组件的html代码 template中必须有且只有一个root元素
2.使用时需要在Vue的作用范围内根据组件名使用全局组件
3.如果在注册组件过程中使用 驼峰命名组件的方式 在使用组件时 必须将驼峰的所有单词小写加入-线进行使用
局部组件
通过将组件注册给对应Vue实例中一个components属性来完成组件注册,这种方式不会对Vue实例造成累加
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>局部组件</title>
</head>
<body>
<div id="app">
<login></login> <logout></logout>
</div>
<!--通过模板标签形式注册局部组件-->
<template id="loginTemplate">
<h1>用户登录</h1>
</template>
<!--引入vue-->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
let login = {
template: "#loginTemplate",
};
//具体方式实现
let logout = {
template: ' <div> <h1>用户注销</h1> </div> ',
};
const app = new Vue({
el:"#app",
data: {},
methods: {},
components: {
login,
logout
}
});
</script>
</body>
</html>
Prop的使用
作用:props用来给组件传递相应静态数据或者是动态数据
1.通过在组件上声明静态数据传递给组件内部
props在这里当做接收使用组件时通过组件标签传递的数据
- 使用组件时可以在组件上定义多个属性以及对应数据
- 在组件内部可以使用props数组生命多个定义在组件上的属性名 日后可以在组件中通过{{ 属性名 }} 方式获取组件中属性值
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<login username="小新" password="123456"></login>
</div>
<!--引入vue-->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
//声明一个组件
let login = {
template:" <div> <h1>用户名 {{username}} </h1>" +
" <h1>密码 {{password}}</h1> </div> " ,
props: ['username','password']
}
const app = new Vue({
el:"#app",
data: {},
methods:{},
components: {
login //组件注册
}
});
</script>
</body>
</html>
2 通过在组件上声明动态数据传递给组件内部
使用v-bind形式将数据绑定Vue实例中data属性,日后data属性发生变化,组件内部数据跟着变化
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>局部组件使用prop接收动态数据</title>
</head>
<body>
<div id="app">
<hello :song="song" :lyric="lyric"></hello>
</div>
<!--引入vue-->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
let hello = {
template:" <div> <h1> {{ song }} </h1> {{lyric}} </div> ",
props: ['song','lyric']
};
const app = new Vue({
el:"#app",
data:{
song:"here with you",
lyric:"The night is yong ,the music's loud "
},
methods:{},
components:{
hello
}
})
</script>
</body>
</html>
3 prop的单向数据流
单向数据流:所有的 prop 都使得其父子 prop 之间形成了一个**单向下行绑定**:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。
所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外改变父级组件的状态,从而导致你的应用的数据流向难以理解。
额外的,每次父级组件发生更新时,子组件中所有的 prop 都将会刷新为最新的值。这意味着你不应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在浏览器的控制台中发出警告。—摘自官网
组件中定义的数据和事件
1.组件中定义的数据
使用data函数方式定义组件的数据 在template html 代码中通过差值表达式直接获取
必须要以return的方式 返回
自己内部的数据不需要props来接收,外部的动态数据仍需要props来接收
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<study :user="username" :lists="lists"></study>
</div>
<!--引入vue-->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
let study = {
template:" <div> <h1> {{user}} {{studyProcess}} </h1> " +
" <ul> <li v-for='item in lists'> {{item}} </li> </ul> </div> ",
data(){
return {
studyProcess:"找工作的学习过程", //组件自己的内部数据,所以不需要props来接收
user:this.username, //非组件自己的内部数据,所以需要prop来传递
lists:this.lists,
}
},
props:['user','lists']
};
const app = new Vue({
el:"#app",
data:{
username:"小新",
lists:["Java基础从进门到放弃","数据库从删库到跑路","Linux从开始到结束"]
},
methods:{
},
components:{
study
}
});
</script>
</body>
</html>
2.组件中定义的事件
//在上段代码中添加事件的
1.组件中定义事件和直接在Vue中定义事件基本一致 直接在组件内部对应的html代码上加入@事件名=函数名方式即可
2.在组件内部使用methods属性用来定义对应的事件函数即可,事件函数中this 指向的是当前组件的实例
向子组件中传递事件并在子组件中调用改事件
在子组件中调用传递过来的相关事件必须使用 this.$emit(‘函数名’) 方式调用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>组件中定义的事件</title>
</head>
<body>
<div id="app">
<study :user="username" :lists="lists" @aaa="learning"></study>
</div>
<!--引入vue-->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
let study = {
template:" <div> <h1> {{user}} {{studyProcess}} </h1> " +
" <ul> <li v-for='item in lists'> {{item}} </li> </ul> " +
" <input type='button' value='StudyHard' @click='learn'> " +
" <input type='button' value='开始学习' @click='learning'> </div> ",
data(){
return {
studyProcess:"找工作的学习过程", //组件自己的内部数据,所以不需要props来接收
user:this.username, //非组件自己的内部数据,所以需要prop来传递
lists:this.lists,
}
},
props:['user','lists'],
methods: {
learn(){
alert('try hard')
alert('疯狂学习')
},
learning(){
this.$emit('aaa'); //aaa是指像prop 传递接收时所使用的名称
}
}
};
const app = new Vue({
el:"#app",
data:{
username:"小新",
lists:["Java基础从进门到放弃","数据库从删库到跑路","Linux从开始到结束"]
},
methods:{
learning:function (){
alert('开始疯狂学习')
}
},
components:{
study
}
});
</script>
</body>
</html>