Vue使用笔记3--创建头部组件
更新日期:
最近在学习使用Vue作为前端的框架,《Vue使用笔记》系列用于记录过程中的一些使用和解决方法。
本文记录Vue组件相关,以及创建头部组件的过程。
实话说,在使用过angular以及react之后,vue给本骚年的感觉就是两者的优点结合在一起了呢。
Vue组件
Vue实例
- 一个Vue实例其实正是一个MVVM模式中所描述的ViewModel
- 在实例化Vue时,需要传入一个选项对象,它可以包含数据、模板、挂载元素、方法、生命周期钩子等选项,参考
- 可以扩展Vue构造器,从而用预定义选项创建可复用的组件构造器
实例生命周期
这里简单放个图吧,左侧的红色框框代表具体的生命周期钩子。
官方文档里面有详细的生命周期钩子哦,大家有需要的话可以具体去研究一下。
Vue组件
组件可以扩展HTML元素,封装可重用的代码。在较高层面上,组件是自定义元素,Vue.js的编译器为它添加特殊功能。
- 所有的Vue.js组件其实都是被扩展的Vue实例
- Vue 的模板是DOM模板,使用浏览器原生的解析器(React则是自己实现一个)
- Props属性
- 组件实例的作用域是孤立的。可以使用props把数据传给子组件,也可以用v-bind绑定动态Props到父组件的数据
- prop默认是单向绑定,使用.sync或.once绑定修饰符显式地强制双向或单次绑定
- 组件可以为 props 指定验证要求(类似React的proptype吧)
- 动态组件
- 多个组件可以使用同一个挂载点,动态地绑定到它的is特性,在它们之间切换
- keep-alive可以把切换出去的组件保留在内存中,保留它的状态或避免重新渲染
- 在切换组件时,切入组件在切入前可能需要进行一些异步操作。使用activate钩子控制组件切换时长
- transition-mode特性用于指定两个动态组件之间如何过渡
- 组件当它有name选项时,可以在它的模板内可以递归地调用自己
父子组件通信
使用父链(会使得父组件与子组件紧密地耦合)
- 子组件可以用this.$parent访问它的父组件
- 根实例的后代可以用this.$root访问它
- 父组件有一个数组this.$children,包含它所有的子元素
自定义事件(Vue事件在冒泡过程中第一次触发回调之后自动停止冒泡,调用true取消)
- 使用$on()监听事件
- 使用$emit()在它上面触发事件
- 使用$dispatch()派发事件,事件沿着父链冒泡
- 使用$broadcast()广播事件,事件向下传导给所有的后代
子组件索引
- 使用v-ref为子组件指定一个索引ID(类似于React的ref属性)
使用 Slot 分发内容
- 使用特殊的
元素作为原始内容的插槽(类似Angular的transclusion) - 父组件的内容将被抛弃,除非子组件模板包含
- 如果子组件模板只有一个没有特性的slot,父组件的整个内容将插到slot所在的地方并替换它
元素可以用一个特殊特性name配置如何分发内容
- 使用特殊的
参考
创建头部菜单
该头部菜单与前面的使用笔记中一致。如图:
由于Vue中木有找到类似React-Bootstrap一样的库,故这里先直接用bootstrap的样式css文件。
添加头部组件
- 在components文件夹中添加Header.vue文件
- 添加模板
1 | <template> |
- 添加逻辑
1 | <script> |
- 添加样式(此处省略)
- 使用
<style>
添加全局样式 - 可使用
<style scoped>
添加局部样式
- 使用
添加属性Props
由于菜单的内容不变,我们可以将其写成Props属性。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22propTypes: { //属性校验器
menus: React.PropTypes.array, //表示menus属性必须是array,否则报错
usermenus: React.PropTypes.array, //表示usermenus属性必须是array,否则报错
},
getDefaultProps: function() {
return { //设置默认属性
menus: [{
title: 'index', //title用于储存路由对应的路径
href: '/index', //href用于设定该菜单跳转路由
text: '首页', //text用于储存该菜单显示名称
}, {
title: 'others',
href: '/other',
text: '其他',
}],
//usermenus用于储存侧边下拉菜单
usermenus: [{
click: function(){}, //click用于设置该菜单点击事件
text: '退出', //text用于储存该菜单显示名称
}],
};
},
添加state状态
像时间这种每500毫秒刷新一次的,我们将其放在state中。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15getInitialState: function() {
return {clock: ''}; //设置初始state值
},
//定义clockRender事件,用于改变this.state.clock值
clockRender: function(){
let numberStandard = function(num) {
let _val = Number(num), _num;
_num = (_val < 10) ? ('0' + _val) : ('' + _val);
return _num;
}, _date = new Date(),
clock = _date.getFullYear() + '年' + (_date.getMonth() + 1) + '月' +
_date.getDate() + '日' + ' ' + numberStandard(_date.getHours()) + ':' + numberStandard(_date.getMinutes()) +
':' + numberStandard(_date.getSeconds());
this.setState({clock: clock});
},
注意:state不应存储计算后的值,计算应该在render中进行,但由于比较长,本骚年也就这样将就用了。小伙伴们有更好的方法也可以提出来哦。
setInterval时钟
在componentDidMount中进行setInterval时钟。componentDidMount属于react生命周期,在初始化渲染执行之后立刻调用一次,仅客户端有效。
render就是一个模板的作用,他只处理和展示相关的逻辑,如果有业务逻辑,应放在componentWillMount和componentDidMount中执行。1
2
3
4
5
6
7
8
9
10
11//进行setInterval时钟
componentDidMount: function(){
let that = this;
this.interval = setInterval(function() {
that.clockRender();
}, 500);
},
//组件注销时需销毁定时器
componentWillUnmount: function(){
clearInterval(this.interval);
},
设置render模板
在这里大家可以看到react-bootstrap的使用方法啦。当然每个组件都是已经在该文件中引入了的。
还有jsx的遍历方法也会在这里展示。
- 在index.jsx页面引入Header时添加属性active=”index”,作为菜单选中样式的判断
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30render() {
return (
let active = this.props.active; //获取父组件传递的props
<Navbar className="header" fluid>
<Navbar.Header className="navbar-header">
<Navbar.Brand>Godbasin</Navbar.Brand>
</Navbar.Header>
<Navbar.Collapse id="bs-example-navbar-collapse-1">
<Nav navbar>
{ //遍历头部菜单menus
this.props.menus.map(function(menu, i) {
//判断,若title等于active,则加载选中样式
return (<li key={i} className={ menu.title == active ? "active" : ""}><a href={menu.href}>{ menu.text }<span className="sr-only">(current)</span></a></li>);
})
}
</Nav>
<Nav navbar pullRight>
<li><a>{ this.state.clock }</a></li>
<NavDropdown title="菜单" id="top-aside-menu">
{ //遍历右侧下拉菜单usermenus
this.props.usermenus.map(function(usermenu,i) {
return (<MenuItem key={i}>{ usermenu.text }</MenuItem>);
})
}
</NavDropdown>
</Nav>
</Navbar.Collapse>
</Navbar>
)
}
Index组件中添加Header
在components文件夹中打开Index.vue文件
1 | <template> |
结束语
Vue还是挺好用的呢,文档也写得很全很详细,虽然相应的插件、库等还是比较少,但不得不说从Angular重构还是挺多可以复用的代码呢。
此处查看项目代码
此处查看页面效果
码生艰难,写文不易,给我家猪囤点猫粮了喵~
查看Github有更多内容噢:https://github.com/godbasin
更欢迎来被删的前端游乐场边撸猫边学前端噢
如果你想要关注日常生活中的我,欢迎关注“牧羊的猪”公众号噢