从零开始学习Vue(三)
我们从一个例子来学习组件,vuejs2.0实战:仿豆瓣app项目,创建自定义组件tabbar
这个例子用到其他组件,对于初学者来说,一下子要了解那么多组件的使用,会变得一头雾水。所以我把这个例子改写了一下,只需要依赖Vue.
然后最好FQ安装一个chrome的扩展 vue-devtools,这样可以更好看到组件的内容
组件(Component)是 Vue.js 最强大的功能之一。组件可以扩展 HTML 元素,封装可重用的代码。
在较高层面上,组件是自定义元素, Vue.js 的编译器为它添加特殊功能。在有些情况下,组件也可以是原生 HTML 元素的形式,以 is 特性扩展。
父子组件的关系可以总结为 props down, events up 。父组件通过 props 向下传递数据给子组件,子组件通过 events 给父组件发送消息。
SLOT的理解: 子组件有名字的slot,将会给父组件同名的slot替换掉, 子组件匿名的slot, 将会给父组件的其他没slot名字的内容替换掉.
<m-tabbar-item id='tab1'>
<img src="../assets/images/ic_tab_home_normal.png" alt="" slot="icon-normal">
<img src="../assets/images/ic_tab_home_active.png" alt="" slot="icon-active">
首页
</m-tabbar-item>
子组件模板:
<a class="m-tabbar-item" :class="{'is-active':isActive}" @click="$parent.$emit('input',id)">
<span class="m-tabbar-item-icon" v-show="!isActive"><slot name="icon-normal"></slot></span>
<span class="m-tabbar-item-icon" v-show="isActive"><slot name="icon-active"></slot></span>
<span class="m-tabbar-item-text"><slot></slot></span>
</a>
最终生成的HTML:
<a class="m-tabbar-item">
<span class="m-tabbar-item-icon">
<img src="../assets/images/ic_tab_home_normal.png" alt=""></span>
<span class="m-tabbar-item-icon" style="display: none;">
<img src="../assets/images/ic_tab_home_active.png" alt=""></span>
<span class="m-tabbar-item-text">
首页
</span>
</a>
<img src="../assets/images/ic_tab_home_normal.png" alt="" slot="icon-normal"> 会替换掉 <slot name="icon-normal"></slot>
<img src="../assets/images/ic_tab_home_active.png" alt="" slot="icon-active"/> 会替换掉 <slot name="icon-active"></slot>,并把slot的名字去掉
首页 会替换掉 <slot></slot> 这个匿名的. 整个页面的代码如下:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<meta content="width=device-width,initial-scale=1,user-scalable=no" name="viewport" />
<script src="Scripts/vue.js" type="text/javascript"></script>
<style type="text/css">
.m-tabbar
{
display: flex;
flex-direction: row;
position: fixed;
bottom: 0;
left: 0;
right: 0;
width: 100%;
overflow: hidden;
height: 50px;
background: #fff;
border-top: 1px solid #e4e4e4;
}
.m-tabbar-item
{
flex: 1;
text-align: center;
}
.m-tabbar-item-icon
{
display: block;
padding-top: 2px;
}
.m-tabbar-item-icon img
{
width: 28px;
height: 28px;
}
.m-tabbar-item-text
{
display: block;
font-size: 10px;
color: #949494;
}
.is-active
{
color: #42bd56;
}
</style>
</head>
<body>
<div id="app">
<div>
<m-tabbar v-model="select">
<m-tabbar-item id='tab1'> <img src="../assets/images/ic_tab_home_normal.png" alt="" slot="icon-normal">
<img src="../assets/images/ic_tab_home_active.png" alt="" slot="icon-active">
首页
</m-tabbar-item>
<m-tabbar-item id='tab2'>
<img src="../assets/images/ic_tab_subject_normal.png" alt="" slot="icon-normal">
<img src="../assets/images/ic_tab_subject_active.png" alt="" slot="icon-active">
书影音
</m-tabbar-item>
<m-tabbar-item id='tab3'>
<img src="../assets/images/ic_tab_status_normal.png" alt="" slot="icon-normal">
<img src="../assets/images/ic_tab_status_active.png" alt="" slot="icon-active">
广播
</m-tabbar-item>
<m-tabbar-item id='tab4'>
<img src="../assets/images/ic_tab_group_normal.png" alt="" slot="icon-normal">
<img src="../assets/images/ic_tab_group_active.png" alt="" slot="icon-active">
小组
</m-tabbar-item>
<m-tabbar-item id='tab5'>
<img src="../assets/images/ic_tab_profile_normal.png" alt="" slot="icon-normal">
<img src="../assets/images/ic_tab_profile_active.png" alt="" slot="icon-active">
我的
</m-tabbar-item>
</m-tabbar>
</div>
</div>
<script type="text/javascript">
Vue.component("m-tabbar", {
props: ['value'],
template:'<div class="m-tabbar"><slot></slot></div>'
}); Vue.component("m-tabbar-item", {
props: ['id'],
computed: {
isActive(){
if(this.$parent.value===this.id){
return true;
}
else
return false;
}
},
template:'<a class="m-tabbar-item" :class="{\'is-active\':isActive}" @click="$parent.$emit(\'input\',id)">'
+'<span class="m-tabbar-item-icon" v-show="!isActive"><slot name="icon-normal"></slot></span>'
+'<span class="m-tabbar-item-icon" v-show="isActive"><slot name="icon-active"></slot></span>'
+ '<span class="m-tabbar-item-text"><slot></slot></span>'
+'</a>'
});
var app = new Vue({
el: '#app',
data: {
select:"tab1"
}
});
</script>
</body>
</html>
m-tabbar组件的双向绑定 v-model="select" 说明m-tabbar暴露出的属性value是和data里的select字段关联的,页面默认选中的是第一个tab,它的Id是tab1.
m-tabbar-item组件里有一个判断 this.$parent.value===this.id,父组件的value等于子组件的Id,则该子组件为选中的。
@click="$parent.$emit(\'input\',id)" 这个方法, 请参考这里 https://cn.vuejs.org/v2/guide/components.html#使用自定义事件的表单输入组件
<m-tabbar v-model="select">等价于 <m-tabbar v-bind:value="select" v-on:input="select=arguments[0]">
所以要让组件的 v-model 生效,它必须:
接受一个 value 属性
在有新的 value 时触发 input 事件
所以@click="$parent.$emit(\'input\',id)" 这个方法就是在子组件click的事件,触发父组件的input事件把子组件的Id传个父组件的value属性
问题来了:为什么父组件有个input事件呢? 它只是个div而已,我可以把这个事件名字改成其他的吗? 改成下面的代码,把事件名改成abcdef,是可以通过的
<m-tabbar v-bind:value="selectId" v-on:abcdef="tabSelect">
<script type="text/javascript">
Vue.component("m-tabbar", {
props: ['value'],
template:'<div class="m-tabbar"><slot></slot></div>',
mounted: function () {
console.log("m-tabbar mounted");
}
}); Vue.component("m-tabbar-item", {
props: ['id'],
mounted: function () {
console.log("m-tabbar-item mounted");
},
computed: {
isActive(){
if(this.$parent.value===this.id){
return true;
}
else
return false;
}
},
template:'<a class="m-tabbar-item" :class="{\'is-active\':isActive}" @click="$parent.$emit(\'abcdef\',id)">'
+'<span class="m-tabbar-item-icon" v-show="!isActive"><slot name="icon-normal"></slot></span>'
+'<span class="m-tabbar-item-icon" v-show="isActive"><slot name="icon-active"></slot></span>'
+ '<span class="m-tabbar-item-text"><slot></slot></span>'
+'</a>'
});
var app = new Vue({
el: '#app',
data: {
selectId:"tab1"
},
methods:{
tabSelect:function(Id){
console.log("tabSelect");
this.selectId= Id;
}
}
});
</script>
是任意名字都可以吗? 不是的,我试过有2个是不行的。 当事件名里有包含Select或者Index这2个词时,父组件就监听不到这个事件了。 难道这2个是什么保留字, 有人知道吗?
从零开始学习Vue(三)的更多相关文章
- 从零开始学习jQuery (三) 管理jQuery包装集
本系列文章导航 从零开始学习jQuery (三) 管理jQuery包装集 一.摘要 在使用jQuery选择器获取到jQuery包装集后, 我们需要对其进行操作. 本章首先讲解如何动态的创建元素, 接着 ...
- 从零开始学习Vue.js,学习笔记
一.为什么学习vue.js methods 只有纯粹的数据逻辑,而不是去处理 DOM 事件细节. vue.js兼具angular.js和react的优点,并且剔除了他们的缺点 官网:http://cn ...
- 从零开始学习vue(2)
一.vue实例 每个vue应用都是通过Vue构造函数创建的一个新的实例开始的: var vm = new Vue({ //选项对象 }) 在这其中vm(viewModel的简称)通常都表示vue实例的 ...
- 从零开始学习Vue(一)
因为最近有个项目的需求是,微信公众号+IOS/Android APP, 界面都很类似. 以往的做法是APP是调用JSON接口,后台只负责提供接口. 而H5,我以前都是用Jquery,用来写手机网站总是 ...
- 前端框架开始学习Vue(三)
初步安装.与搭建 https://www.cnblogs.com/yanxulan/p/8978732.html ----如何搭建一个vue项目 安装 nodejs,,, npm i == np ...
- oracle从零开始学习笔记 三
高级查询 随机返回5条记录 select * from (select ename,job from emp order by dbms_random.value())where rownum< ...
- 从零开始学习Vue(四)
这里引入一个概念SPA(single Page Application), 接着上次的例子,我们在页面底部做了一个Tab的菜单,点击不同的按钮应该是显示不同的内容. 按传统的MVC的思维,我要在Con ...
- 从零开始学习Vue(二)
思维方式的变化 WebForm时代, Aspx.cs 取得数据,绑定到前台的Repeater之类的控件.重新渲染整个HTML页面.就是整个页面不断的刷新;后来微软打了个补丁,推出了AJAX控件,比如U ...
- 从零开始学习jQuery(转)
本系列文章导航 从零开始学习jQuery (一) 开天辟地入门篇 从零开始学习jQuery (二) 万能的选择器 从零开始学习jQuery (三) 管理jQuery包装集 从零开始学习jQuery ( ...
随机推荐
- Activity的生命周期与加载模式——Activity的4种加载模式
配置Activity时可指定android:launchMode属性,该属性用于配置该Activity的加载模式,该属性支持如下4个属性值. standard:标准模式,这是默认的加载模式. sing ...
- weblogic 集群部署时上传jsp不更新问题
在进行集群部署的时候,进行“源可访问性”设置的时候,要注意选择“我要使部署能够通过下列位置进行访问”: 前提是必须有共享存储:
- 关于在官网上下载Eclipse遇到的问题!!
首先Eclipse是什么? Eclipse 是一个开放源代码的.基于Java的可扩展开发平台.就其本身而言,它只是一个框架和一组服务,用于通过插件组件构建开发环境. 幸运的是,Eclipse 附带了一 ...
- 如何使用DockerHub官方的mysql镜像
Mysql是一个广泛使用的开源关系型数据库. 如何获取Mysql Docker镜像? docker pull mysql:5.7 如何使用这个Docker镜像? 1.启动一个Mysql Server容 ...
- 为什么python适合写爬虫?(python到底有啥好的?!)
我用c#,java都写过爬虫.区别不大,原理就是利用好正则表达式.只不过是平台问题.后来了解到很多爬虫都是用python写的.因为目前对python并不熟,所以也不知道这是为什么.百度了下结果: 1) ...
- 图论——Dijkstra算法
图论其实是比较难的一种题型,但是一些模板题,是没有什么太大难度的! 这里给大家带来的是迪杰斯特拉(Dijkstra)算法. 迪杰斯特拉算法是由荷兰计算机科学家狄克斯特拉于1959 年提出的,因此又叫狄 ...
- [html5] 学习笔记-表单新增元素与属性
本节讲的是表单元素的form,formaction属性,frommethod,formenctype属性,formtarget,autofocus属性,required,labels属性. 1.for ...
- JAVA中的访问修饰符和包
一.JAVA访问修饰符 访问修饰符,用来控制类中成员的可见性 有四个访问修饰符,分别是:default,private,public,protected 1.default(默认):默认权限,不用写的 ...
- yii2 邮件发送(有图有真相)
经典的密码找回方案是发送邮件到用户邮箱然后修改密码,下面利用yii2 高级版的mail功能,进行邮件的发送,如下图 1.在comm/config/main-local.php中添加 'mailer' ...
- 在GlassFish应用服务器上创建并运行你的第一个Restful Web Service【翻译】
前言 本人一直开发Android应用,目前Android就业形势恶劣,甚至会一路下滑,因此决定学习服务器开发.采用的语言是java,IDE是Intellij,在下载Intellij的同时看到官网很多优 ...