VUE2.X全教程(三)--组件精讲

主要内容

1.解决vue组件渲染的bug 

2.组件引用

3.父子组件间的值传递

4.组件的参数校验及非props特性

5.给父组件绑定原生事件

6.组件间的数据传递处理

7插槽的使用

8.作用域插槽

9.动态组件及v-one指令  

Vue组件引发的bug及解决方案:

 <div id="app">
            <table>
                <tbody>
                    <row></row>
                    <row></row>
                    <row></row>
                </tbody>
            </table>
        </div>
<script>
        Vue.component("row",{
            template:"<tr><td>this is a row</td></tr>"
        })
        var  vm = new Vue({
            el:'#app'
        });

当我们使用这种方式使用组件的时候浏览器由于H5的规范 tbody下面必须是tr和td, 而不识别row,所以会引发渲染的问题,如下是渲染之后的结果,tr和td在tbody之外了

解决方案 用tr取代掉组件标签  并在tr中 加入is属性 值为组件名  ul->li,ol->li,select ->option 中同理

<tr is="row"></tr>

2.在子组件中定义data,data必须是一个函数,因为子组件会被调用多次,每一个子组件都拥有一个独立的数据空间,互不影响

Vue.component("row",{
            data:function(){
                return {
                    content:"hello world"
                }
            },
            template:"<tr><td>{{content}}</td></tr>"
        })

3.引用: 当我们不得不对dom元素进行操作的时候,我们需要用引用来实现对dom的操作,比如动画效果等等

this.$refs:指的是所有的vue中的引用

  <div ref="hello"
                     @click="handleClick">
                    hello world
                </div>

 methods:{
                handleClick:function(){
                    alert(this.$refs.hello.innerHTML);
                }
            }

组件引用:

<div id="app">
    <!--组件引用-->
    <count ref="count1" @change="handleChange"></count>
    <count ref="count2" @change="handleChange"></count>
    <div>{{total}}</div>
</div>
<script>
    Vue.component("count", {
        template: "<div @click='changeNumber'>{{number}}</div>",
        data: function () {
            return {
                number: 0
            }
        },
        methods: {
            changeNumber: function () {
                this.number++;
//                    向父组件添加监听方法
                this.$emit('change');
            }
        }
    })

    var vm = new Vue({
        el: '#app',
        data: {
            total: 0
        },
        methods: {
            handleChange: function () {
                this.total = this.$refs.count1.number + this.$refs.count2.number;
            }
        }
    });

 

4.父子组件中的数据传递

父组件向子组件中通过属性进行传值

单向数据流 :父组件可以随意向子组件传递参数,但是子组件不能随意修改父组件传递过来的参数,只能使用,因为修改父组件的值可能会影响到其他的子组件的使用。

子组件通过事件向父组件中传值

<div id="app">
    <counter :count="2" @change="handleChange"></counter>
    <counter :count="3" @change="handleChange"></counter>
    <div>{{total}}</div>
</div>
<script>
    var counter={
        props:['count'],
        data:function(){
            return{
// 根据单向数据流的规则,不能直接修改父组件传递过来的参数值,而是用一个独立的数据空间用来存储父组件传递过来的值,然后进行操作
                number:this.count
            }
        },
        template:"<div @click='handleClick'>{{number}}</div>",
        methods:{
            handleClick:function(){
                this.number+=2;
                this.$emit("change",2); //可以传递多个参数
            }
        }
    }

    var  vm = new Vue({
        el:'#app',
        data:{
          total:5
        },
        components:{
            counter:counter
        },
        methods:{
            handleChange:function(step){
                this.total=this.total+step;
            }
        }
    });

 

5.组件参数校验与非props特性

    Vue.component("son", {
//            props:{
              content:Number
                content:[String,Number] 可以同时允许多个值
//                content:{
                    type:String,
                    required:true,
                    default:"default value",
//                    validator:function(value){
//                        return value.length>5 && value.length<10;
//                    }
//                }
//            },
        template: "<div>{{content}}</div>"
    })
    var vm = new Vue({
        el: '#app'
    });

6.给组件绑定原生事件

<div id="app">
    <child @click.native="handleClick"></child>
</div>
<script>
    Vue.component("child", {
        //这才是子组件中的原生事件
//            template:"<div @click='childClick'>hello world</div>",
        template: "<div>hello world</div>"
//            methods:{
//                childClick:function(){
//                    alert("child click");
//                    this.$emit("click");
//                }
//            }
    })
    var vm = new Vue({
        el: '#app',
        methods: {
            handleClick: function () {
                alert("click");
            }
        }
    });

7.组件间的传值

    1.vuex框架

    2.bus 总线,发布订阅模式,观察者模式

<div id="app">
    <child content="wuhen"></child>
    <child content="yegucheng"></child>
</div>
<script>
    Vue.prototype.bus = new Vue();
    Vue.component("child", {
        data: function () {
            return {
                selfContent: this.content
            }
        },
        props: {
            content: String
        },
        template: "<div @click='handleClick'>{{selfContent}}</div>",
        methods: {
            handleClick: function () {
//                   给bus中添加监听事件并传递需要传递的值,在需要使用的函数中监听该事件便可以获取到该值
                this.bus.$emit("change", this.selfContent);
            },
        },

        //mounted :当组件被装载的时候调用 
        mounted: function () {
            var _this = this;
            this.bus.$on("change", function (msg) {
                _this.selfContent = msg;
            })
        }
    })
    var vm = new Vue({
        el: '#app'

    });

 

9.在Vue中使用插槽

父组件传递的标签会被转义,而不会被解析

 <child>
        <!--直接在父组件中传递标签 插槽的使用-->
        <h1 slot="one">hello</h1>

        <h1 slot="two">world</h1>
    </child>

</div>
<script>
    Vue.component("child", {
        props: ['content'],
        data: function () {
            return {
                selfContent: this.content
            }
        },
        template: "<div>" +
        '<slot name="one"></slot>' +
        '<slot name = two></slot>' +
        "</div>"
    })
    var vm = new Vue({
        el: '#app'
    });

 

10:作用域插槽:

 <div id="app">
            <child>
                <!-- props 用来接收子组件传递过来的参数-->
                <template slot-scope="props">
                    <h1>{{props.item}}</h1>
                </template>
            </child>
        </div>
<script>
        Vue.component("child",{
            data:function(){
              return{
                  list:[1,2,3,4]
              }
            },
            //:item= item  向父组件传值 插槽循环调用
            template:'<div>' +
                    "<slot v-for='item of list' :item=item></slot>"+
            '</div>'
        })
        var  vm = new Vue({
            el:'#app'
        });
</script>

11:动态组件 和 v-once 指令

当我们切换组件的时候Vue会帮我们销毁之前的组件,然后创建一个新的组件。这种操作会消耗大量性能。我们可以将组件的标签加上v-once ,这样就会将我们的子组件放到内存中,下次再使用的时候就不用重新创建了,而是直接从内存中去获取,可以提高我们对静态资源的显示效率。

 <div id="app">
            <!-- 没用动态组件的时候的实现方式-->
            <!--<child-one v-if="type==='child-one'"></child-one>-->
            <!--<child-two  v-if="type==='child-two'"></child-two>-->
            <!-- 动态组件的实现方式-->
            <component :is="type"></component>
            <button @click="handleChange">change</button>
        </div>
<script>
        Vue.component("child-one",{
            //v-once 会将之前使用过的组件加载到内存中,下次使用的时候就能直接使用,提高静态资源的加载效率
            template:'<div v-once>child-one</div>'
        })
        Vue.component("child-two",{
            template:'<div v-once>child-two</div>'
        })
        var  vm = new Vue({
            el:'#app',
            data:{
                type:'child-one'
            },
            methods:{
                handleChange:function(){
                    this.type= this.type==='child-one'? 'child-two':'child-one';
                }
            }
        });

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值