组件化开发
- 组件化开发思想
- 组件注册方式
- 组件数据的交互方式
- 组件插槽用法
- 组件方式实现功能开发
组件化开发思想
组件化规范: web componeents:通过封装好的功能的定制元素;
把不同的功能封装不同的组件中
1.标准
2.分制:把不同的功能封装到不同的组件中
3.重用:不合适的直接就可以换掉
4.组合:通过组合的方式生成新的商品
组件之间的关系:父子关系,兄弟关系,祖孙关系…
组件的基本使用
模板使用的注意事项
//1.data必须是一个函数;会形成一个环境,保证每一个组件数据是相互独立
//2.组件模板必须是单个根元素,如果有多个需要用一个大盒子包裹起来;
//3.组件模板内容可以使用es6模板字符串形式;
/为什么需要模板字符串:内容更加直观;
//4.组件的命名方式 :驼峰命名式,可以首字母大写HelloWorld;那组件名称必须要小写;
//如使用驼峰是命名组件,使用组件的时候,只能在字符串内容中使用,驼峰命名,在标签模板中,必须使用短横线的方式使用组件,把所有的单词都变成小写的;
<div id="app">
<button-counter></button-counter>//组件名称
</div>
<script src="js/vue.js"></script>
<script>
//全局组件的注册:每个组件的数据都是相互独立
// Vue.component("组件的名称",{
// data:是一个函数
// data:(){}
// })
Vue.component("button-counter", {
data() {
return {
count: 0
}
},
template: `<button @click="headel"> 点击{{count}}次 <button>`,
methods: {
headel() {
this.count += 2;
}
}
})
var vm = new Vue({
el: '#app',
data: {
}
});
</script>
局部组件注册
<div id="app">
<hello-world></hello-world>
<hello-tom></hello-tom>
<hello-jerry></hello-jerry>
</div>
<script src="js/vue.js"></script>
<script>
//局部组件:components里面注册局部组件;
//用这种方式注册的组件,只能在父组件使用
var HelloWorld = {
data() {
return {
msg: 'hello'
}
},
template: '<div>{{msg}}</div>'
}
var HelloTom = {
data() {
return {
msg: 'HelloTom'
}
},
template: '<div>{{msg}}</div>'
}
var HelloJerry = {
data() {
return {
msg: 'HelloJerry'
}
},
template: '<div>{{msg}}</div>'
}
var vm = new Vue({
el: '#app',
data: {
},
//注册局部组件
components: {
'hello-world': HelloWorld,
'hello-tom': HelloTom,
'hello-jerry': HelloJerry
}
});
</script>
父组件想子组件传值
//父组件想=像子组件传值:1.静态方式绑定:title=“来自父组件的值”
//2.属性绑定方式::title=“ptitle”
//使用props接收父组件传递过来的值;多个数值以逗号分隔
> **父组件向子组件传值-props属性名规则**
props里面如果传递的是 props: ['testTile']驼峰命名;在标签内部必须以短横线的方式 传递属性:menu-title='ptitle'
在字符串形式的模板中可以使用驼峰的方式传递属性
<div id="app">
<div>{{pmsg}}</div>
<menu-item title="来自父组件的值"></menu-item>
<menu-item :title="ptitle" content="hello"></menu-item>
</div>
<script src="js/vue.js"></script>
<script>
Vue.component("menu-item", {
props: ['title', 'content'],
data() {
return {
msg: '子组件本身的数据'
}
},
template: '<div>{{msg}}----{{title}}----{{content}}</div>'
})
var vm = new Vue({
el: '#app',
data: {
pmsg: '父组件中内容',
ptitle: '动态绑定属性'
}
});
</script>
props属性值的类型
/*
父组件向子组件传值-props属性值类型
字符串 数组类型 布尔类型 数组 对象类型
*/
<div id="app">
<div>{{pmsg}}</div>
<menu-item :pstr='pstr' :pnum='12' pboo='true' :parr='parr' :pobj='pobj'></menu-item>
</div>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
Vue.component('menu-item', {
props: ['pstr', 'pnum', 'pboo', 'parr', 'pobj'],
template: `
<div>
<div>{{pstr}}</div>
<div>{{12 + pnum}}</div>
<div>{{typeof pboo}}</div>
<ul>
<li :key='index' v-for='(item,index) in parr'>{{item}}</li>
</ul>
<span>{{pobj.name}}</span>
<span>{{pobj.age}}</span>
</div>
</div>
`
});
var vm = new Vue({
el: '#app',
data: {
pmsg: '父组件中内容',
pstr: 'hello',
parr: ['apple', 'orange', 'banana'],
pobj: {
name: 'lisi',
age: 12
}
}
});
</script>
子组件想父组件传值
子组件向父组件传值-基本用法
props传递数据原则:单向数据流;值允许父组件想父组件传值;如果子组件向父组件传值就不容易控制
子组件通过自定义的模式向父组件传递数据
$emit用户触发自定义事件
子组件向父组件传值-携带参数:
e m i t ( " e n l a r g e − t e x t " , 10 ) 第 二 个 参 数 传 递 参 数 ; 父 组 件 中 通 过 @ e n l a r g e − t e x t = ′ h a n d l e ( emit("enlarge-text", 10)第二个参数传递参数; 父组件中通过@enlarge-text='handle( emit("enlarge−text",10)第二个参数传递参数;父组件中通过@enlarge−text=′handle(event)'接受参数;
<div id="app">
<div :style='{fontSize: fontSize + "px"}'>{{pmsg}}</div>
<menu-item :parr='parr' @enlarge-text="headel"></menu-item>
</div>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
Vue.component('menu-item', {
props: ['parr'],
template: `
<div>
<ul>
<li :key='index' v-for='(item,index) in parr'>{{item}}</li>
</ul>
<button @click="$emit('enlarge-text')">扩大父组件中字体大小</button>
</div>
`
});
var vm = new Vue({
el: '#app',
data: {
pmsg: '父组件中内容',
parr: ['apple', 'orange', 'banana'],
fontSize: 10
},
methods: {
headel() {
//扩大字体大小;
this.fontSize += 5;
}
}
});
</script>
兄弟组件之间的数据传递
/*
兄弟组件之间数据传递
必须通过单独事件中心进行通信传递数据
提供时间中心: var hub = new Vue();
监听与销毁事件:
$on:监听事件;
$off:销毁事件
*/
<div id="app">
<div>父组件</div>
<div>
<button @click='handle'>销毁事件</button>
</div>
<test-tom></test-tom>
<test-jerry></test-jerry>
</div>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
// 提供事件中心
var hub = new Vue();
Vue.component('test-tom', {
data: function() {
return {
num: 0
}
},
template: `
<div>
<div>TOM:{{num}}</div>
<div>
<button @click='handle'>点击</button>
</div>
</div>
`,
methods: {
handle() {
//触发兄弟组件的事件
hub.$emit('jerry-event', 2);
}
},
//声明周期 触发是代表模板已经准备完毕
mounted: function() {
//监听事件;
hub.$on('tom-event', (val) => {
this.num += val;
})
}
});
Vue.component('test-jerry', {
data: function() {
return {
num: 0
}
},
template: `
<div>
<div>JERRY:{{num}}</div>
<div>
<button @click='handle'>点击</button>
</div>
</div>
`,
methods: {
handle() {
//触发兄弟组件的事件
hub.$emit('jerry-event', 2);
}
},
mounted: function() {
// 监听事件
hub.$on('jerry-event', (val) => {
this.num += val;
});
}
});
var vm = new Vue({
el: '#app',
data: {
},
methods: {
handle: function() {
hub.$off('tom-event');//销毁事件
hub.$off('jerry-event');
}
}
});
</script>
插槽的基本使用
//组件插槽:自定义组件起始标签和结束标签中间的位置
//作用:父组件向子组件传递内容
//组件里面的信息是插槽传递过来的;如果插槽中有默认数据,你传递的子组件中没有传递内容;那么就会默认显示插槽里面的内容
<div id="app">
<alert-box>
有bug
</alert-box>
</div>
<script src="js/vue.js"></script>
<script>
//语法结构:
Vue.component('alert-box', {
template: `
<div>
<strong>ERROR:</strong>
<slot>默认内容</slot>
</div>
`
});
var vm = new Vue({
el: '#app',
data: {
}
});
</script>
具名插槽
在模板中可以定义多个插槽;
如果想把插槽名称填写到标签上的话,只能填写一个
具名插槽:可以填写多个插槽;多个插槽的情况下,回忆插槽的名称来匹配; 组件里面就以名字来识别插槽标题信息
如果多个插槽没有携带名字的话,没有匹配到的就会放到默认的插槽中
临时包裹信息,但是不会显示到页面中;把多个插槽填充到文本中