Vue组件化开发2

组件模板分离的写法

组件分离的写法有两种一种是将组件内容通过script标签封装起来,通过给script定义的id来进行注册,另外一种是通过template模板标签将组件内容封装起来,同样是通过template定义的id来进行组件的注册,推荐使用template这种方式。

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    {{message}}
    <cpn></cpn>
</div>
<!--1.script标签,注意:类型必须是text/x-template-->
<!--<script type="text/x-template" id="cpn">-->
<!--<div>-->
    <!--<h2>我是标题</h2>-->
    <!--<p>我是内容,111</p>-->
<!--</div>-->
<!--</script>-->

<!--2、template标签-->
<template id="cpn">
    <div>
        <h2>我是标题</h2>
        <p>我是内容,222</p>
    </div>
</template>

<script src="../js/vue.js"></script>
<script>
    // 1、注册一个全局组件
    Vue.component('cpn',{
        template: '#cpn'
    })


    const app = new Vue({
        el: '#app',
        data:{
            message: 'hello'
        }
    })
</script>
</body>
</html>

组件的数据存放问题

组件中也可以定义自己组件内部的数据,可以类比Vue实例中的data,代码如下:

// 1、注册一个全局组件
Vue.component('cpn',{
    template: '#cpn',
    data() {
        return {
            title: 'llll'
        }
    }
})

组件中的data为什么是函数

转载:vue中组件的data为什么是一个函数

组件通信

父组件向子组件传递数据
下面展示的主要是向一个id为app的Vue实例中注册了一个id为cpn的组件,其中父组件app通过 :cmmovies="movies" :cmmessage="message 向子组件cpn传递了movies和message两个数据,在子组件对象中的props中分别定义了cmmovies和cmmessage两个参数对movies和message两个数据进行接收,定义的cmmovies和cmmessage可以通过type、default和required来确定该参数的类型、默认值和是否必须。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <cpn :cmmovies="movies" :cmmessage="message"></cpn>
</div>
<template id="cpn">
    <div>
        <ul>
            <li v-for="item in cmmovies">{{item}}</li>
        </ul>
    </div>
</template>
<script src="../js/vue.js"></script>
<script>
    const cpn = {
        template: '#cpn',
        props: {
            //1、类型的限制
            // cmmovies: Array,
            // cmmessage: String
            //2、提供一些默认值
            cmmessage: {
                type: String,
                default: '标题',
                required: true
            },
            cmmovies: {
                type: Array,
                default() {
                    return []
                },
                required: true
            }
        },
        methods: {

        },
        data() {
            return {

            }
        }
    }
    const app = new Vue({
        el: '#app',
        data:{
            message: 'hello',
            movies: ['信条','黑客帝国','三体']
        },
        components: {
            'cpn': cpn
        }
    })
</script>
</body>
</html>

子组件向父组件传递数据

子组件向父组件传递数据只能通过自定义事件来实现,子组件通过this.$emit("事件名",data);来触发事件告诉父组件需要传递什么数据到父组件中。代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!--父组件模板-->
<div id="app">
    <cpn @btnclick="cpnClick"></cpn>
</div>
<!--子组件模板-->
<template id="cpn">
    <div>
        <button v-for="item in categories" @click="itemClick(item)">
            {{item.name}}
        </button>
    </div>
</template>
<script src="../js/vue.js"></script>
<script>
    //子组件
    const cpn = {
        template: '#cpn',
        data() {
            return {
                categories: [
                    {id: 'aaa', name: '热门推荐'},
                    {id: 'bbb', name: '手机数码'},
                    {id: 'ccc', name: '家用家电'},
                    {id: 'ddd', name: '电脑办公'}
                ]
            }
        },
        methods: {
            itemClick(item){
                // console.log(item)
                this.$emit('btnclick',item)
            }
        }
    };
    // 父组件
    const app = new Vue({
        el: '#app',
        data:{
            message: '你好'
        },
        components: {
            cpn
        },
        methods: {
            cpnClick(item){
                console.log('ok',item)
            }
        }
    })
</script>
</body>
</html>

上面的代码首先是通过template模板定义了一个子组件,其中子组件中定义了一组button并且给每一个button都定义了名为itemClick的点击事件,在触发点击事件的时候通过调用this.$emit('btnclick',item)向父组件发送事件名和数据,这个事件名就是在父组件中cpn标签中自定义的@btnclick事件,这个自定义事件的实现就是cpnClick方法,最后父组件的自定义btnclick触发后调用cpnClick方法在控制台打印'ok'和子组件传回来的数据。

以上为个人见解,如有错误的地方,麻烦提醒下,万分感谢。

posted @ 2021-01-28 16:11  lamsacule  阅读(37)  评论(0)    收藏  举报