1.Vue中组件 #

使用方法Vue.component(tag, constructor)

1.1 创建hello world组件 #

<hello></hello>
var hello = Vue.extend({
  template:'<div>hello world</div>'
})
Vue.component('hello',hello);
var vm = new Vue({
  el:"#app"
});

要先注册组件再创造实例

1.2 创建父子级组件 #

在父组件内注册子组件

var Child = Vue.extend({
    template:'child'
});
var Parent = Vue.extend({
    template: 'Parent <my-component></my-component>',
    components: {
        //<my-component> 只能用在父组件模板内
        'my-component': Child
    }
});
Vue.component('parent',Parent);

直接注册组件,语法糖形式

Vue.component('parent',{
    template:'<div>Hello</div><child></child>',
    components: {
        'child': {
            template:'<div>world</div>'
        }
    }
});

1.3 模板的is特性 #

防止元素内部的自定义标签被提到元素的外面,导致渲染不正确。

<table>
  <tr is="my-component"></tr>
</table>

2.组件传递数据 #

先从属性传递到props,在从props取出来绑定到组件里

2.1 传递静态属性 #

Vue.component('parent',{
    template:'<span>Hello</span><child></child>{{msg}}',
    props:['msg'], //此时获得的为字符串1
    components:{
        child:{
            template:'<span>world</span>'
        }
    }
});
var vm = new Vue({
    el:'#app'
})

2.2 传递动态属性 #

<parent :msg = 1></parent><!--此时传递的是数字类型,并且可以获取data上的属性-->

父子组件不能通用属性 属性采用-线,props采用驼峰命名

3.props验证 #

<div id="app">
    <parent :me="message"></parent>
</div>
<template id="tmpl">
    {{me}}
</template>

3.1 验证属性 #

类型 用法 用途
type type:[String, Number] 类型
required required:true 必填
default function () {return 2000;} 默认值
validator validator: function (v) {return true} 验证器
coerce coerce: function (v) {return v+200;} 转换字符串
twoWay twoWay:true 双向绑定
Vue.component('parent',{
    template:'#tmpl',
    props:{
        'me':{
            type:[String],
            required:true,
            default: function () {
                return 2000;
            },
            validator: function (v) {
                return v=='hello200'
            },
            coerce: function (v) {
                return v+200;
            }
        },
    }
});

3.2 双向绑定 #

设置双向绑定属性

<div id="app">
    <input type="text" v-model="data">
    <parent  :message.sync="data"></parent>
</div>
<template id="tmpl">
    <input type="text" v-model="message">
</template>
Vue.component('parent',{
    template:'#tmpl',
    props:{
        'message':{
            twoWay:true
        }
    }
});
var vm = new Vue({
    el:'#app',
    data:{
        message:'hello',
    }
});

4.组件中的通信 #

事件名称 方法用途
$on 监听事件
$emit 在自身出发
$dispatch 沿父链传播包括自己
$broadcast 向下发射事件
<div id="app">
    <parent></parent>
</div>

<template id="parent">
    父亲
    <child></child>
    <button @click="parent">点爸爸</button>
</template>
<template id="child">
    儿子<button @click="child">点儿子</button>
</template>
var parent = Vue.extend({
    template:'#parent',
    methods:{
        parent: function () { this.$broadcast('broad','爸爸被点击了');},
    },
    events:{
        dispatch: function (data) {alert(data)},
    },
});
var child = Vue.extend({
    template:'#child',
    events:{
        broad: function (data) {alert(data);},
        self: function (data) {alert(data);},
        dispatch:function (data) {alert(data)},
        emit:function (data) {alert(data)}
    },
    methods:{
        child: function () {
            this.$dispatch('dispatch','儿子被点击了');
            this.$emit('emit','自己被点击了');
        }
    }
});
Vue.component('parent',parent);
Vue.component('child',child);
var vm = new Vue({
    el:'#app'
})

5.子组件索引 #

<div id="app">
    <hello v-ref:p></hello>
</div>

获取当前实例上的所有组件

var com = Vue.extend({
    template:'<div>hello</div>'
});
Vue.component('hello',com);
var vm = new Vue({
    el:'#app'
});
console.log(vm.$refs.p.$el.style.background='red');

6.slot #

保留组件中的内容,嵌入到组件的内容

<div id="app">
    <hello>
        <span>hello</span>
        <span>world</span>
    </hello>
</div>
var com = Vue.extend({
    template:'<div>vue <slot></slot></div>'
});
Vue.component('hello',com);
var vm = new Vue({
    el:'#app'
});

7.具名slot #

<div id="app">
    <hello>
        <span slot="hello">hello</span>
        <span slot="world">world</span>
    </hello>
</div>

指定嵌套位置

var com = Vue.extend({
    template:'<div>vue <slot name="world"></slot> <slot name="hello"></slot></div>'
});
Vue.component('hello',com);
var vm = new Vue({
    el:'#app'
});

8.实例上的组件 #

<div id="app">
    <input type="radio" v-model="cur" name="group" value="index">index
    <input type="radio" v-model="cur" name="group" value="home">home
    <component :is="cur"></component>
</div>

切换组件

var vm = new Vue({
        el:'#app',
        data:{cur:'index'},
        components:{
            index:{
                template:'<div>hello</div>'
            },
            home:{
                template:'<div>world</div>'
            }
        }
    });

9.增加数据 #

<div id="app">
   {{world}}
</div>

增加数据,刷新视图

var vm = new Vue({
    el:'#app',
    data:{}
});
vm.$set('world',200);
Vue.set(vm.$data,'world',100);

10.异步设置数据 #

<div id="app">
    {{cur}}
</div>

设置数据是异步设置的无法立即获得,需要通过下一事件环获取数据

var vm = new Vue({
        el:'#app',
        data:{cur:'index'},
    });
    vm.cur = 1;
    Vue.nextTick(function () {
        console.log(vm.$el.innerHTML==vm.cur);
    });

11.computed缓存 #

<div id="app">
    {{cur}}
</div>

取消computed缓存问题

var vm = new Vue({
    el:'#app',
    data:{cur:'index'},
    computed:{
        timer:{
            get:function () {
                return new Date();
            },
            cache:false
        }
    }
});
setInterval(function () {
   vm.cur = vm.timer;
},1000);