组件是Vue.js最强大的功能之一。组件可以扩展HTML元素,封装可重用的代码,说白了就是一组可以重复使用的模板。
组件系统让我们可以用独立可复用的小组件来构建大型应用,几乎任意类型的应用的界面都可以抽象为一个组件树:
可以把组件代码按照template、style、script的拆分方式,放置到对应的.vue文件中。
组件预定义选项中最核心的几个: 模板(template)、初始数据(data)、接受的外部参数(props)、方法(methods)、生命周期钩子函数(lifecycle hooks)。
Vue中有两种组件的注册类型:全局注册和局部注册。
全局注册
全局组件语法格式如下:
Vue.component(tagName, options)
tagName 为组件名,options 为配置选项。注册后,我们可以使用以下方式来调用组件:
<tagName></tagName>
全局组件示例:
<body> <div id="app"> <!--组件的使用-->> <button-counter></button-counter> <button-counter></button-counter> <button-counter></button-counter> </div> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script> <script> //定义一个新组件 Vue.component('button-counter',{ data:function(){ return{ count:0 } }, template:'<button @click="count++">点击了{{count}}次。</button>' }) var app = new Vue({ el: "#app", data: { } }); </script> </body>
上面的示例代码,每个组件都会各自独立维护它的 “count”。因为每用一次组件,就会有一个它的新实例被创建。
注意:data 必须是一个函数。一个组件的 "data" 选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立拷贝。如果 Vue 没有这条规则,在复用组件的时候,当一个组件的“data”发生改变时,就会影响其他实例。
局部注册
局部组件示例:
<body> <div id="app"> <test-component></test-component> </div> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script> <script> var testComponent = Vue.extend({ template: '<span>局部组件示例!</span>' }); var app = new Vue({ el: "#app", components:{ 'test-component':testComponent } }); </script> </body>
组件之间的数据传递
1. props 传递参数
props”是组件数据的一个字段,用来接受父组件传递过来的数据的一个自定义属性。因为组件实例的作用域是孤立的,所以子组件需要显式地用props选项来获取父组件的数据。 Props选项可以是字面量、表达式、绑定修饰符。
示例:
<body> <div id="app"> <demo message="hello!"></demo> </div> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script> <script> //定义一个新组件 Vue.component('demo',{ //声明 props props:['message'], template: '<span>{{ message }}</span>' }) var app = new Vue({ el: "#app" }); </script> </body>
动态props 示例:
<body> <div id="app"> <demo2 v-bind:message="parentMsg"></demo2> </div> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script> <script> Vue.component('demo2',{ props:['message'], template: '<span>{{ message }}</span>' }) var app = new Vue({ el: "#app", data: { parentMsg: '父组件内容' } }); </script> </body>
上面的示例是用v-bind 动态绑定 props 的值到父组件的数据中。每当父组件的数据变化时,该变化也会传导给子组件。
prop 是单向绑定的,当父组件的属性变化时,将传导给子组件,但是不会反过来。如果子组件要把数据传递回去,就需要使用自定义事件!可以使用 v-on 绑定自定义事件, 每个 Vue 实例都实现了事件接口(Events interface)。
另外,父组件可以在使用子组件的地方直接用 v-on 来监听子组件触发的事件。
示例:
<body> <div id="app"> <h2>{{ total }}</h2> <hr> <button-counter v-on:increment="incrementTotal"></button-counter> </div> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script> <script> Vue.component('button-counter', { template: '<button v-on:click="incrementHandler">{{ counter }}</button>', // data 必须是一个函数 //这样的好处就是每个实例可以维护一份被返回对象的独立的拷贝,如果 data 是一个对象则会影响到其他实例 data: function () { return { counter: 0 } }, methods: { incrementHandler: function () { this.counter += 1 this.$emit('increment') } }, }) var app = new Vue({ el: "#app", data: { total:0 }, methods:{ incrementTotal:function(){ this.total += 1 } } }); </script> </body>
2. 插槽slot 的方式
Vue 实现了一套内容分发的 API,将 <slot> 元素作为承载分发内容的出口。 <slot> 元素作为承载分发内容的出口,作者称其为 插槽,可以应用在组合组件的场景中。
当组件渲染的时候,<slot></slot> 将会被替换为“Your Profile”。插槽内可以包含任何模板代码,包括 HTML。
如果 template 中没有包含一个 <slot> 元素,则该组件起始标签和结束标签之间的任何内容都会被抛弃。
示例:
<body> <div id="app"> <todo> <!-- 将值 通过插槽插入 -->> <todo-title slot="todo-title" v-bind:title="todoTitle"> </todo-title> <todo-items slot="todo-items" v-for="(item, index) in todoItems" v-bind:item="item" v-bind:index="index":key="index"></todo-items> </todo-items> </todo> </div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script> <script> // 在模板中 留出插槽 Vue.component('todo', { template: '<div>\ <div>待办事项</div>\ <slot name="todo-title"></slot>\ <ul>\ <slot name="todo-items"></slot>\ </ul>\ </div>' });
//定义名为 todo-title 待办标题组件 Vue.component('todo-title', { props: ['title'], template: '<div>{{title}}</div>' }); //定义名为 todo-items 待办标题组件 Vue.component('todo-items', { //这里的index,就是数组的下标,使用for循环遍历的时候,可以循环出来! props: ['index', 'item'], template: '<li>{{index + 1}}. {{item}}</li>', });
var app = new Vue({ el: "#app", data: { //初始化数据 todoTitle: 'Vue 笔记', todoItems: ['环境搭建', '基础知识', '示例'], } }); </script> </body>
标签:vue,app,笔记,Vue,template,props,组件,data From: https://www.cnblogs.com/tanyongjun/p/16608713.html