在Vue上注册的就是全局组件,在任意的组件和实例上都可以使用
let CommonHeader = { template:"<h1>这是一个公共的头部文件</h1>",//里面写html标签,即视图文件 data(){ return{ } }, methods:{ } } Vue.component("CommonHeader",CommonHeader)//组件命名建议使用大驼峰或连接符 const vm = new Vue({ el: '#box', data: { }, methods: { } })1、在某个组件或者实例中注册的就是局部组件,只能在注册的组件或者实例上使用 2、局部组件可以在其他组件的conponents上注册(即既可以是new Vue,也可以是其他组件)
示例1:在 new Vue上注册
//在 new Vue上注册可以在这个实例中应用 当前是id为box的标签 let CommonTitle = { template:`<h1>这是局部组件标题</h1>`, data () { return { } }, methods: { } } const vm = new Vue({ el: '#box', data: { }, methods: { }, components: { 'CommonTitle':CommonTitle } })示例2:在 其他组件的components属性上注册
//在其他组件注册则只能在当前组件的template模板中使用 let CommonTitle = { template:`<h1>这是局部组件标题</h1>`, data () { return { } }, methods: { } } let CommonHeader = { template:` <div> <h1>这是大标题</h1> <common-title></common-title> </div> `, data(){ return{ } }, methods:{ }, components: { 'CommonTitle': CommonTitle } } Vue.component("CommonHeader",CommonHeader) const vm = new Vue({ el: '#box', data: { }, methods: { }, // components: { // 'CommonTitle':CommonTitle // } })注意
组件中的data 必须是 一个函数 返回一个对象 (原因是 组件是需要复用的 ,如果直接是对象,多次使用时,使用的是同一个对象,不符合项目开发要求,而如果是返回对象的话(实际上是闭包),会让组件在每一次使用的时候都形成一个独立的空间 )每个组件有自己的作用域,组件内部的数据,和方法只能在组件内部使用(如向跨组件,需要组件间通信)组件的命名 可以有两种 1大驼峰 2下划线命名法 eg: CommonHead common-head 使用时二者都一样 局部组件 在哪个组件的components中注册,就只能在这个组件的template中使用组件的template 有且只能有一个根标签(元素)组件间的嵌套使用形成了组件间的关系
验证三种类型: 数据类型 是否必须填写 默认值
数据类型:String Number Boolean Array Object Date Function Symbol 是否必须填写: required:true/false true必填 false非必填 默认值 : default
// 此时props不是数组,而是对象 props:{ //只验证类型 a:String, //既验证类型,又要求必传 b:{ type:[String,Number],//类型是多个中的一个 required:true }, //验证类型,并设置默认值 c:{ type:Number, default:0 } }注意
props中定义的参数名会自动的编译成实例,属性props名字不能和data中以及methods和计算属性,不能同名如果默认值是数组或者对象,则需要一个函数返回这个默认值props能否改变props保持单向的 即父向子(子不能改变),易于维护通过自定义事件触发
//子组件 methods中 this.$emit("事件名",携带的数据) /* 父组件 <子组件 @事件名="fn"></子组件> methods中 fn(data){ data就是子组件传过来的数据} */ <script> let CommonTitle = { template: ` <div> 子组件 <button @click="change">单击传输数据</button> </div>`, data () { return { msg: '我是子组件的数据' } }, methods: { change () { // this.$emit("事件名",this.msg) this.$emit("change1",this.msg) } } } let Home = { template: ` <div> <common-title @change1="fn"></common-title> home页面内容 </div>`, data () { return { title:"我是home页", title2:"我是home页2" } }, methods: { // fn () { // alert("出发了fn") // } fn (msg) { alert(msg) } }, components: { CommonTitle } } let vm = new Vue({ el: '#box', components: { Home } }) </script> </body>注意 1 兄弟组件通信,是谁emit的谁去on,所以需要定义一个第三方组件eventBus 2 回调函数如果不写成箭头函数,需要处理this问题
可以在外部定义一个变量接收this let _this=this eventBus.$on("change1",function(msg){ _this.msg=msg }) 可以使用bind(this) eventBus.$on("change1",function(msg){ this.msg = msg }.bind(this))直接在父组件里面拿到了子组件这个实例
let CommonTitle = { template: ` <div> 子组件1 </div>`, data () { return { msg: 123 } }, } let Home = { template: ` <div> <common-title ref="commonTitle" ></common-title> </div>`, mounted () { console.log(this.$refs.commonTitle)//此时打印得到的是子组件这个实例本身 }, components: { CommonTitle, } } let vm = new Vue({ el: '#box', components: { Home } }) //不建议直接使用ref操作子组件子组件里引用$parent
mounted () { console.log(this.$parent)//得到的是当前组件的父组件 } /* VueComponent {_uid: 1, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: VueComponent, …} */父组件引用$children
mounted () { console.log(this.$parent) // 得到的当前组件的所有子组件,是数组,通过下标可以直接得到子组件 } // [VueComponent]父组件 提供provide
let msg=12345 let Home = { provide:{ msg:msg, num:107 }, }子组件 接收inject
let CommonTitle = { inject: ["msg","num"], mounted () { console.log(this.msg)//12345 console.log(this.num)//107 } }其实是用来占位的,是vue的系统组件
<solt></slot> //在使用组件时,自定义标签内容,会自动的灌入到solt占的位置上 //可以实现组件在不同的父组件中使用时,内部可以有不一样的代码块(布局)可以在子组件中,定义多个插槽,且每个插槽,有自己的名字,在代码传入时,指定传入哪个
let CommonTitle = { template: ` <div> <h2>我是子组件</h2> <slot name="xm"></slot> <slot name="xq"></slot> </div> ` } let Home = { template:` <div> home页内容 <common-title> <template slot="xq"> <button>我是小强</button>//此时的button会占用 name="xq"的位置 </template > <div slot="xm"> <button>我是小明</button>//此时的button会占用 name="xm"的位置 </div> </common-title> </div>`, components: { CommonTitle, } } let vm = new Vue({ el: '#box', components: { Home, } })