前端Vue框架(三)

子组件补充

子组件案列

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset='UTF-8'>
    <title>子组件案例</title>
    <style>
        .wrap {
             calc(200px * 4 + 80px);
            margin: 0 auto;
            user-select: none;
        }
        .box {
             200px;
            height: 360px;
            /*border: 1px solid black;*/
            background-color: rgba(10, 200, 30, 0.5);
            border-radius: 10px;
            float: left;
            margin: 10px;
        }
        .box img  {
             100%;
            /*height: 200px;*/
            border-radius: 50%;
            /*10%;*/
            /*height:15%;*/
            float:right;
            /*margin-left:20px;*/
        }
        .b1{
            text-align: center;
        }

    </style>
</head>
<body>
    <div id="app">
        <div class="wrap"></div>
        <my-tag1 ></my-tag1>
        <my-tag2 ></my-tag2>
        <my-tag3 ></my-tag3>
        <my-tag4 ></my-tag4>
    </div>
</body>
<script src="js/vue.js"></script>
<script>
    let Title = {
        template: `
            <p class="b1">前女友</p>
        `

    };
    let myTag1 = {
        template:`
            <div class="box">
                <img src="img/111.jpg" alt="">
                <Title></Title>
                <p class="b1" @click="fn">抱了{{ num }}次</p>
</div>
      `,
        components: {
            Title
        },
        data(){
            return {
                num: 0
            }
        },
        methods:{
            fn(){
                this.num ++
            }
        }
    };
    let myTag2 = {
        template:`
            <div class="box">
                <img src="img/222.jpg" alt="">
                 <Title></Title>
                 <p class="b1" @click="fn">抱了{{ num }}次</p>
</div>
        `,
        components:{
            Title
        },
         data(){
            return {
                num: 0
            }
        },
        methods:{
            fn(){
                this.num ++
            }
        }
    };
    let myTag3 = {
        template:`
            <div class="box">
                <img src="img/333.jpg" alt="">
                <Title></Title>
                <p class="b1" @click="fn">抱了{{ num }}次</p>

</div>
        `,
        components:{
            Title
        },
         data(){
            return {
                num: 0
            }
        },
        methods:{
            fn() {
                this.num ++
            }
        }
    };
    let myTag4 = {
        template:`
            <div class="box">
                <img src="img/444.jpg" alt="">
                <Title></Title>
                <p class="b1" @click="fn">抱了{{ num }}次</p>
</div>
        `,
        components:{
            Title
        },
         data(){
            return {
                num: 0
            }
        },
        methods:{
            fn(){
                this.num ++
            }
        }
    };
    new Vue({
        el:'#app',
        components:{
            myTag1,
            myTag2,
            myTag3,
            myTag4
        }
    })
</script>
</html>

案列二

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title></title>
    <style>
        .wrap {
             calc(200px * 4 + 80px);
            margin: 0 auto;
            user-select: none;
        }
        .box {
             200px;
            height: 260px;
            /*border: 1px solid black;*/
            background-color: rgba(10, 200, 30, 0.5);
            border-radius: 10px;
            float: left;
            margin: 10px;
        }
        .box img {
             100%;
            /*height: 200px;*/
            border-radius: 50%;
        }
        .box p {
            text-align: center;
        }
    </style>
</head>
<body>
    <div id="app">
        <div class="wrap">
            <tag></tag>
            <tag></tag>
            <tag></tag>
            <tag></tag>
        </div>
    </div>
</body>
<script src="js/vue.js"></script>
<script>
    let titleTag = {
        template: `
        <p>
            <b>
                清纯妹
            </b>
        </p>
        `,
    };

    let tag = {
        template: `
        <div class="box">
            <img src="img/111.jpg" alt="">
            <title-tag />
            <p @click="fn">
                锤它:<b>{{ num }}下</b>
            </p>
        </div>
        `,
        // 能被复用的组件(除了根组件),数据都要做局部化处理,因为复用组件后,组件的数据是相互独立的
        // data的值为绑定的方法的返回值,返回值是存放数据的字典
        data () {
            return {
                num: 0
            }
        },
        methods: {
            fn() {
                this.num ++
            }
        },
        components: {
            titleTag,
        }
    };

	new Vue({
		el: '#app',
        components: {
		    tag,
        }
	});

    `
    class P:
        num = 0
        def __init__(n):
            this.n = n
    p1 = P()
    p2 = P()
    P.num = 10
    p1.num
    p2.num
    `

</script>
</html>

组件传参--父传子

数据交互--父传子--通过绑定属性的方式
1.父组件提供数据
2.在父组件模板中,为子组件标签设置自定义属性,且自定义属性绑定的值由父组件提供
3.在子组件实例中,用过props实例成员获得自定义属性,然后就可以使用父组件的数据

使用父组件的数据,在子组件的模板上进行渲染步骤流程:

​ 1.先创建子组件;
​ 2.在父组件中注册子组件(components)
​ 3.在父组件模板中渲染出子组件,且为子组件标签设置自定义属性,自定义属性值由父组件提供
​ 4.在子组件实例中,通过props实例成员获得自定义属性,便可使用父组件提供的数据

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset='UTF-8'>
    <title>父传子</title>
    <style>
        .wrap {
             calc(200px * 4 + 80px);
            margin: 0 auto;
            user-select: none;
        }
        .box {
             200px;
            height: 260px;
            /*border: 1px solid black;*/
            background-color: rgba(10, 200, 30, 0.5);
            border-radius: 10px;
            float: left;
            margin: 20px;
        }
        .box img {
             100%;
            height: 160px;
            border-radius: 50%;
            margin: 0 auto;
            display: block;
        }
        .box p {
            text-align: center;
        }
    </style>
</head>
<body>
    <div id="app">
        <son v-for="photo in photos" v-bind:photo="photo"></son>
    </div>
</body>
<script src="js/vue.js"></script>
<script>
    let photos = [
        {title: '女友1号', img:'img/111.jpg',},
        {title: '女友2号', img:'img/222.jpg',},
        {title: '女友3号', img:'img/333.jpg',},
        {title: '女友4号', img:'img/444.jpg',},
        {title: '女友1号', img:'img/111.jpg',},
        {title: '女友2号', img:'img/222.jpg',},
        {title: '女友3号', img:'img/333.jpg',},
        {title: '女友4号', img:'img/444.jpg',},
    ];
    let son = {
        // 在组件内部就可以通过设置的自定义属性,拿到外部选择子组件提供给属性的的值
        props:['photo'],
        template: `
        <div class="box">
               <img :src="photo.img" alt="">
               <p>{{ photo.title }}</p>
               <p @click="fn">亲亲{{ num }}下</p>
            </div>
        `,
        data(){
            return{
                num: 0
            }
        },
        methods:{
            fn(){
                this.num ++
            }
        }
    };

    new Vue({
        el:'#app',
        data:{
            photos,
        },
        components: {
            son
        }
    });
    /**
     * 1.数据在父组件中产生
     * 2.在父组件中渲染组件,子组件绑定自定义属性,附上父组件中的数据
     * 3.子组件自定义属性在子组件中的props成员中进行声明(采用字符串发射机制)
     * 4.在子组件内部,就可以用props声明的属性(直接作为变量)来使用父组件的数据
     */
</script>
</html>
<style>
    .info {
        text-align: center;
         200px;
        padding: 3px;
        box-shadow: 0 3px 5px 0 pink;
        float: left;
        margin: 5px;
    }
    .info img {
         200px;
    }
</style>
<div id="app">
    <!-- 2) 在父组件模板中,为子组件标签设置自定义属性,绑定的值由父组件提供 -->
    <info v-for="info in infos" :key="info.image" :myinfo="info"></info> 
</div>
<script src="js/vue.js"></script>
<script>
    let infos = [
        {
            image: 'img/001.png',
            title: '小猫'
        },
        {
            image: 'img/002.png',
            title: '蛋糕'
        },
        {
            image: 'img/003.png',
            title: '蓝糕'
        },
        {
            image: 'img/004.png',
            title: '恶犬'
        },
    ];
  //局部组件
    let info = {
        template: `
        <div class="info">
            <img :src="myinfo.image" alt="">
            <p><b>{{ myinfo.title }}</b></p>
        </div>
        `,
        // 3) 在子组件实例中,通过props实例成员获得自定义属性
        props: ['myinfo']
    };

  //父组件
    new Vue({
        el: '#app',
        components: {
            info,
        },
        data: {
            infos,  // 1) 父组件提供数据
        }
    })
</script>

组件交互--子传父(由子组件传递数据)

组件交互--子传父
1.数据由子组件提供
2.子组件内部通过触发系统事件,发送一个自定义事件,将数据携带出来
3.父组件为子组件标签的自定义属性通过方法实现,就可以通过参数拿到子组件传递处理的参数
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset='UTF-8'>
    <title>作业</title>
    <style>
        .box {
             200px;
            height: 260px;
            /*border: 1px solid black;*/
            background-color: rgba(10, 200, 30, 0.5);
            border-radius: 10px;
            float: left;
            margin: 20px;
        }
        .box img {
             100%;
            height: 160px;
            border-radius: 50%;
            margin: 0 auto;
            display: block;
        }
    </style>
</head>
<body>
    <div id="app">
        <p><button @click="fn('tv')">电视</button></p>
        <p><button @click="fn('phone')">手机</button></p>
        <!--<div v-for="da in das">-->
            <!--<img :src="da.img"/>-->
            <!--<p>{{ da.title }}</p>-->
        <!--</div>-->
        <tag v-for="tv in das" :tv="tv" @change="changeFn"></tag>
        <h2 style="color: red;">{{ index }}</h2>


        </div>
</body>
<script src="js/vue.js"></script>
<script>
    let ad_data = {
        tv: [
        {title: 'tv1', img:'img/111.jpg',},
        {title: 'tv2', img:'img/222.jpg',},
        {title: 'tv3', img:'img/333.jpg',},
        {title: 'tv4', img:'img/444.jpg',},
        ],
        phone:[
        {title: 'phone1', img:'img/111.jpg',},
        {title: 'phone2', img:'img/222.jpg',},
        {title: 'phone3', img:'img/333.jpg',},
        {title: 'phone4', img:'img/444.jpg',},
        ]
    };
    let tag = {
        props: ['tv'],
        template: `
			// 1.点击触发子组件该事件
            <div class="box" @click="choiceFn">
                <img :src="tv.img" alt="">
                <p>{{ tv.title }}</p>
            </div>
             `,
        methods:{
            choiceFn(){
                // 2.自行触发,提供数据,将数据用事件形式传给父组件
                // 注意:$emit()中第一个参数是自定义的属性名,不是函数名)
                this.$emit('change',this.tv)
            }
        }
    };

    new Vue({
        el:'#app',
        data:{
            das: ad_data['tv'],
            index: '未选任何广告'
        },
        methods:{
            fn(ad){
                this.das = ad_data[ad]
            },
            // 3.接收子组件提供的数据,触发子组件提供的事件
            changeFn(dat){
                console.log(dat);
                this.index = dat.title

            }
        },
        components:{
            tag
        }


    })
    // console.log(data)
</script>
</html>
<style>
    .close:hover {
        cursor: pointer;
        color: red;
    }
</style>
<div id="app">
    <p>
        <input type="text" v-model="userMsg">
        <button @click="sendMsg">留言</button>
    </p>
    <ul>
        <!-- 2) 子组件内部通过触发系统事件,发送一个自定义事件,将数据携带出来 -->
        <msg-li @remove_msg="removeAction" v-for="(msg, i) in msgs" :msg="msg" :index="i" :key="msg"></msg-li>
    </ul>
</div>
<script src="js/vue.js"></script>
<script>
    let msgLi = {
        template: `
        <li>
            <span class="close" @click="deleteMsg(index)">x </span>
            <span>第{{ index + 1 }}条:</span>
            <span>{{ msg }}</span>
        </li>
        `,
        props: ['msg', 'index'],
        methods: {
            // 最先触发系统的click事件
            deleteMsg(i) {
                // 1) 数据由子组件提供
                // $emit('自定义事件名', 参数们)
                this.$emit('remove_msg', i);
            }
        }
    };
    new Vue({
        el: '#app',
        data: {
            msgs: [],
            userMsg: ''
        },
        methods: {
            sendMsg() {
                if (this.userMsg) {
                    this.msgs.push(this.userMsg);
                    this.userMsg = "";
                }
            },
            // 3) 父组件位子组件标签的自定义属性通过方法实现,就可以通过参数拿到子组件传递处理的参数
            removeAction(i) {
                this.msgs.splice(i, 1)
            }
        },
        components: {
            msgLi
        }
    })
</script>
原文地址:https://www.cnblogs.com/chmily/p/11871750.html