我们通过Vue的component方法来定义一个全局组件。
<div id="app"> <!--使用定义好的全局组件--> <counter></counter> </div> <script src="./node_modules/vue/dist/vue.js"></script> <script type="text/javascript"> // 定义全局组件,两个参数:1,组件名称。2,组件参数 Vue.component("counter",{ template:'<button v-on:click="count++">你点了我 {{ count }} 次,我记住了.</button>', data(){ return { count:0 } } }) var app = new Vue({ el:"#app" }) </script>
-
组件其实也是一个Vue实例,因此它在定义时也会接收:data、methods、生命周期函数等
-
不同的是组件不会与页面的元素绑定,否则就无法复用了,因此没有el属性。
-
但是组件渲染需要html模板,所以增加了template属性,值就是HTML模板
-
全局组件定义完毕,任何vue实例都可以直接在HTML中通过组件名称来使用组件了。
-
data必须是一个函数,不再是一个对象。
效果:
<div id="app"> <!--使用定义好的全局组件--> <counter></counter> <counter></counter> <counter></counter> </div>
效果:
你会发现每个组件互不干扰,都有自己的count值。怎么实现的?
data: { count: 0 }
取而代之的是,一个组件的 data 选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝:
data: function () { return { count: 0 } }
如果 Vue 没有这条规则,点击一个按钮就会影响到其它所有实例!
3.局部组件
一旦全局注册,就意味着即便以后你不再使用这个组件,它依然会随着Vue的加载而加载。
因此,对于一些并不频繁使用的组件,我们会采用局部注册。
我们先在外部定义一个对象,结构与创建组件时传递的第二个参数一致:
const counter = { template:'<button v-on:click="count++">你点了我 {{ count }} 次,我记住了.</button>', data(){ return { count:0 } } };
然后在Vue中使用它:
var app = new Vue({ el:"#app", components:{ counter:counter // 将定义的对象注册为组件 } })
-
components就是当前vue对象子组件集合。
-
其key就是子组件名称
-
其值就是组件对象名
-
-
效果与刚才的全局注册是类似的,不同的是,这个counter组件只能在当前的Vue实例中使用
-
页面首先分成了顶部导航、左侧内容区、右侧边栏三部分
-
左侧内容区又分为上下两个组件
-
各个组件之间以嵌套的关系组合在一起,那么这个时候不可避免的会有组件间通信的需求。
-
父组件使用子组件时,自定义属性(属性名任意,属性值为要传递的数据)
-
子组件通过props接收父组件数据,通过自定义属性的属性名
父组件使用子组件,并自定义了title属性:
<div id="app"> <h1>打个招呼:</h1> <!--使用子组件,同时传递title属性--> <introduce title="大家好,我是锋哥"/> </div> <script src="./node_modules/vue/dist/vue.js"></script> <script type="text/javascript"> Vue.component("introduce",{ // 直接使用props接收到的属性来渲染页面 template:'<h1>{{title}}</h1>', props:['title'] // 通过props来接收一个父组件传递的属性 }) var app = new Vue({ el:"#app" }) </script>
效果:
我们定义一个子组件,并接收复杂数据:
const myList = { template: '\ <ul>\ <li v-for="item in items" :key="item.id">{{item.id}} : {{item.name}}</li>\ </ul>\ ', props: { items: { type: Array, default: [], required: true } } };
-
这个子组件可以对 items 进行迭代,并输出到页面。
-
props:定义需要从父组件中接收的属性
-
items:是要接收的属性名称
-
type:限定父组件传递来的必须是数组
-
default:默认值
-
required:是否必须
-
-
当 prop 验证失败的时候,(开发环境构建版本的) Vue 将会产生一个控制台的警告。
我们在父组件中使用它:
<div id="app"> <h2>传智播客已开设如下课程:</h2> <!-- 使用子组件的同时,传递属性,这里使用了v-bind,指向了父组件自己的属性lessons --> <my-list :items="lessons"/> </div>
var app = new Vue({ el:"#app", components:{ myList // 当key和value一样时,可以只写一个 }, data:{ lessons:[ {id:1, name: 'java'}, {id:2, name: 'php'}, {id:3, name: 'ios'}, ] } })
效果:
type类型,可以有:
注意:子组件模板有且只有一个根标签