-
认识Vue 并安装nodeJS和NPM
-
Vue快速入门
-
Vue实例
-
Vue指令
-
Vue组件化
-
Vue路由vue-router
-
webpack快速入门
-
vue-cli入门
6.组件化
在大型应用开发的时候,页面可以划分成很多部分。往往不同的页面,也会有相同的部分。例如可能会有相同的头部导航。
但是如果每个页面都独自开发,这无疑增加了我们开发的成本。所以我们会把页面的不同部分拆分成独立的组件,然后在不同页面就可以共享这些组件,避免重复开发。
6.1.全局组件
我们通过Vue的component方法来定义一个全局组件。
- 组件其实也是一个Vue实例,因此它在定义时也会接收:data、methods、生命周期函数等
- 不同的是组件不会与页面的元素绑定,否则就无法复用了,因此没有el属性。
- 但是组件渲染需要html模板,所以增加了template属性,值就是HTML模板
- 全局组件定义完毕,任何vue实例都可以直接在HTML中通过组件名称来使用组件了。
- data必须是一个函数,不再是一个对象。
效果:
6.2.组件的复用
定义好的组件,可以任意复用多次:
效果:
你会发现每个组件互不干扰,都有自己的count值。怎么实现的?
组件的data属性必须是函数!
当我们定义这个
组件时,它的data 并不是像这样直接提供一个对象:
data: {
count: 0
}
取而代之的是,一个组件的 data 选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝:
data: function () {
return {
count: 0
}
}
如果 Vue 没有这条规则,点击一个按钮就会影响到其它所有实例!
6.3.局部注册
一旦全局注册,就意味着即便以后你不再使用这个组件,它依然会随着Vue的加载而加载。
因此,对于一些并不频繁使用的组件,我们会采用局部注册。
我们先在外部定义一个对象,结构与创建组件时传递的第二个参数一致:
const counter = {
template:'',
data(){
return {
count:0
}
}
};
然后在Vue中使用它:
var app = new Vue({
el:"#app",
components:{
counter:counter // 将定义的对象注册为组件
}
})
- components就是当前vue对象子组件集合。
- 其key就是子组件名称
- 其值就是组件对象的属性
- 效果与刚才的全局注册是类似的,不同的是,这个counter组件只能在当前的Vue实例中使用
6.4.组件通信
通常一个单页应用会以一棵嵌套的组件树的形式来组织:
- 页面首先分成了顶部导航、左侧内容区、右侧边栏三部分
- 左侧内容区又分为上下两个组件
- 右侧边栏中又包含了3个子组件
各个组件之间以嵌套的关系组合在一起,那么这个时候不可避免的会有组件间通信的需求。
6.4.1.props(父向子传递)
- 父组件使用子组件时,自定义属性(属性名任意,属性值为要传递的数据)
- 子组件通过props接收父组件属性
父组件使用子组件,并自定义了title属性:
打个招呼:
效果:
6.4.2.props验证
我们定义一个子组件,并接受复杂数据:
const myList = {
template: '\
\
- {{item.id}} : {{item.name}}
\
\
',
props: {
items: {
type: Array,
default: [],
required: true
}
}
};
- 这个子组件可以对 items 进行迭代,并输出到页面。
- props:定义需要从父组件中接收的属性
- items:是要接收的属性名称
- type:限定父组件传递来的必须是数组
- default:默认值
- required:是否必须
- items:是要接收的属性名称
当 prop 验证失败的时候,(开发环境构建版本的) Vue 将会产生一个控制台的警告。
我们在父组件中使用它:
已开设如下课程:
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类型,可以有:
6.4.3.动态静态传递
给 prop 传入一个静态的值:
给 prop 传入一个动态的值: (通过v-bind从数据模型中,获取title的值)
静态传递时,我们传入的值都是字符串类型的,但实际上任何类型的值都可以传给一个 props。
6.4.4.子向父的通信
来看这样的一个案例:
num: {{num}}
- 子组件接收父组件的num属性
- 子组件定义点击按钮,点击后对num进行加或减操作
我们尝试运行,好像没问题,点击按钮试试:
子组件接收到父组件属性后,默认是不允许修改的。怎么办?
既然只有父组件能修改,那么加和减的操作一定是放在父组件:
var app = new Vue({
el:"#app",
data:{
num:0
},
methods:{ // 父组件中定义操作num的方法
increment(){
this.num++;
},
decrement(){
this.num--;
}
}
})
但是,点击按钮是在子组件中,那就是说需要子组件来调用父组件的函数,怎么做?
我们可以通过v-on指令将父组件的函数绑定到子组件上:
num: {{num}}
在子组件中定义函数,函数的具体实现调用父组件的实现,并在子组件中调用这些函数。当子组件中按钮被点击时,调用绑定的函数:
Vue.component("counter", {
template:'\
\
num2:{{num}}\
\
\
',
props:['num'],
methods:{
plus(){
this.$emit("inc");
},
reduce(){
this.$emit("dec");
}
}
})
- vue提供了一个内置的this.$emit()函数,用来调用父组件绑定的函数
效果:
-
认识Vue 并安装nodeJS和NPM
-
Vue快速入门
-
Vue实例
-
Vue指令
-
Vue组件化
-
Vue路由vue-router
-
webpack快速入门
-
vue-cli入门