单文件组件
1、单文件组件
1.在很多 Vue 项目中,我们使用 Vue.component
来定义全局组件,紧接着用 new Vue({ el: '#container '})
在每个页面内指定一个容器元素。
2.这种方式在很多中小规模的项目中运作的很好,在这些项目里 JavaScript 只被用来加强特定的视图。但当在更复杂的项目中,或者你的前端完全由 JavaScript 驱动的时候,下面这些缺点将变得非常明显:
- 全局定义 (Global definitions) 强制要求每个 component 中的命名不得重复
-
字符串模板 (String templates) 缺乏语法高亮,在 HTML 有多行的时候,需要用到丑陋的
\
- 不支持 CSS (No CSS support) 意味着当 HTML 和 JavaScript 组件化时,CSS 明显被遗漏
- 没有构建步骤 (No build step) 限制只能使用 HTML 和 ES5 JavaScript,而不能使用预处理器,如 Pug (formerly Jade) 和 Babel
3.文件扩展名为 .vue
的 single-file components (单文件组件) 为以上所有问题提供了解决方法,并且还可以使用 webpack 或 Browserify 等构建工具。
直接将组件分离出来,作为一个单独的文件。
2、使用单文件组件的三个步骤
- Left单文件组件配置
//文件名为Left.vue
<template>
<div>
<h3>Left 组件</h3>
<p>组件的值是:{{ msg }}</p>
</div>
</template>
<script>
//默认导出 固定写法
export default {
//data数据源 类型为函数
data(){
return{
msg: 'left'
}
}
}
</script>
<style lang="less" >
</style>
- 在根组件App.vue引用Left.vue单文件组件
3、单文件组件之间的通信(数据交互)
3.1 组件关系
- 组件在被封装好之后,彼此之间是相互独立的,不存在父子关系
- 在使用组件的时候,根据彼此的嵌套关系,形成了父子关系、兄弟关系
父子组件是两个封闭的作用域
父组件为User.vue
子组件为status.vue,detail.vue
3.2 父组件往子组件里面传值
1.在子组件中自定义可以接收的属性:
<script>
export default{
props:['name']//props:['name','age']可以传多个自定义属性
}
</script>
2.在父组件中引用子组件
<template>
<app-status
:name="name"></app-status>
</template>
<script>
//引入
import Status from "./status.vue"
export default{
data(){
return{
name:"zcy"
}
},
//注册
components:{
"app-status":Status
}
}
</script>
3.这时候,我们就可以在子组件中使用这个name了
<template>
<div>
<p>{{name}}</p>
</div>
</template>
4.如果我们直接改变props的name属性的值,会报错(怕我们数据流发生混乱),所以我们要定义一个属性初始化这个传过来的name
<template>
<div>
<p>{{myName}}</p>
<p>{{changeName()}}</p>
</div>
</template>
<script>
export default{
props:['name'],
data(){
return{
myName=this.name
}
},
methods:{
changeName:function(){
this.myName='xiaoming';
}
}
}
</script>
5.props验证,可以传一个也可以传多个,必须传required:true,default:'daming' 这两个只能存在一个,必传或者默认
<script>
export default{
//props:['name'],
props:{
name:String,
name:[String,Array,Number],
name:{
type:String,
required:true//必须传,存其一
default:'daming'//默认,存其一
},
//如果是Object
name:{
type:Object,
//required:true//必须传,存其一
default(){
return{
}
}
},
//age:Number
},
data(){
return{
myName=this.name
}
},
methods:{
changeName:function(){
this.myName='xiaoming';
}
}
}
</script>
3.3 子组件往父组件里面传值
1.在子组件中绑定上点击事件,然后通过$emit触发自定义的事件(事件名和值)
<template>
<div>
<p>{{myName}}</p>
<p>{{changeName()}}</p>
<p><button @click="changePName">改变父级的name</button></p>
</div>
</template>
<script>
export default{
props:{
name:{
type:String
}
},
data(){
return{
myName=this.name
}
},
methods:{
changeName:function(){
this.myName='xiaoming';
},
changePName:function(){
this.$emit('changePName','xiaohuang');
}
}
}
</script>
2.在父组件中绑定上这个自定义的事件
<template>
<app-status
:name="name"
@changePName="changeName"></app-status>
</template>
<script>
//引入
import Status from "./status.vue"
export default{
data(){
return{
name:"zcy"
}
},
//注册
components:{
"app-status":Status
},
methods:{
changeName:function(name){
this.name=name;
}
}
}
</script>
3.4 兄弟组件传值
绑定和触发全局事件(EventBus)
1.在main.js中注册一个新的Vue实例
export const EventBus=new Vue()
2.在子组件status.vue中引入这个EventBus,这个子组件去改变另一个兄弟子组件
<template>
<div>
<p>{{age}}</p>
<p><button @click="changeAge">改变兄弟值</button></p>
</div>
</template>
<script>
import {EventBus} from "./main.js"
export default{
data(){
return{
age:10
}
},
methods:{
changeAge:function(){
this.age=20;
EventBus.$emit("editAge",this.age);//全局触发自定义事件
}
}
}
</script>
3.在子组件detail.vue中去引入EventBus,通过$on绑定上自定义事件
<template>
<div>
<p>{{age}}</p>
</div>
</template>
<script>
import {EventBus} from "./main.js"
export default{
data(){
return{
age:10
}
},
methods:{
},
create(){
EventBus.$on("editAge",(age)=>{
this.age=age;
});//绑定自定义事件
}
}
</script>
网友评论