Vue.js使用-组件(上篇)

1.什么是组件
组件可以理解为定义的一个view模块,可重复使用。

2.组件使用
1)创建组件
var myComponent = Vue.extend({
template: '

this is a component
'
})
2)注册组件
Vue.component('my-component',myComponent)
3)使用示例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div id="app">
        <my-component></my-component>
    </div>
</body>
<script src="js/vue.js"></script>
<script>
    var myComponent = Vue.extend({
        template: '<div>this is a component</div>'
    })

    Vue.component('my-component', myComponent)

    new Vue({
        el: '#app'
    })
</script>
</html>

运行结果:

简化写法,可以省略创建和注册的步骤,直接在Vue对象中定义,会默认创建和注册。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div id="app">
        <my-component></my-component>
    </div>
</body>
<script src="js/vue.js"></script>
<script>
    new Vue({
        el: '#app',
        components: {
            'my-component':{
                template: '<div>this is a component</div>'
            }
        }
    })
</script>
</html>

运行结果:

3.组件全局注册和局部注册
上例中,my-component在所有view中都可以使用,如何做到只能在某个view才能使用呢?
可以将component注册到某个view的components属性

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div id="app1">
        <my-component></my-component>
    </div>
    <div id="app2">
        <my-component></my-component>
    </div>
</body>
<script src="js/vue.js"></script>
<script>
    var myComponent = Vue.extend({
        template: '<div>this is a component</div>'
    })

    new Vue({
        el: '#app1',
        components: {
            'my-component': myComponent
        }
    })

    new Vue({
        el: '#app2'
    })
</script>
</html>

运行结果:

可以看到在app2中使用my-component会报错

4.组件的嵌套
父组件和子组件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div id="app">
        <parent-component></parent-component>
    </div>
</body>
<script src="js/vue.js"></script>
<script>
    var Child = Vue.extend({
        template: '<div>this is child component</div>'
    })

    var Parent = Vue.extend({
        template: '<div>this is parent component</div><div><child-component></child-component></div>',
        components: {
            'child-component': Child
        }
    })

    Vue.component('parent-component', Parent)

    new Vue({
        el: '#app'
    })
</script>
</html>

运行结果:

5.组件中使用Vue对象的Model属性props
组件是独立的,所以要使用Model的属性,需要在组件中定义props字段,然后再view中绑定props为对应的model值。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div id="app">
        <my-component v-bind:my-name="name" v-bind:my-age="age"></my-component>
    </div>
</body>
<script src="js/vue.js"></script>
<script>
    new Vue({
        el: '#app',
        data: {
            name: 'shijingjing',
            age: 28
        },
        components: {
            'my-component': {
                'template': '<div>{{ myName }} {{myAge}}</div>',
                props: ['myName', 'myAge']
            }
        }
    })
</script>
</html>

运行结果:

需要注意的是html是不分大小写的,所以在组件中定义的属性myName,在view中对应的为my-name

6.props绑定类型
修改model属性值,组件中绑定的model值会变化吗?
1)单向绑定

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div id="app">
        <input type="text" v-model="name">
        <input type="text" v-model="age">
        <my-component v-bind:my-name="name" v-bind:my-age="age"></my-component>
    </div>
</body>
<script src="js/vue.js"></script>
<script>
    new Vue({
        el: '#app',
        data: {
            name: 'shijingjing',
            age: 28
        },
        components: {
            'my-component': {
                'template': '<div><input type="input" v-model="myName"><input type="input" v-model="myAge"></div>',
                props: ['myName', 'myAge']
            }
        }
    })
</script>
</html>

运行结果:

可以看到,修改model值,组件中绑定的model值也会变化;修改组件中绑定的model值,model的值不会变化。
2)双向绑定
组件中绑定属性后加上.sync,都可以同步变化。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div id="app">
        <input type="text" v-model="name">
        <input type="text" v-model="age">
        <my-component v-bind:my-name.sync="name" v-bind:my-age.sync="age"></my-component>
    </div>
</body>
<script src="js/vue.js"></script>
<script>
    new Vue({
        el: '#app',
        data: {
            name: 'shijingjing',
            age: 28
        },
        components: {
            'my-component': {
                'template': '<div><input type="input" v-model="myName"><input type="input" v-model="myAge"></div>',
                props: ['myName', 'myAge']
            }
        }
    })
</script>
</html>

运行结果:

3)单次绑定
.once组件值绑定后,就不会再随着model的变化而变化。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div id="app">
        <input type="text" v-model="name">
        <input type="text" v-model="age">
        <my-component v-bind:my-name.once="name" v-bind:my-age.once="age"></my-component>
    </div>
</body>
<script src="js/vue.js"></script>
<script>
    new Vue({
        el: '#app',
        data: {
            name: 'shijingjing',
            age: 28
        },
        components: {
            'my-component': {
                'template': '<div><input type="input" v-model="myName"><input type="input" v-model="myAge"></div>',
                props: ['myName', 'myAge']
            }
        }
    })
</script>
</html>

运行结果:

7.组件的另一种声明方式
在上面的示例中,组件的template都是在js中定义的,view和js混在一起的方式是不提倡的,因此,比较优雅的一种方式是使用