组件基础
组件是可复用的 Vue 实例
每用一次组件,就会有一个它的新实例被创建
<div id="app">
<button-counter></button-counter>//各自维护自己的实例
<button-counter></button-counter>//每次使用组件
<button-counter></button-counter>//都会创建一个新的实例
</div>
一个组件的 data 选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝
// 定义一个名为 button-counter 的新组件
Vue.component('button-counter', {
data: function () {
return {
count: 0
}
},
template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>'
})//这是全局注册的组件(Vue.component)
var app = new Vue({
el: '#app',
})
组件注册
待更
通过prop向子组件传递数据
一个组件默认可以拥有任意数量的 prop,任何值都可以传递给任何 prop
<div id="app">
<button-counter v-for="post in posts"
v-bind:key = "post.id"
v-bind:title = "post.text+count">//此处count为实例#app的属性
</button-counter>
<button @click = "count++" v-bind:title = "count">I am</button>
</div>
Vue.component('button-counter',{
data: function(){
return {
count:0,
}
},
props:['title','key']//"key"是保留属性不能用作组件属性
template:'<button @click = "count++">{{title+count}}</button>'//此处count为当前组件的属性
})
var app = new Vue({
el: '#app',
data:{
count:111,
posts:[
{id:1,text:"I am one title"},
{id:2,text:"I am two title"},
{id:3,text:"I am three title"},
]
}
})
prop较多时可以用以下方法
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-C6E5z422-1577934789309)(https://s2.ax1x.com/2019/12/29/lurjN4.png)]
监听子组件事件
Vue 实例提供了一个自定义事件的系统来解决这个问题。父级组件可以像处理 native DOM事件一样通过v-on 监听子组件实例的任意事件
// 父组件(创建的每个实例?)
<button-counter v-for="post in posts"
v-bind:key = "post.id"
v-bind:title = "post.text+count"
v-on:font-enlarge = "fontsize += 0.1">
</button-counter>
子组件可以通过调用 $emit 方法 并传入事件名称来触发一个事件
// 子组件(button按钮)
template:`
<div>
<button @click = '$emit("font-enlarge")'>font变大</button>
<p @click = "count++">{{title+count}}</p>
</div>
`
组件的事件抛出值
<button v-on:click="$emit('enlarge-text', 0.1)">
Enlarge text
</button>
当父级组件监听这个子组件的某个事件的时候
我们可以通过 $event 访问到被抛出的这个值
<blog-post
...
v-on:enlarge-text="postFontSize += $event"
></blog-post>
如果这个事件处理函数是一个方法
<blog-post
...
v-on:enlarge-text="onEnlargeText"
></blog-post>
那么这个值将会作为第一个参数传入这个方法
methods: {
onEnlargeText: function (enlargeAmount) {
this.postFontSize += enlargeAmount
}
}
在组件中使用v-model
v-model 是数据的双向绑定
在组件中无法直接使用,那么应该怎样操作呢!!!
<input v-model="searchText">
// 这两段程序是等价的
<input
v-bind:value="searchText"
v-on:input="searchText = $event.target.value"//本次input事件的值
>
而在组件中使用v-model时
要将$event.target.value 写成 $event
为了使创建出的实例能够正常工作,这个组件内的 必须:
- 将其 value 特性绑定到一个名叫 value 的 prop 上
- 在其 input 事件被触发时,将新的值通过自定义的 input 事件抛出
template: `
<input
v-bind:value="value"
v-on:input="$emit('input', $event.target.value)"
>
`
至此 v-model 可以在组件实例中正常运行了
动态组件
元素是vue 里面的一个内置组件
实现动态切换的关键在于的 “is” 特性通过 v-bind:is 来给 “is” 绑定的值传入一个组件名,就会切换到这个组件
<component v-bind:is = "whichtmeplate">这里的内容无法显示</component>
<button @click = "selectcom('a')"> 选择a</button>
<button @click = "selectcom('b')"> 选择b</button>
<button @click = "selectcom('c')"> 选择c</button>
var app=new Vue({
el: '#app',
data:{whichtmeplate:""},
components:{
acomp:{
template:`
<p>这里是组件A</p>
`
},
bcomp:{
template:`
<p>这里是组件B</p> `
},
ccomp:{
template:`
<p>这里是组件C</p>
`
}},
methods:{
selectcom:function(item){
this.whichtmeplate=item+"comp"}
}
})
解析DOM模板时的注意事项
有些 HTML 元素,诸如 ul、ol、table 和 select,对于哪些元素可以出现在其内部是有严格限制的。而有些元素,诸如 li、tr 和 option,只能出现在其它某些特定的元素内部
<table>
<blog-post-row></blog-post-row>
</table>
// 当自定义组件 <blog-post-row> 作为无效的内容提升到外部,并导致最终渲染结果出错时
// 这是一种替代方案
<table>
<tr is="blog-post-row"></tr>
</table>
需要注意的是如果我们从以下来源使用模板的话,这条限制是不存在的:
- 字符串 (例如:template: ‘…’)
- 单文件组件(.vue)
- script type = “text/x-template”(带<>)