5.Vue的组件化(下)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://unpkg.com/vue/dist/vue.js"></script>
</head>
<body>
    <!-- 模板组件抽离写法 -->
    <div id="app1">
        <cpn1></cpn1>
        <cpn2></cpn2>
    </div>
    <!-- 方法一 -->
    <script type="text/x-template" id="cpn1">
        <div>
            <p>一:我分离出来了</p>
            <p>一:我分离出来了</p>
        </div>
    </script>
    <!-- 方法二 -->
    <template id="cpn2">
        <div>
            <p>二:我分离出来了</p>
            <p>二:我分离出来了</p>
        </div>
    </template>
    <script>
        Vue.component('cpn1',{
            template: '#cpn1'
        })
        Vue.component('cpn2',{
            template: '#cpn2'
        })
        const app1 = new Vue({
            el: '#app1'
        })
    </script><hr>

    <!--
        组件的数据存放问题
        1. 组件无法访问Vue实例中的data
        2. 组件对象也有一个data属性(也可以有methods等属性)
        3. 该data属性必须是一个函数,且这个函数返回一个对象,对象内保存着数据
    -->
    <div id="app2">
        <cpn3></cpn3>
    </div>
    <template id="cpn3">
        <div>
            <p>动态绑定数据:{{msg}}</p>
            <p>动态绑定数据:{{msg}}</p>
        </div>
    </template>
    <script>
        Vue.component('cpn3',{
            template: '#cpn3',
            data() {
                return {
                    msg: '我是动态数据'
                }
            }
        })
        const app2 = new Vue({
            el: '#app2'
        })
    </script><hr>

    <!-- 
        父子组件通信
        子组件是不能引用父组件或者Vue实例的数据的,但开发中常常需要一些数据从上层传递到下层
        比如在一个页面中,我们从服务器请求到了很多数据,其中一部分数据并不是由整个页面的大组件展示
        而是需要下面的子组件进行展示,这时候就需要让大组件(父组件)将数据传递给小组件(子组件)
    -->

    <!-- 父传子:Pass props -->
    <div id="app3">
        <cpn4 v-bind:cpeople="people" :cmsg="msg" :cdemo="demo"></cpn4>
    </div>
    <template id="cpn4">
        <div>
            <p>人物数组:{{cpeople}}</p>
            <p>msg对象:{{cmsg}}</p>
            <p>demo对象:{{cdemo}}</p>
        </div>
    </template>
    <script>
        const cpn4 = {
            template: '#cpn4',
            // props: ['cpeople']    使用一:不进行类型限制
            props: {  
                // 使用二:进行类型限制
                cpeople: Array,
                cmsg: String,
                cdemo: { 
                    type: Object,
                    default: {  // 还可以添加默认值
                        name: "小王",
                        age: 18
                    },
                    required: true // 设置为必传
                }
            }
        }
        // Vue环境(根组件)
        const app3 = new Vue({
            el: '#app3',
            data: {
                people: ['张三','李四','王五','赵六'],
                msg:{
                    name: '麻子',
                    weight: "120斤"
                },
                demo:{
                    name:"小李",
                    age: 19
                }
            },
            components: {
                cpn4
            }
        })
    </script><hr>

    <!-- 
        子传父
        当子组件需要向父组件传递事件时,就要用到自定义事件
        之前学习的 v-on 不仅可以用来监听DOM事件,也可以用于监听组件间的自定义事件
        自定义事件流程:
        在子组件中,通过
    -->
    <!-- 父组件模板 -->
    <div id="app4">
        <cpn5 @itemclick="cpnClick"></cpn5>
    </div>
    <!-- 子组件模板 -->
    <template id="cpn5">
        <div>
            <button v-for='item in categories' @click="btnClick(item)">{{item.name}}</button>
        </div>
    </template>
    <script>
        // 1. 子组件
        const cpn5 = {
            template: '#cpn5',
            data() {
                return {
                    categories: [
                        {id: 'aaa', name: '热门推荐'},
                        {id: 'bbb', name: '手机数码'},
                        {id: 'ccc', name: '家具家电'},
                        {id: 'ddd', name: '电脑办公'}
                    ]
                }
            },
            methods: {
                btnClick: function(item) {
                    // $emit('发送给父组件的事件')
                    this.$emit('itemclick')
                }
            }
        }
        // 2. 父组件
        const app4 = new Vue({
            el: '#app4',
            data: {
                
            },
            components: {
                cpn5
            },
            methods: {
                cpnClick() {
                    console.log('cpnClick');
                }
            }
        })
    </script><hr>

    <!-- 父子组件通信--双向绑定 -->
    <div id="app5">
        <cpn6   :number1="num1" 
                :number2="num2"
                @num1change="num1change"
                @num2change="num2change"/>
    </div>
    <template id="cpn6">
        <div>
            <p>props:{{number1}}</p>
            <p>data:{{dnumber1}}</p>
            <!-- <input type="text" v-model="dnumber1"> -->
            <input type="text" :value="dnumber1" @input="num1Input">
            <p>props:{{number2}}</p>
            <p>data:{{dnumber2}}</p>
            <!-- <input type="text" v-model="dnumber2"> -->
            <input type="text" :value="dnumber2" @input="num2Input">
        </div>
    </template>
    <script>
        const app5 = new Vue({
            el: '#app5',
            data: {
                num1: 1,
                num2: 0
            },
            methods: {
                num1change(value) {
                    // console.log(typeof value); 默认传字符串类型
                    this.num1 = parseInt(value); // 转换为数字类型
                },
                num2change(value) {
                    // console.log(typeof value);
                    this.num2 = parseInt(value);
                }
            },
            components: {
                cpn6: {
                    template: '#cpn6',
                    props: {
                        number1: Number,
                        number2: Number
                    },
                    data() {
                        return {
                            dnumber1: this.number1,
                            dnumber2: this.number2
                        }
                    },
                    methods: {
                        num1Input(event) {
                            this.dnumber1 = event.target.value;
                            this.$emit('num1change',this.dnumber1)
                        },
                        num2Input(event) {
                            this.dnumber2 = event.target.value;
                            this.$emit('num2change',this.dnumber2)
                        },
                    }
                }
            }
        })
    </script>

</body>
</html>

更多相关内容大家可以前往我的个人博客浏览:eyes++的个人空间

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值