Vue组件基础学习(三)
1 全局的自定义组件
-
方法
Vue.component(id,[definition])
-
{string} id
-
{Function | Object} [definition]
-
用法 注册或获取全局组件。注册还会自动使用给定的
id
设置组件的名称(截取官网介绍)// 注册组件,传入一个扩展过的构造器 Vue.component('my-component', Vue.extend({ /* ... */ })) // 注册组件,传入一个选项对象 (自动调用 Vue.extend) Vue.component('my-component', { /* ... */ }) // 获取注册的组件 (始终返回构造器) var MyComponent = Vue.component('my-component')
-
-
简单实例 (
data
必须是一个函数)<div id="app"> <my-component></my-component> </div> <script> //全局的自定义组件 是可复用的Vue实例,所以也具备例如 data computed,watch methods 以及生命周期钩子等 //命名如果是驼峰命名法,那么创建时以 -加小写 //my-component Vue.component('myComponent',{ //组件的data参数是一个函数方法,返回对象 data:function(){ return{ count:0 } }, //模板定义 template:'<button @click="count++">点击次数:{{count}}</button>' }) var vm=new Vue({ el:"#app", data:{ msg:"aaa" } }) </script>
2.父子组件之间的数据传递
1. 父组件向子组件传递,通过Prop向子组件传递数据
<div id="app">
<!-- 静态传值 -->
<my-component-prop title="参数传递"></my-component-prop>
<!-- 动态传值 -->
<my-component-prop :title="msg"></my-component-prop>
<!-- 动态循环渲染使用 -->
<my-component-prop v-for="title in titles" :title="title"></my-component-prop>
<!-- 静态传递数字,布尔值,数组,对象也要通过v-bind绑定的方式来告诉Vue 这是一个表达式而不是字符串。例如以下-->
<my-component-prop :number="40"></my-component-prop>
<my-component-prop :isTrue="false"></my-component-prop>
<my-component-prop :titles="["aa","bbb"]"></my-component-prop>
<my-component-prop :object="{name:'lisi',age:18}"></my-component-prop>
<!-- 当然这些也可以动态传递 -->
</div>
<script>
Vue.component('my-component-prop',{
props:['title'],
//模板定义
template:'<h3>{{title}}</h3>'
})
var vm=new Vue({
el:"#app",
data:{
msg:"参数传递",
titles:["a",'b','c']
}
})
</script>
你想将一个对象的所有属性都作为 prop 传入
<my-component-prop v-bind="post"></my-component-prop>
<!-- 等价与 -->
<my-component-prop v-bind:title="post.title" :name="post.name" :age="post.age"></my-component-prop>
post:{title:'aaa',name:'lisi',age:18}
Vue.component('my-component-prop',{
//组件的data参数是一个函数方法
props:['title','name','age'],
//模板定义
template:'<h3>{{title}} {{name}}{{age}}</h3>'
})
-
父组件向子组件传递数据是单向数据流
以上通过Prop向子组件动态的传递数据, 当数据改变时 那么对应子组件的也会刷新改变
<div id="app"> <!-- 例如 --> <!-- 通过表单控件来双向绑定数据 --> <input v-model="msg"> <!-- 自定义组件 --> <my-component-prop :msg="msg"></my-component-props> </div> <script> //当msg值发生改变时 定义的组件mgs值也会改变 Vue.component('my-component-props',{ props:['msg'], //模板定义 template:'<h3>{{message}}</h3>' }) var vm=new Vue({ el:"#app", data:{ msg:"参数传递" } }) </script>
而子组件需要使用这个参数,而不改变父组件这个参数的值。子组件接下来希望将其作为一个本地的 prop 数据来使用,这是就可以定义一个本地的data属性 并将prop的初始值赋给他
- 1.可以在子组件内部定义参数,并将父组件传递的值赋给他
Vue.component('my-component-prop',{ //组件的data参数是一个函数方法 props:['msg'], data:function(){ return { message:this.msg } }, //模板定义 template:'<h3>{{message}}</h3>' })
2.这个 prop 以一种原始的值传入且需要进行转换。在这种情况下,最好使用这个 prop 的值来定义一个计算属性
props: ['size'], computed: { normalizedSize: function () { return this.size.trim().toLowerCase() } }
-
也可以为props指定传参类型
props: { title: String, likes: Number, isPublished: Boolean, commentIds: Array, author: Object, callback: Function, contactsPromise: Promise }
**注意:**如果props要为某个参数或对象指定类型就用
{}
以对象的形式来包裹,反之用[]
以字符串数组形式列出
2.子组件向父组件传值,通过发布自定义事件,让父组件监听从而达到子组件向父组件传递参数,使用**this.$emit()
**方法
第一步定义子组件 (这里定义的是全局,也可以定义局部)
//自定义组件
var my_children = Vue.component('children', {
//绑定点击事件
template: '<button @click="incrementCount">添加count={{count}}</button>',
data: function () {
return {
count: 0
}
},
methods: {
incrementCount: function () {
this.count=this.count+1;
//发布一个一个自定义事件并传参
this.$emit('addcount', this.count)
}
}
})
第二部父组件调用并获取参数
var vm = new Vue({
el: "#app",
components: {
perent: my_children
},
methods: {
add: function (value) {
this.counts.push(value)
//console.log(this.counts)
}
},
data: {
counts: []
}
})
<div id="app">
<perent @addcount="add"></perent>
<ul>
<li v-for="count in counts">{{count}}</li>
</ul>
</div>
-
其他注意事项
-
在自定义组件的根元素上监听原生的事件,就可以使用
v-on
的修饰符.native
来实现<my-component v-on:click.native="onClick"></my-component>
-
在自定义组件的根元素上使用
v-model
**官网介绍:**一个组件上的
v-model
默认会利用名为value
的 prop 和名为input
的事件,但是像单选框、复选框等类型的输入控件可能会将value
特性用于不同的目的。model
选项可以用来避免这样的冲突:Vue.component('base-checkbox', { //使用model来避免冲突 model: { prop: 'checked', event: 'aa' }, //仍需要在props下定义checked props: { checked: Boolean }, //将状态发送给父组件 template: `<input type="checkbox" v-bind:checked="checked" v-on:change="$emit('aa', $event.target.checked)">` }); var vm=new Vue({ el:"#app", data:{ checked:true } });
<div id="app"> <base-checkbox v-model="checked"></base-checkbox> <h3>{{checked}}</h3> </div>
-
自定义组件内使用
v-model
Vue.component('children', { data:function(){ return { checked:false } }, template: `<input type="checkbox" v-model="checked" @change="change">`, methods:{ //将状态发送给父组件 change(){ this.$emit('change',this.checked) } } }); var vm=new Vue({ el:"#app", data:{ value:false }, methods:{ getChange(value){ this.value=value } } })
<div id="children"> <aaa @change="getChange"></aaa> <h5>{{value}}</h5> </div>
-