Vue组件学习(转载)

什么是组件:组件是Vue.js最强大的功能之一。组件可以扩展HTML元素,封装可重用的代码。在较高层面上,组件是自定义的元素,Vue.js的编译器为它添加特殊功能。在有些情况下,组件也可以是原生HTML元素的形式,以is特性扩展。

如何注册组件?

需要使用Vue.extend方法创建一个组件,然后使用Vue.component方法注册组件。Vue.extend方法格式如下:

var MyComponent = Vue.extend({
    // 选项...后面再介绍
})

如果想要其他地方使用这个创建的组件,还得个组件命个名:

Vue.component(‘my-component‘, MyComponent)

命名之后即可在HTML标签中使用这个组件名称,像使用DOM元素一样。下面来看看一个完整的组件注册和使用例子。

html代码:

<div id="example">
    <my-component></my-component>
</div>

js代码:

// 定义
var MyComponent = Vue.extend({
    template: ‘<div>A custom component!</div>‘
})

// 注册
Vue.component(‘my-component‘, MyComponent)

// 创建根实例
new Vue({
    el: ‘#example‘
})

输出结果:

<div id="example">
    <div>A custom component!</div>
</div

嵌套组件

组件本身也可以包含组件,下面的parent组件就包含了一个命名为child-component组件,但这个组件只能被parent组件使用:

var child = Vue.extend({
    template: ‘<div>A custom component!</div>‘
});
var parent = Vue.extend({
    template: ‘<div>Parent Component: <child-component></child-component></div>‘,
    components: {
        ‘child-component‘: child
    }
});
Vue.component("parent-component", parent);

上面的定义过程比较繁琐,也可以不用每次都调用Vue.component和Vue.extend方法:

// 在一个步骤中扩展与注册
Vue.component(‘my-component‘, {
template: ‘<div>A custom component!</div>‘
})

// 局部注册也可以这么做
var Parent = Vue.extend({
    components: {
        ‘my-component‘: {
            template: ‘<div>A custom component!</div>‘
        }
    }
})

动态组件

多个组件可以使用同一个挂载点,然后动态的在他们之间切换。使用保留的<component>元素,动态地绑定到它的is特性。下面的列子在同一个vue实例下挂了home、posts、archive三个组件,通过特性currentView动态切换组件显示。

html代码:

<div id="dynamic">
    <button id="home">Home</button>
    <button id="posts">Posts</button>
    <button id="archive">Archive</button>
    <br>
    <component :is="currentView"></component>
</div>

js代码:

var vue = new Vue({
    el:"#dynamic",
    data: {
        currentView: "home"
    },
    components: {
        home:{
            template: "Home"
        },
        posts: {
            template: "Posts"
        },
        archive: {
            template: "Archive"
        }
    }
});
document.getElementById("home").onclick = function(){
vue.currentView = "home";
};
document.getElementById("posts").onclick = function(){
vue.currentView = "posts";
};
document.getElementById("archive").onclick = function(){
vue.currentView = "archive";
};

组件和v-for

<my-component v-for="item in items"></my-component>

    不能传递数据给组件,因为组件的作用域是独立的。为了传递数据给组件,应当使用props:

<my-component
v-for="item in items"
:item="item"
:index="$index">
</my-component>

不自动把 item 注入组件的原因是这会导致组件跟当前 v-for 紧密耦合。显式声明数据来自哪里可以让组件复用在其它地方。

深入响应式原理

    在组件绑定数据时,如何绑定才能够有效,并且可动态修改、添加属性?看看下面的原理介绍。

如何追踪变化:把一个不同对象传给vue实例作为data的选项,vue.js将遍历它的属性,用Object.defineProperty将它转换为getter/setter。这是ES5特性,所有vue.js不支持IE8或更低版本。
    模板中每个指令/数据绑定都有一个对应的watcher对象,在计算过程中它把属性记录为依赖。之后当依赖的setter被调用时 ,会触发watcher重新计算。流程如下所示:

变化检测问题:vue.js不能检测到对象属性的添加或删除,属性必须在data上才能让vue.js转换它为getter/setter模式,才能有响应。例如:

var data = { a: 1 };
var vm = new Vue({
data: data
});
// `vm.a` 和 `data.a` 现在是响应的
vm.b = 2
// `vm.b` 不是响应的
data.b = 2
// `data.b` 不是响应的

不过,也有办法在实例创建后添加属性并且让它是相应的。可以使用set(key,value)实例方法:

vm. set(‘b‘, 2)
// `vm.b` 和 `data.b` 现在是响应的

对于普通对象可以使用全局方法:Vue.set(object, key, value):

Vue.set(data, ‘c‘, 3)
// `vm.c` 和 `data.c` 现在是响应的

初始化数据:尽管Vue.js提供动态的添加相应属性,还是推荐在data对象上声明所有的相应属性。

不这么做:

var vm = new Vue({
    template: ‘<div>{{msg}}</div>‘
})
// 然后添加 `msg`
vm.$set(‘msg‘, ‘Hello!‘)

应该这么做:

var vm = new Vue({
    data: {
        // 以一个空值声明 `msg`
        msg: ‘‘
    },
    template: ‘<div>{{msg}}</div>‘
})
// 然后设置 `msg`
vm.msg = ‘Hello!‘

    组件完整案例

下面介绍的例子实现了模态窗口功能,代码也比较简单。

html代码:

<!-- 实现script定义一个模板 -->
<script type="x/template" id="modal-template">
    <!--模板是否显示通过v-show="show"来设置, transition设置动画效果-->
    <div class="modal-mask" v-show="show" transition="modal">
        <div class="modal-wrapper">
            <div class="modal-container">
                <div class="modal-header">
                    <!--slot 相当于header占位符-->
                    <slot name="header">
                        default header
                    </slot>
                </div>
                <div class="modal-body">
                    <!--slot 相当于body占位符-->
                    <slot name="body">
                        default body
                    </slot>
                </div>
                <div class="modal-footer">
                    <!--slot 相当于footer占位符-->
                    <slot name="footer">
                        default footer
                    </slot>
                    <button class="modal-default-button" @click="show = false">OK</button>
                </div>
            </div>
        </div>
    </div>
</script>
<div id="app">
    <!--点击按钮时设置vue实例特性showModal的值为true-->
    <button id="show-modal" @click="showModal = true">show modal</button>
    <!--modal是自定义的一个插件,插件的特性show绑定vue实例的showModal特性-->
    <modal :show.sync="showModal">
        <!--替换modal插件中slot那么为header的内容-->
        <h3 slot="header">Custom Header</h3>
    </modal>
</div>

js代码:

//定义一个插件,名称为modal
Vue.component("modal", {
    //插件的模板绑定id为modal-template的DOM元素内容
    template: "#modal-template",
    props: {
        //特性,类型为布尔
        show:{
            type: Boolean,
            required: true,
            twoWay: true
        }
    }
});
//实例化vue,作用域在id为app元素下,
new Vue({
    el: "#app",
    data: {
        //特性,默认值为false
        showModal: false
    }
});

css代码:

.modal-mask {
    position: fixed;
    z-index: 9998;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, .5);
    display: table;
    transition: opacity .3s ease;
}

.modal-wrapper {
    display: table-cell;
    vertical-align: middle;
}

.modal-container {
    width: 300px;
    margin: 0px auto;
    padding: 20px 30px;
    background-color: #fff;
    border-radius: 2px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, .33);
    transition: all .3s ease;
    font-family: Helvetica, Arial, sans-serif;
}

.modal-header h3 {
    margin-top: 0;
    color: #42b983;
}

.modal-body {
    margin: 20px 0;
}

.modal-default-button {
    float: right;
}

/*
* the following styles are auto-applied to elements with
* v-transition="modal" when their visiblity is toggled
* by Vue.js.
*
* You can easily play with the modal transition by editing
* these styles.
*/

.modal-enter, .modal-leave {
    opacity: 0;
}

.modal-enter .modal-container,
.modal-leave .modal-container {
    -webkit-transform: scale(1.1);
    transform: scale(1.1);
}

由于自己在项目中还没怎么深入使用组件的功能,所以自己对组件的理解也不深入,介绍的比较肤浅,忽喷。

时间: 2024-10-13 21:14:30

Vue组件学习(转载)的相关文章

vue学习——刚学Vue组件,吐槽一个东西

Vue组件的props是用来传值的 这里是官方链接 template:"<bbb @click='onClick()'>{{value}}</bbb>", //"<div>{{value}}</div>" 讨厌的东西就出在这行代码,一个组件的 template 调用同级别的组件 bbb 然后使用 props 传值,结果是行不通的,并且没有报错!虽然,明知道是什么问题,可是还是令我感到不舒服. 测试代码: <!DO

vue.js学习之组件数据流详解

本文和大家分享的主要是vue.js组件数据流相关内容,一起来看看吧,希望对大家学习vue.js有所帮助. 一.组件 组件,可以说是现代前端框架中必不可少的组成部分.使用组件,不仅能极大地提高代码的复用率和开发者的开发效率,对于代码后期的维护也有着非常重要的意义.前端开发,由于历史遗留原因,WebComponent 虽然好用,但其发展情况却受到极大地限制,和很多新兴的前端技术一样,可望而不可即.基于这样的情况,聪明的开发者们尝试通过框架内部集成相应的功能来完成组件化,各种现代前端框架基本上都有各自

Vue.js学习笔记(7)组件详解

在这篇文章之前小颖分享过小颖自己写的组件:Vue.js学习笔记(5)tabs组件和Tree升级版(实现省市多级联动) 先给大家看下小颖写了一个简单的组件示例: 组件: <template> <div class='content' v-if='showFlag'> <input type="text" v-bind:style='{ width:compwidth+"px"}' v-model='compvalue' @keyup='m

vue.js学习笔记(4)— 父子组件之间通信的第一种方式 props 和 $emit

我们知道,vue组件中,父组件把数组传递给子组件的话,通常是使用props传递,而vue规定,prop是只能单向下行传递的,那么子组件要怎么才能实现数据的向上传递呢,这里引述一个概念:"父子组件的关系:prop向下传递,事件向上传递",上一篇文章当中,关于数据向上传递用到的事件方法 $emit() 也进行了详细的说明,不懂的童鞋可以翻回去看一下.下面就是今天要说的父子组件相互通信的问题,点击效果依次如下: 代码如下: <!DOCTYPE html> <html>

来吧!一文彻底搞定Vue组件!

作者 | Jeskson 来源 | 达达前端小酒馆 Vue组件的概述 组件是什么呢,了解组件对象的分析,Vue组件中的data属性,props传递数据的原理到底是什么. 事件通信的那些事 如何了解父子组件事件通信,和遇到非父子组件事件通信如何处理. 组件类型又是什么鬼 自定义组件双向绑定v-model,动态组件,又是如何称为动态的,为啥是动态呢,递归组件,如何理解递归. Vue组件的了解 Vue的理解,可以找我上一篇vue.js-详解三大流行框架VUE_快速进阶前端大咖-Vue基础,组件是什么,

vue组件

require.js 加载 vue组件 r.js 合并压缩 require.js 参考阮一峰 Javascript模块化编程(三):require.js的用法r.js 合并压缩 参考司徒正美 r.js合并实践 准备: vue.js 原本是学习vue组件 require.js 然后想到用require 加载 r.js 文件太多 合并 文件目录 忽略部分文件及文件夹 一.先说vue 组件 先引入vue 再引入vue组件 Vue.extend({}) 定义组件 template data method

vue组件最佳实践

看了老外的一篇关于组件开发的建议(强烈建议阅读英文原版),感觉不错翻译一下加深理解. 这篇文章制定一个统一的规则来开发你的vue程序,以至于达到一下目的.1.让开发者和开发团队更容易发现一些事情.2.让你更好的利用你的IDE.3.让你更加容易的使用打包工具4.让你的代码更容易碎片化以达到复用的目的. 基于模块开发 用一些功能单一的小模块来组织你的应用 Why? 对于你自己和你团队的人来说较小的模块更容易看懂 维护 复用和调试. How? 每个组件应该保持单一 独立 可复用 可测试把你很大的组件拆

vue 组件属性props,特性驼峰命名,连接线使用

今天在学习vue的时候碰到了一个有趣的问题 是这样的,先来个话题引入,后面会用到 var myname={ 'first-name':'9', 'last-name':'l o n g' } console.log(myname.first-name); console.log(myname['first-name']); 打印出来是  NaN  9 解释下,之所以没有前面没有打印出来9,是因为程序走的时候,把我们认为的英文连接符当做减号看待,myname.first是undefined,nam

Web打印组件jatoolsPrinter(转载)

应用web化,不论对开发商,还是对用户来说,实在是一种很经济的选择,因为基于web的应用,客户端的规则很简单,容易学习,容易维护,容易发布.但对程序员来说,因为浏览器的局限性,却要面对很多挑战.怎么样来进行基于web的套打,就是这么一个令多数程序员头痛不已的问题. 基于web的套打,难度在于要将浏览器中呈现的html,精确地打印到票据中,而且能够实现对分页位置的控制.下面就ie浏览器所能采用的套打解决方案,来个汇总分析,希望对大家有所帮助. jatoolsPrinter 是一款实现网页套打的免费