Vue.js组件

组件: 顾名思义, 也就是组成的部件, 即整体的组成部分 这个组成部分是可以缺少的,但是其存在的意义是无可替代的 这个组成部分也是可以复用的 全局方法一: 大致可以分成三步 1.在我们引入vue.js之后,Vue会被注册为一个全局对象,我们使用对象本身的方法进行组件的创建 ------使用Vue这个全局对象的component方法进行全局注册一个组件

2.创建根实例,进行视图的绑定

3.组件的显示

-----将组价的名称作为标签写在视图内部,就能够完成组件的显示

<!DOCTYPE html>
<html>

    <head>
        <meta charset="UTF-8">
        <title></title>
        <!--引入js-->
        <script src="https://unpkg.com/vue/dist/vue.js"></script>
    </head>

    <body>
        <div id="app">
            <!--3. 定义的组件名作为标签存在,将组件显示在页面上-->
            <my-component></my-component>

        </div>
    </body>

</html>
<script>

    //1. 使用vue这个全局队形内置的components方法进行组件的创建
    //在components这个方法中有两个重要的参数,第一个参数是组件的名称,第二个参数是组件的内容
    Vue.component('my-component', {
        //在这里使用一个父标签将组件包裹起来
        template: '<div><a href="#">注册</a><a href="#">登录</a></div>'
    })

    //2. 创建根实例,也就是实例化一个vue对象,进行视图的绑定
    var vm = new Vue({
        el: '#app'
    })
</script>

全局方法二 使用全局的Vue.extend()构造器进行注册 Vue.extend()类似于继承,通过这个构造器扩展(继承)之后,相当于Vue对象本身添加了一些这个对象原先没有的东西

<!DOCTYPE html>
<html lang="en">

    <head>
        <meta charset="UTF-8">
        <title>Vue入门之extend全局方法</title>
        <script src="https://unpkg.com/vue/dist/vue.js"></script>

        <style type="text/css">

        </style>
    </head>

    <body>
        <div id="app"></div>
    </body>

</html>
<script>
    //通过构造器创建一个组件,相当于在vue这个全局对象本身上添加了一些新的内容,作用相当于构造函数
    //----继承自vue,但是比vue本身更强大
    var myVue = Vue.extend({
        template: '<div>这是通过构造器创建出来的组件</div>'
    });
    var app = new myVue({
        el: '#app'
    });
</script>

局部方法一 大致分成两个部分 1.穿件跟实例 2.在跟实例内部定义组件

<!DOCTYPE html>
<html>

    <head>
        <meta charset="UTF-8">
        <title></title>
        <!--引入js-->
        <script src="https://unpkg.com/vue/dist/vue.js"></script>
    </head>

    <body>
        <div id="app">
            <!--3. 这是我定义的组件    占位标签-->
            <my-component></my-component>

        </div>
    </body>

</html>
<script>
    //1. 创建根实例
    var vm = new Vue({
        el: '#app',
        //2. 在根实例内部创建组件
        components:{
           'my-component':{
               template: '<div><a href="#">注册</a><a href="#">登录</a></div>'
           }
        }
    })
</script>

组件注册的其它方式1

<!DOCTYPE html>
<html>

    <head>
        <meta charset="UTF-8">
        <title></title>
        <!--引入js-->
        <script src="https://unpkg.com/vue/dist/vue.js"></script>
    </head>

    <body>
        <div id="app">
            <!--这是我定义的组件-->
            <my-component></my-component>

        </div>

        <template id="my-template">
            <div>
                <a href="#">注册</a>
                <a href="#">登录</a>
            </div>
        </template>
    </body>

</html>
<!--

    注意组件的模板替换了自定义元素,自定义元素的作用只是作为一个挂载点。

    ----这可以用实例选项 replace 改变。


-->
<script>
    //1. --定义  +  注册 组件构造器
    Vue.component('my-component', {
        //将template的内容提取到一个标签中,通过id来获取
        template: '#my-template'
    })

    //2. 创建根实例
    var vm = new Vue({
        el: '#app'
    })
</script>

组件注册的其它方式2

<!DOCTYPE html>
<html>

    <head>
        <meta charset="UTF-8">
        <title></title>
        <!--引入js-->
        <script src="https://unpkg.com/vue/dist/vue.js"></script>
    </head>

    <body>
        <div id="app">
            <!--这是我定义的组件-->
            <template>
                <div>
                    <a href="#">注册</a>
                    <a href="#">登录</a>
                </div>
            </template>

        </div>

    </body>

</html>
<!--

自定义的标签只是自定义组件的一个挂载点,自定义组件会将其替换掉

----直接使用自定义的组件将自定义的标签替换

-->
<script>
    //2. 创建根实例
    var vm = new Vue({
        el: '#app'
    })
</script>

组件内部的data 组件内部的data属性必须是一个函数 以全局注册的组件为例

<!DOCTYPE html>
<html>

    <head>
        <meta charset="UTF-8">
        <title></title>
        <!--引入js-->
        <script src="https://unpkg.com/vue/dist/vue.js"></script>
    </head>

    <body>
        <div id="app">
            <!--全局的组件-->
            <ab></ab>
            <!--局部的组件-->
            <my-component></my-component>
        </div>
    </body>

</html>
<script>
    //自定义指令
    //Vue.directive('指令名',{})


    //定义组件    参数1:组件的名称    参数2: 对象
    Vue.component("ab",{
        template:
            `<ul>
                <li>{{name}}</li>
                <li>{{age}}</li>
                <li>{{sex}}</li>
            </ul>`,
        //data属性的属性值是一个函数----函数内部返回一个对象
        data:function(){
            return {
                name:"首页",
                age:"联系我们",
                sex:"新闻"
            }
        }

    })

    //2. 创建根实例-----并在根实例下面创建一个局部的组件
    var vm = new Vue({
        el: '#app',
        //局部组件
         components:{
           'my-component':{
               template: `<ul>
                <li>{{name}}</li>
                <li>{{age}}</li>
                <li>{{sex}}</li>
            </ul>`,
            data:function(){
                return {
                    name:1,
                    age:2,
                    sex:3
                }
            }
           }
        }
    })

</script>

父子组件通信 父组件将数据传递给自组件使用prop 子组件将其内部发生的事情通告给父组件使用emit 复杂的父子组件的props

<!DOCTYPE html>
<html>

    <head>
        <meta charset="UTF-8">
        <title></title>
        <!--引入js-->
        <script src="https://unpkg.com/vue/dist/vue.js"></script>
        <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
    </head>

    <body>
        <div id="app">
            <parent></parent>
        </div>
        <template id="parent">
            <div>
                <div>我是父组件</div>
                <child :message="message"></child>
            </div>
        </template>
        <template id="child">
            <div>
                <div>我是子组件</div>
                <span>{{message}}</span>
            </div>
        </template>
    </body>
</html>
<script>
    var vm = new Vue({
        el: '#app',
        //我是父组件
        components:{'parent':{
            template:"#parent",
            data:function(){
                return {
                    message:"hello world"
                }
            },
            //我是子组件
            components:{'child':{
                props:['message'],
                template:"#child"
            }}
        }}
    })
</script>

字面量语法 vs 动态语法 使用字面量语法传递数字,有时候会出现问题 单向数据流 数据从父组件传递到子组件,但是不会反过来传递 数据传递-注意事项 在 JavaScript 中对象和数组是引用类型,指向同一个内存空间, 如果 prop 是一个对象或数组,在子组件内部改变它会影响父组件的状态。 自定义事件

每个 Vue 实例都实现了事件接口(Events interface),即:

    使用 $on(eventName) 监听事件

    使用 $emit(eventName) 触发事件

类似于我们注册(vue中是$on)点击事件,通过鼠标点击触发(vue中是emit)
    document.onclick = function(event){
        console.log(111)
    }
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <script src="https://unpkg.com/vue/dist/vue.js"></script>
        <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
        <style>
            #dv1,
            #dv2 {
                width: 500px;
                height: 100px;
            }

            #dv1 {
                border: 1px solid red;
                margin: 50px auto;
            }

            #dv2 {
                border: 1px solid green;
                margin: 50px auto;
            }
        </style>
    </head>

    <body>

        <div id="app2">
            <component2></component2>
        </div>

        <div id="app1">
            <component1></component1>
        </div>
    </body>

</html>
<script type="text/javascript">
    //1. 创建一个空的公共的vue对象
    var bus = new Vue();

    //2. 在vm1实例中创建组件1,定义$emit来发送数据
    var vm1 = new Vue({
        el: '#app1',
        components: {
            component1: {
                template: `<div id="dv1"  v-on:click="add">
                                <div>点击我,触发自定义事件,进行数据的传递</div>
                                <div>当前的数据是:{{num}}</div>
                            </div>`,
                data: function() {
                    return {
                        num: 0
                    }
                },
                methods: {
                    add: function() {
                        this.num++;
                        bus.$emit('test', this.num)
                    }
                }
            }
        }
    })

    //在vm2实例中创建组件2,定义$on来接收传递的数据
    var vm2 = new Vue({
        el: '#app2',
        components: {
            component2: {
                template: `<div id="dv2" v-on:click="result">
                                <div>点击我,进行自定义事件的注册</div>
                                <div>传递过来的数据是{{getData}}</div>
                            </div>`,
                data: function() {
                    return {
                        getData: 0
                    }
                },
                methods: {
                    result: function() {
                        //this问题
                        var vm2This = this;
                        bus.$on('test', function(num) {
                            vm2This.getData = num;
                            //事件的解绑问题
                            bus.$off("test")
                        })

                    }
                }
            }
        }
    })
</script>

slot 有时候,我们需要对组件进行局部的修改, vue提供了一种方式来混合父组件的内容与子组件自己的模板 这个过程被称为 内容分发 也就是slot

<!DOCTYPE html>
    <html lang="en">

    <head>
        <meta charset="UTF-8">
        <title>Vue入门之extend全局方法</title>
        <script src="https://unpkg.com/vue/dist/vue.js"></script>
    </head>

    <body>
        <div id="app">
            <!--父容器输入标签,会将slot标签替换掉-->
            <my-slot>
                <h3>这里是父容器写入的</h3>
            </my-slot>

            <!--父容器绑定数据到子容器的slot,会将slot中的数据替换掉-->
            <my-slot>{{ email }}</my-slot>

            <!--父容器什么都不传内容-->
            <my-slot></my-slot>
        </div>
    </body>

    </html>

    <script>
        // 反引号:可以定义多行字符串。
        var temp = `
      <div>
        <h1>这里是子组件</h1>
        <hr>
        <slot>slot标签会被父容器写的额外的内容替换掉,如果父容器没有写入任何东西,此标签将保留!</slot>
      </div>
    `;
        Vue.component('MySlot', { // 如果定义的组件为MySlot,那么用组件的时候:<my-slot></my-slot>
            template: temp,
        });
        // 初始化一个Vue实例
        var app = new Vue({
            el: '#app',
            data: {
                email: 'flydragon@gmail.com'
            }
        });
    </script>

具名slot 元素可以用一个特殊的属性 name 来配置如何分发内容。多个 slot 可以有不同的名字。 具名 slot 将匹配内容片段中有对应 slot 特性的元素 仍然可以有一个匿名 slot ,它是默认 slot ,作为找不到匹配的内容片段的备用插槽。如果没有默认的 slot ,这些找不到匹配的内容片段将被抛弃

动态组件 通过使用保留的 元素,动态地绑定到它的 is 特性,我们让多个组件可以使用同一个挂载点,并动态切换 如果把切换出去的组件保留在内存中,可以保留它的状态或避免重新渲染

<!DOCTYPE html>
<html>

    <head>
        <meta charset="UTF-8">
        <title></title>
        <!--引入js-->
        <script src="https://unpkg.com/vue/dist/vue.js"></script>
        <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
    </head>

    <body>
        <h3>动态组件</h3>
        <!-- 定义三个temp模板,用于切换 -->
        <template id="temp-tab01">
            <div>this is tab01</div>
        </template>
        <template id="temp-tab02">
            <div>this is tab02</div>
        </template>
        <template id="temp-tab03">
            <div>this is tab03</div>
        </template>

        <div id="dr01">
            <!-- 导航栏 -->
            <div class="border cf">
                <ul>
                    <li>
                        <a href="javascript:void(0);" @click="toggleTabs(tab01Text);">{{tab01Text}}</a>
                    </li>
                    <li>
                        <a href="javascript:void(0);" @click="toggleTabs(tab02Text);">{{tab02Text}}</a>
                    </li>
                    <li>
                        <a href="javascript:void(0);" @click="toggleTabs(tab03Text);">{{tab03Text}}</a>
                    </li>
                </ul>
            </div>
            <!-- 点击导航后要切换的内容 -->
            <div class="border" style="height: 100px;">
                <!-- 如果把切换出去的组件保留在内存中,可以保留它的状态或避免重新渲染。为此可以添加一个 keep-alive 指令参数 -->
                <component :is="currentView" keep-alive></component>
            </div>
        </div>
    </body>

</html>
<script>
//通过使用保留的 <component> 元素,动态地绑定到它的is属性,我们让多个组件可以使用同一个挂载点,并动态切换:
    //扩展组件tab01
    var tab01 = Vue.extend({
        template: "#temp-tab01",
    });
    //扩展组件tab02
    var tab02 = Vue.extend({
        template: "#temp-tab02",
    });
    //扩展组件tab03
    var tab03 = Vue.extend({
        template: "#temp-tab03",
    });
    //新建vue实例
    var dr01 = new Vue({
        el: "#dr01",
        data: {
            tab01Text: "tab01", //导航栏文本1
            tab02Text: "tab02", //导航栏文本2
            tab03Text: "tab03", //导航栏文本3
            currentView: 'tab01', //默认选中的导航栏
        },
        //局部注册组件
        components: {
            tab01: tab01,
            tab02: tab02,
            tab03: tab03,
        },
        methods: {
            //绑定tab的切换事件
            toggleTabs: function(tabText) {
                this.currentView = tabText;
            }
        }
    });
</script>

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏机器学习实践二三事

Shell && Vim快捷键

刚买到了自己一直想买的HHKB pro 2 type S,不得不说手感什么的确实没让我失望,重点是Ctrl的位置很适合类unix环境啊,不会快捷键都不好意思敲这...

21150
来自专栏java达人

javascript之BOM

一、BOM(The Browser ObjectModel):-浏览器对象模型, (1)BOM提供了独立于内容而与浏览器窗口进行交互的...

21780
来自专栏vue学习

17、将数据渲染到组件(列表渲染、模板语法、父子组件之间的传值)

(1)v-for语法 https://cn.vuejs.org/v2/guide/list.html 我们用 v-for 指令根据一组数组的选项列表进行渲染...

19810
来自专栏Lambda

【第一季】Vue2.0内部指令

学习这套课程你需要的前置知识: HTML的基础知识,你需要达到中级水平,写前端页面的结构代码完全没有问题。 CSS的基础知识,最好做过半年以上的切图和布局,最...

21790
来自专栏Java帮帮-微信公众号-技术文章全总结

JSP简单入门(3)

3、<jsp:param>标签 当使用<jsp:include>标签和<jsp:forward>标签引入或将请求转发给的资源是一个能动态执行的程序时,还可以使用...

31240
来自专栏前端说吧

vue - 父组件数据变化控制子组件类名切换

先说当时的思路和实现 核心是父子组件传值和v-bind指令动态绑定class实现

16010
来自专栏技术墨客

React学习(6)—— 高阶应用:非受控组件

在大部分情况下,推荐使用 受控组件 来实现表单、输入框等状态控制。在受控组件中,表单等数据都有React组件自己处理。这里将介绍另外一种非受控组件,表单的数据有...

6420
来自专栏小樱的经验随笔

php实现图形计算器

存档: index.php 1 <html> 2 <head> 3 <title>图形计算器开发</title> 4 ...

56140
来自专栏木子昭的博客

模拟Vue数据的双向绑定

Vue的数据双向绑定功能一直为人称道, Vue数据的双向数据绑定主要依赖了Object.defineProperty,这里尝试用最简单的代码, 实现数据的双向...

37050
来自专栏柠檬先生

jquery mobile 移动web(6)

jquery mobile 针对移动端设备的事件类型。   1.touch 事件。     tap 快速触摸屏幕并且离开,类似一种完整的点击操作。  ...

236100

扫码关注云+社区

领取腾讯云代金券