<zszxz-componen>
就是 自定义标签, 命名格式使用分割符号;需要在组件中添加template
才可以显示内容;
<div id="app">
<zszxz-component></zszxz-component>
</div>
<script type="text/javascript">
Vue.component('zszxz-component',{
// 选项
template: '<div>知识追寻者 </div>'
})
var app = new Vue({
el: '#app',
data: {
}
})
</script>
渲染结果
<div id="app">
<div>知识追寻者 </div>
</div>
在 vue实例中可以使用 components
选项 注入局部组件。
<div id="app">
<zszxz-component></zszxz-component>
</div>
<script type="text/javascript">
var child = {
template: '<div>知识追寻者 </div>'
}
var app = new Vue({
el: '#app',
components : {
'zszxz-component' : child
}
})
</script>
在特殊的标签中只能使用特殊的子标签;比如<table>
标签 中只能 存放<th>
,<td>
,<tr>
; 此时就需要使用 is 属性 挂载标签;
<div id="app">
<table >
<tbody is='zszxz-component'></tbody>
</table>
</div>
<script type="text/javascript">
var child = {
template: '<div>知识追寻者 </div>'
}
var app = new Vue({
el: '#app',
components : {
'zszxz-component' : child
}
})
</script>
components 中还可以放 methods, computed, data等; data 必须是个函数;
data: function () { return { count: 0 } }
三个按钮达到互不影响示例如下,如果data是外部对象则三个按钮都会对一个count进行计数;
<div id="app">
<zszxz-component></zszxz-component>
<zszxz-component></zszxz-component>
<zszxz-component></zszxz-component>
</div>
<script type="text/javascript">
var child = {
template: '<button @click="count++">{{count}} </button>',
data : function(){
return {
count:0
}
}
}
var app = new Vue({
el: '#app',
components : {
'zszxz-component' : child
}
})
</script>
组件间的通信使用props实现;父组件向子组件正向传递,子组件接受数据进行渲染;子组件使用props 声明从父组件接受到数据,其方式有2种,分别是字符串数组和对象;
<div id="app">
<zszxz-component content="父级内容"></zszxz-component>
</div>
<script type="text/javascript">
var child = {
props: ['content'],
template: '<div>{{content}}</div>',
}
var app = new Vue({
el: '#app',
components : {
'zszxz-component' : child
}
})
</script>
渲染结果
<div>父级内容</div>
如果传递的动态数据则需要使用v-bind进行动态绑定props值;
<div id="app">
<input type="text" v-model="message" placeholder="请输入">
<zszxz-component :content="message"></zszxz-component>
</div>
<script type="text/javascript">
var child = {
props: ['content'],
template: '<div>{{content}}</div>',
};
var app = new Vue({
el: '#app',
components : {
'zszxz-component' : child
},
data: {
message: ''
}
})
</script>
单向数据流
在 data 里面再声明一个变量实现 子组件与父组件间变量的解耦关系,之间操作content变量就不会改变init-content的值;
<div id="app">
<zszxz-component :init-content="6666"></zszxz-component>
</div>
<script type="text/javascript">
Vue.component('zszxz-component',{
props: ['initContent'],
template: '<div>内容:{{content}}</div>',
data: function() {
return {
content: this.initContent
}
},
});
var app = new Vue({
el: '#app',
})
</script>
HTML不区分大小写,使用DOM模板时,驼峰命名的props名称要转为分隔符命名
props验证
Vue.component('my-component', {
props: {
// 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)
propA: Number,
// 多个可能的类型
propB: [String, Number],
// 必填的字符串
propC: {
type: String,
required: true
},
// 带有默认值的数字
propD: {
type: Number,
default: 100
},
// 带有默认值的对象
propE: {
type: Object,
// 对象或数组默认值必须从一个工厂函数获取
default: function () {
return { message: 'hello' }
}
},
// 自定义验证函数
propF: {
validator: function (value) {
// 这个值必须匹配下列字符串中的一个
return ['success', 'warning', 'danger'].indexOf(value) !== -1
}
}
}
})
vue.1.x ; v-on 除了 监听事件之外还可以自定义组件之间的事件;子组件使用$emit() 触发事件(子组件通向父组件),父组件使用$on来监听子组件事件;
<div id="app">
<p>总数 : {{total}} </p>
<zszxz-component @increase="getTotal" @reduce="getTotal"></zszxz-component>
</div>
<script type="text/javascript">
Vue.component('zszxz-component',{
template: '<div><button @click="addCount"> +1 </button> \
<button @click="subCount"> -1 </button> </div>',
data: function() {
return {
counter: 0
}
},
methods: {
addCount: function() {
this.counter++;
this.$emit('increase',this.counter);
},
subCount: function() {
this.counter--;
this.$emit('reduce',this.counter);
}
}
});
var app = new Vue({
el: '#app',
data: {
total: 0
},
methods:{
getTotal: function(total){
this.total = total;
}
}
})
</script>
如果想监听原生事件可以使用v-on
的 .native
修饰符
<base-input v-on:focus.native="onFocus"></base-input>
vue.2.x 可以使用 v-model 实现 组件自定义事件;
<div id="app">
<p>总数 : {{total}} </p>
<zszxz-component v-model="total"></zszxz-component>
</div>
<script type="text/javascript">
Vue.component('zszxz-component',{
template: '<div><button @click="addCount"> +1 </button></div>',
data: function() {
return {
counter: 0
}
},
methods: {
addCount: function() {
this.counter++;
this.$emit('input',this.counter);
}
}
});
var app = new Vue({
el: '#app',
data: {
total: 0
},
})
</script>
使用bus 可以实现 组件间通讯;如买房租房,bus就是第三方中介;
<div id="app">
<p>消息 : {{message}} </p>
<zszxz-component></zszxz-component>
</div>
<script type="text/javascript">
var bus = new Vue();
Vue.component('zszxz-component',{
template: '<div><button @click="handleEvent"> 事件处理 </button></div>',
methods: {
handleEvent: function() {
bus.$emit('on-message','来自组件的内容');
}
}
});
var app = new Vue({
el: '#app',
data: {
message: ''
},
mounted: function(){
var _this = this;
bus.$on('on-message', function(msg){
_this.message = msg;
})
}
})
</script>
当组件较多时,可以通过 ref 属性为每个组件指定索引名称;父组件通过$refs来访问子组件;
<div id="app">
<p>内容:{{content}}</p>
<button @click="handleRef">点击</button>
<zszxz-component ref="zszxz"></zszxz-component>
</div>
<script type="text/javascript">
Vue.component('zszxz-component',{
template: '<div>子组件 </div>',
data: function(){
return {
message: '知识追寻者'
}
}
});
var app = new Vue({
el: '#app',
data: {
content: ''
},
methods: {
handleRef : function(){
// 通过 $refs访问指定实例
var msg = this.$refs.zszxz.message;
this.content = msg;
}
}
})
</script>