Vue.js组件理解

组件使用细节点

解决元素标签位置错误的问题:is 属性

<div id="app">
    <table>
        <tbody>
            <!--tbody里要用一个组件,但不能直接写组件名
                会导致位置错误问题,使用 is 属性将自定义组件row
                与 tr 标签绑定在一起
            -->
            <tr is=‘row‘></tr>
            <tr is=‘row‘></tr>
            <tr is=‘row‘></tr>
        </tbody>
    </table>

        <ul>
            <li is=‘row‘></li>
            <li is=‘row‘></li>
            <li is=‘row‘></li>
        </ul>
</div>

<script>

    Vue.component(‘row‘, {
        template: ‘<tr><td>this is a row</td></tr>‘
    });

    var vm = new Vue({
        el: "#app"
    });

</script>

组件data函数

在子组件中,data 必须是一个函数,有可能一个子组件会被调用很多次,每个子组件数据不能产生冲突,通过一个函数返回一个对象的目的,就是让每个子组件都拥有独立的数据存储。

Vue.component(‘row‘, {
    //在子组件中,data 必须是一个函数
    data: function(){
        return {
            content: ‘this is a row‘
        }
    },
    template: ‘<tr><td>{{content}}</td></tr>‘
});

ref的使用

<div id="app">
    <counter ref="one" @change="handleChange"></counter>
    <counter ref="two" @change="handleChange"></counter>
    <div>{{total}}</div>
</div>

<script>

    Vue.component(‘counter‘,{
        template: ‘<div @click="handleClick">{{number}}</div>‘,
        data: function(){
            return {
                number: 0
            }
        },
        methods: {
            handleClick: function() {
                this.number ++;
                // $emit() 自定义事件向父组件通信
                this.$emit(‘change‘);
            }
        }
    });

    var vm = new Vue({
        el: "#app",
        data: {
            total: 0
        },
        methods: {
            handleChange: function() {
                //可以使用自加一方法
                //this.total++;
                //也可以求二者之和
                // 通过 $refs 获取子组件的引用,再获取数据
                this.total = this.$refs.one.number + this.$refs.two.number;
            }
        }
    });

父子组件的数据传递

父组件通过属性的形式向子组件传递数据

Vue 中的单项数据流:父组件可以向子组件传递参数,该参数在父组件可随便修改,子组件绝对不能反过来去修改父组件传递过来的参数,只用不改

<div id="app">
    <!--父往子传递-->
    <!--父组件通过绑定属性的形式向子组件传递数据-->
    <counter :count="3" @inc="handleIncrease"></counter>
    <counter :count="2" @inc="handleIncrease"></counter>

    <!--子往父传递-->
    <!--子组件通过事件触发的形式向父组件传递数据-->
    <div>{{total}}</div>
</div>

<script>
    var counter = {
        props: [‘count‘],
        data: function() {
            return {
                //定义一个number 把获取来的数据克隆一个传进去
                number: this.count
            }
        },
        template: ‘<div @click="handleClick">{{number}}</div>‘,
        methods: {
            handleClick: function() {
                this.number += 2;
                //子组件通过点击将事件触发出去
                this.$emit(‘inc‘, 2)
            }
        }
    }
    var vm = new Vue({
        el: "#app",
        components: {
            counter: counter
        },
        data: {
            total: 5
        },
        methods: {
            // 父组件执行的函数里可以直接接收到 $emit()的参数
            handleIncrease: function(step) {
                this.total += step;
            }
        }
    });

组件参数校验与非props特性

<div id="app">
    <child :content="123"></child>
</div>

<script>

    Vue.component(‘child‘,{
        props: {
            //设定子组件接收的content 属性,
            //  要么是数字,要么是字符串
            content: [String, Number]
            /*
            也可以这样写:
            content: {
                //类型
                type: String,

                //设定这个属性是必须的
                required: true,

                //如果不给default 传数值,默认default
                default: ‘default value‘,

                //对传入 content属性 添加校验
                //规定长度必须大于5
                validator: function(value) {
                    return (value.length > 5)
                }
            }
            */
        },
        template: ‘<div>{{content}}</div>‘
    })

    var vm = new Vue({
        el: "#app"
    });
    

props 特性:

父组件传递了content 子组件又声明了一个content接收; 二者有一个对应关系。该属性不会在DOM中出现,子组件可直接通过插值表达式调用content内的内容。

非props 特性

父组件传递一个属性,但是子组件并没有props的内容,没有声明,无法获取父组件内容。该属性会在子组件DOM中出现

给组件绑定原生事件

<div id="app">
    <!--
        加native修饰符,监听原生点击事件,
        方法同子组件设置自定义事件向父组件触发
    -->
    <child @click.native=‘handleClick‘></child>
</div>

<script>
    Vue.component(‘child‘,{
        template: ‘<div>child</div>‘
    })
    var vm = new Vue({
        el: "#app",
        methods: {
            handleClick: function() {
                alert(‘click‘)
            }
        }
    });
</script>

非父子组件间的传值

  1. 借助官方的数据框架 vuex解决
  2. 发布订阅模式 总线机制 Bus 观察者模式
<!--非父子组件传值
    Bus / 总线 / 发布订阅模式 / 观察者模式
-->
<div id="app">
    <!--点击一个,另一个变成相同的-->
    <child content=‘anqw‘></child>
    <child content=‘joe‘></child>
</div>

<script>
    //每一个Vue 实例都会有bus 属性
    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 ,这个bus 又是Vue 实例,
                //所以会有$emit()方法,同时把内容传进参数
                this.bus.$emit(‘change‘,this.selfContent);
            }
        },
        //借助生命周期钩子,被挂载时执行
        //$on 方法监听自定义事件
        mounted: function() {
            //固定this的指向
            var this_ = this;
            this.bus.$on(‘change‘, function(msg) {
                this_.selfContent = msg
            })
        }
    })
    var vm = new Vue({
        el: "#app"
    });

在Vue中使用插槽 slot

<div id="app">
    <child>
        <!--插槽-->
        <!--如果不传标签会显示默认内容-->
        <h1>Anqw</h1>
    </child>
</div>

<script>
    Vue.component(‘child‘,{
        //slot插槽中显示的是父组件插入的标签
        template: ‘<div><p>hello</p><slot>默认内容</slot></div>‘
    })
    var vm = new Vue({
        el: "#app"
    });

</script>

将多个插槽一一对应

<div id="app">
    <body-content>
        <div class="header" slot=‘header‘>header</div>
        <div class="footer" slot=‘footer‘>footer</div>
    </body-content>
</div>

<script>
    Vue.component(‘body-content‘,{
        //将插槽一一对应,用slot 与 name 属性绑定
        template: `<div>
                        <slot name=‘header‘></slot>
                        <div class="content">
                            content
                        </div>
                        <slot name=‘footer‘></slot>
                    </div>`
    });
    var vm = new Vue({
        el: "#app"
    });

</script>
<!--
    显示结果:
    header
    content
    footer
-->

Vue 中的作用域插槽

<div id="app">
    <child>
        <!--首先父组件内传了一个插槽,
            作用域插槽,必须用 template 标签包裹,
            同时声明从子组件接收的数据都放在props中,
            slot-scope 对应的属性名接收到数据后,
            以li的形式进行展示.
        -->
        <template slot-scope="props">
            <!--由父组件传递循环对应的模板-->
            <li>{{props.item}} - hello</li>
        </template>
    </child>
</div>

<script>
    Vue.component(‘child‘,{
        data: function() {
            return {
                list: [1,2,3,4]
            }
        },
        //当子组件做循环,DOM结构需要由外部传递时
        template: `<div>
                        <ul>
                            <slot
                                v-for="item of list"
                                :item="item">
                            </slot>
                        </ul>
                    </div>`
    });
    var vm = new Vue({
        el: "#app"
    });

</script>

动态组件与v-once指令

<div id="app">
    <!--动态组件-->
    <!--会根据 is 中数据的变化去加载不同的组件-->
    <!--<component :is="type"></component>-->

    <child-one v-if="type === ‘child-one‘"></child-one>
    <child-two v-if="type === ‘child-two‘"></child-two>

    <button @click="handleClick">change</button>

    <!--当点击button时 两个组件 toggle显示-->
</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: {
            handleClick: function() {
                this.type = (this.type === ‘child-one‘?
                    ‘child-two‘: ‘child-one‘);
            }
        }
    });
</script>

原文地址:https://www.cnblogs.com/anqwjoe/p/9053431.html

时间: 2024-10-10 02:16:53

Vue.js组件理解的相关文章

如何理解vue.js组件的作用域是独立的

vue.js组件的作用域是独立,可以从以下三个方面理解: 1.父组件模板在父组件作用域内编译,父组件模板的数据用父组件内data数据:2.子组件模板在子组件作用域内编译,子组件模板的数据用子组件内data数据,如果要用父组件的必须用props传递:3.子组件标签的数据,使用父组件内的data数据 案例代码: <div id="demo"> <my-component v-if="show" v-bind:my-message="messa

vue.js 组件之间如何实现数据传递?

组件是 vue.js  最强大的功能之一,而组件实例的作用域是相互独立的,这就意味着不同组件之间的数据无法相互引用.如何传递数据也成了组件的重要知识点之一.本文和大家分享的就是vue.js  组件之间传递数据相关内容,一起来看看吧,希望对大家 学习vue.js有所帮助. 组件 组件与组件之间,还存在着不同的关系.父子关系与兄弟关系(不是父子的都暂称为兄弟吧). 父子组件 父子关系即是组件 A  在它的模板中使用了组件  B ,那么组件  A  就是父组件,组件  B  就是子组件. //  注册

如何对第一个Vue.js组件进行单元测试 (上)

首先,为什么要单元测试组件? 单元测试是持续集成的关键.通过专注于小的.独立的实体,确保单元测试始终按预期运行,使代码更加可靠,你可以放心地迭代你的项目而不必担坏事儿. 单元测试不仅限于脚本.可以独立测试的任何东西都是可单元测试的,只要你遵循一些好的做法.这些实例包括单一责任.可预测性和松散耦合. 作为我们应用程序的可重用实体,Vue.js组件是单元测试的理想选择.我们将用不同的输入和交互测试做好的单个单元,并确保它始终按照我们的预期运行. 在开始之前 Vue CLI 3发布了.Vue Test

Vue.js 组件精讲

课程介绍:你会学到什么        了解 Vue.js 组件开发的精华        Vue.js 组件知识全覆盖        掌握多种 Vue.js 组件开发的模式        独立组件不依赖 Vuex 和 Bus 情况下,各种跨级通信手段(provide / inject.broadcast / dispatch.findComponents 系列)        7 个完整的 Vue.js 组件示例        如何做好一个开源项目        Vue.js 容易忽略的 API

Vue.js 组件 component

什么是组件? 组件(component)是Vue.js最强大的功能之一,核心目标是扩展HTML元素,封装可重用的代码.我们可以把组件代码按照template.style.script的拆分方式,放置到对应的 .vue  文件中. Vue.js的组件可以理解为预先定义好行为的ViewModel类,一个组件可以预定义很多选项,但最核心的是以下几个: 模板(template) --  模板声明了数据和最终展现给用户的DOM之间的映射关系 初始数据(data) --  一个组件的初始数据状态.对于可复用

vue.js 组件-全局组件和局部组件

这两天学习了Vue.js 感觉组件这个地方知识点挺多的,而且很重要,所以,今天添加一点小笔记. 首先Vue组件的使用有3个步骤,创建组件构造器,注册组件,使用组件3个方面. 代码演示如下: <!DOCTYPE html> <html> <body> <div id="app"> <!-- 3. #app是Vue实例挂载的元素,应该在挂载元素范围内使用组件--> <my-component></my-compo

Vue.js——组件快速入门(上篇)

Vue.js--60分钟组件快速入门(上篇) 组件简介 组件系统是Vue.js其中一个重要的概念,它提供了一种抽象,让我们可以使用独立可复用的小组件来构建大型应用,任意类型的应用界面都可以抽象为一个组件树: 那么什么是组件呢?组件可以扩展HTML元素,封装可重用的HTML代码,我们可以将组件看作自定义的HTML元素. 本文的Demo和源代码原作者已放到GitHub!(所有示例都放在GitHub Pages上了,请访问https://github.com/keepfool/vue-tutorial

Vue.js—组件快速入门以及Vue路由实例应用

上次我们学习了Vue.js的基础,并且通过综合的小实例进一步的熟悉了Vue.js的基础应用.今天我们就继续讲讲Vue.js的组件,更加深入的了解Vue,js的使用.首先我们先了解一下什么是Vue.js的组件,组件其实就是页面组成的一部分,它是一个具有独立的逻辑和功能或页面,组件可以扩展 HTML 元素,封装可重用的代码.组件系统让我们可以用独立可复用的小组件来构建大型应用,几乎任意类型的应用的界面都可以抽象为一个组件树,如下图: 接下来我们就仔细讲讲组件的使用吧. 1 全局组件 以下就是我们注册

vue.js 组件之间传递数据

组件是 vue.js  最强大的功能之一,而组件实例的作用域是相互独立的,这就意味着不同组件之间的数据无法相互引用.如何传递数据也成了组件的重要知识点之一.本文就这个知识点和大家一起来扒一扒,希望对大家 学习vue.js有所帮助. 组件 组件与组件之间,还存在着不同的关系.父子关系与兄弟关系(不是父子的都暂称为兄弟吧). 父子组件 父子关系即是组件 A  在它的模板中使用了组件  B ,那么组件  A  就是父组件,组件  B  就是子组件. //  注册一个子组件 Vue.component(