《Vue.js实战》笔记 第七章(重点)

第七章

1. 第一二节 组件与复用 使用Props传递数据

  • practioce_4.1.html
<!-- 
    第7章
    第一节 组件与复用
    创建组件后要注册,全局注册和局部注册
    局部组件需只能在该实例的作用域内使用
    table里面只能用 is来加载组件


    第二节 使用Props传递数据
    传递字符串可以不使用V-bind 其他不行
    props 要是驼峰变量
    组件return的数据作用域只在组件本身 

 -->
<!DOCTYPE html>
<html>
<head>
    <link rel="stylesheet" type="text/css" media="screen" href="style_4.css" />
    <script src="Vue.js"></script>
</head>
<body>
   <div id="first">
       <div>
           <table>
               <tbody is="my-component-part"></tbody>
           </table>
       </div>
       <div>
           <label>父组件的数据:</label>
           <input type="text" v-model="parentMessage"> 
           <my-component :message="parentMessage" message-text="来自父组件的数据"></my-component>
       </div>   
   </div>
</body>
<script>   
    
    Vue.component("my-component",{
        props: ["messageText","message"],
        template:"<p>{{messageText}}:{{message}}</p>",
        data: function(){
            return {
                counter: 0
            };
        }
    })

    var Child = {
        template:"<div>我是局部组件</div>"
    }
    var first = new Vue({
        el:"#first",
        components: {
            "my-component-part":Child
        },
        data:{
            parentMessage:" It is me !"
        }
    })
</script>
</html>

重要


2. 第三节 组件通信

  • practice_4.2.html
<!-- 

    第7章
    第三节  组件通信
    input v-model
    
    third-component 实现双向绑定的v-model组件的两个要求
    1:接收一个value属性
    2:有新的value时触发input事件
    
    非父子组件通信:
    bus空Vue  forth-component

    父子组件最好用props和$emit来通信
    this.$parent
    this.$children 需要遍历所有组件实例麻烦

    自组建索引$refs fifth-component
 -->
<!DOCTYPE html>
<html>
<head>
    <link rel="stylesheet" type="text/css" media="screen" href="style_4.css" />
    <script src="Vue.js"></script>
</head>
<body>
<div id="first">
    <div>
        <p>总数:{{total}}</p>
        <first-component @increase="handleGetTotal" @reduce="handleGetTotal"></first-component>
    </div>
    <div>
        <p>总数:{{totals}}</p>
        <second-component v-model="totals"></second-component>
    </div>
    <div>
        <p>总数:{{totales}}</p>
        <third-component v-model="totales"></third-component>
        <button @click="handleRe">-1</button>
    </div>
    <div>
        {{message}}
        <forth-component></forth-component>
        <br>{{msg}}<br>
    </div>
    <div>
        <button @click="handleRef">通过ref获取子组件实例</button>
        <fifth-component ref="comA"></fifth-component>
        {{refmsg}}
    </div>
</div>
</body>
<script>   
    
    Vue.component("first-component",{
        template:'\
            <button @click="handleIncrease">+1</button>\
            <button @click="handleReduce">-1</button>\
       ',
        data: function(){
            return {
                counter: 0
            }
        },
        methods: {
            handleIncrease:function(){
                this.counter++;
                this.$emit("increase",this.counter);
            },
            handleReduce:function(){
                this.counter--;
                this.$emit("reduce",this.counter);
            }
        }
    });

    Vue.component("second-component",{
        template:'\
            <button @click="handleClick">+1</button>\
            ',
        data: function(){
            return {
                counter: 0
            }
        },
        methods: {
            handleClick:function(){
                this.counter++;
                this.$emit("input",this.counter);
            }
        }
    });

     Vue.component("third-component",{
         props:['value'],
        template:'<input :value="value" @input="updateValue">',
        methods: {
                updateValue:function(event) {
                    this.$emit("input",event.target.value);
                }
            }
    });

    var bus = new Vue();
    Vue.component("forth-component",{
        template:'<button @click="handleEvent">传递事件</button>',
        methods: {
                handleEvent:function(){
                    bus.$emit("on-message","来自组件forth的内容");
                    this.$parent.msg = "来自forth的内容,修改了父链"
                }
            }
    });

    Vue.component("fifth-component",{
        template:'<p>ref=comA的子组件</p>',
        data:function(){
            return {
                message:"fifth子组件的内容"
            }
        }
    })

    var first = new Vue({
        el:"#first",
        data:{
            total: 0,
            totals: 0,
            totales: 0,
            msg:"Parent",
            message:"",
            refmsg:"",
        },
        mounted:function() {
            var _this = this ;
            bus.$on("on-message",function(msg){
                _this.message = msg;
            })
        },
        methods:{
            handleGetTotal:function(total){
                this.total = total;
            },
            handleRe:function(){
                this.totales--;
            },
            handleRef:function(){
                var msg = this.$refs.comA.message;
                this.refmsg = msg; 
                console.log(msg);
            }
        }
    })
</script>
</html>

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述


3. 第四节 使用slot分发

  • practice_4.3.html
<!-- 

    第7章
    第四节  使用slot分发内容
    作用域
    slot用法
    作用域插槽
    访问slot   $slot
 -->
<!DOCTYPE html>
<html>

<head>
    <link rel="stylesheet" type="text/css" media="screen" href="style_4.css" />
    <script src="Vue.js"></script>
</head>

<body>
    <div id="first">
        <a-component>
            <h2 slot="header">标题</h2>

            <div>
                <p>分发的内容</p>
                <p>更多分发的内容</p>
            </div>
            <div>
                <p slot="footer">底部信息</p>
            </div>
        </a-component>
    </div>

    <div id="second">
        <my-list :books="books">
            <template slot="book" slot-scope="props">
                <li>
                    {{props.bookName}}
                </li>
            </template>
        </my-list>
    </div>
</body>
<script>
    Vue.component("a-component", {
        template: '\
            <div>\
            <slot name="header"></slot>\
                <slot>\
                    <p>如果父组件没有插入内容,我将作为默认出现</p>\
                        </slot>\
                        <slot name="footer"></slot>\
                        </div>',
        mounted () {
            var header = this.$slots.header;
            // console.log(header);
            console.log(header[0].elm.innerHTML); 
            // 访问slot
        }
    });

    Vue.component("my-list", {
        props: {
            books: {
                type: Array,
                default: function () {
                    return [];
                }
            }
        },
        template: '\
            <ul>\
                <slot name="book"\
                v-for="book in books"\
                :book-name="book.name">\
                </slot>\
                </ul>'
    });

    var app = new Vue({
        el: '#first',   
    })

    var second = new Vue({
        el: '#second',
        data: {
            books: [
                {
                    name: 'HTML'
                },
                {
                    name: 'Css3'
                },
                {
                    name: 'javascript'
                }
            ]
        }
    })
</script>

</html>

4. 第五节 组件高级用法

  • practice_4.4.html
<!-- 

    第7章
    第五节  组件高级用法
    递归
    内联模板
    动态组件
    $nextTick
    手动挂载

    
 -->
<!DOCTYPE html>
<html>

<head>
    <link rel="stylesheet" type="text/css" media="screen" href="style_4.css" />
    <script src="Vue.js"></script>
</head>

<body>
    <div id="first">
        <first-component :count="1"></first-component>
        <!-- 动态组件 -->
        <div>
            <component :is="currentView"></component>
            <button @click="handleChangeView('A')">A</button>
            <button @click="handleChangeView('B')">B</button>
            <button @click="handleChangeView('C')">C</button>
        </div>
        <second-component></second-component>
    </div>

    <div id="second">
        <div id="div" v-if="showDiv">
            $nextTick用法
        </div>
        <button @click="getText">获取div内容</button>
        <div id="mount-div"></div>
    </div>
    
</body>
<script>

    Vue.component("first-component", {
        name: "first-component",
        props: {
            count: {
                type: Number,
                default: 1
            }
        },
        template: '\
        <div class="child">\
            <first-component\
            :count="count + 1"\
            v-if="count < 3">\
            </first-component>\
            <p>递归</p>\
            </div>',
    });

    Vue.component('second-component', function (resolve, reject) {
        window.setTimeout(function () {
            resolve({
                template: '<div>我是异步渲染的</div>'
            });
        }, 2000)
    })

    //手动挂载
    var MyComponent = Vue.extend({
        template: '<div>Hello: {{name}}</div>',
        data: function () {
            return {
                name: 'Rain X'
            }
        }
    });
    new MyComponent().$mount('#mount-div');


    var first = new Vue({
        el: '#first',
        components: {
            comA: {
                template: '<p>组件A</p>'
            },
            comB: {
                template: '<p>组件B</p>'
            },
            comC: {
                template: '<p>组件C</p>'
            },
        },
        data: {
            currentView: 'comA'
        },
        methods: {
            handleChangeView: function (component) {
                this.currentView = 'com' + component;
            }
        }
    })

    var second = new Vue({
        el: '#second',
        data: {
            showDiv: false
        },
        methods: {
            getText: function () {
                this.showDiv = true;
                this.$nextTick(function () {
                    var text = document.getElementById('div').innerHTML;
                    console.log(text);
                });
            }
        }
    })
</script>

</html>

  • style_4.css
div{
    border: 1px solid blue;
}
.title{
    font: 18px bold orange;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值