@lizlalala
2017-01-04T10:29:02.000000Z
字数 4932
阅读 1493
vue
组件
最近一直困惑于mv*模式,因此想分别试一下vue的mvvm,以及backbone的mvc,重构一下之前用jquery写的最原始版本的todo。 那么第一部分便是vue的学习啦。
之前的博客里面,我们讲了vue的数据绑定以及它的用法,这一篇主要尝试它的组件化部分,与react的组件化的异同之处,以及在开发过程中尝试理解它的mvvm的思想。
ps:之前的数据绑定,因为当时公司的版本是旧的,为了继续在前fe的基础上继续写,不得已用的是0.12的版本,今天这篇的版本是1.0:)
查看vue component教程,总结来说,它是react props的扩展版本。
(1)相同的地方在于:props也是默认单向数据流,从父组件传递属性到子组件。
(2)之所以说扩展,体现在两个方面:
让我们看第一个扩展。
vue的props提供了两种使用方法,静态的+动态绑定。
用react的方式来理解的话:
//html
<div class="childWrapper">
<input v-model="dynamicMsg">
<br><span>静态绑定:</span>
<child parent-msg="dynamicMsg"></child>
<br><span>动态绑定到父元素:</span>
<child :parent-msg="dynamicMsg"></child>
</div>
//javascript
Vue.component('child', {
props: ['parentMsg'],
template: '<span>{{ parentMsg }}</span>'
})
var parent = new Vue({
el:".childWrapper",
data:{
dynamicMsg:"hello"
}
})
注意点:
1. js中的camel写法对应于html中的kebab-case
2. 如果 prop 是一个对象或数组,是按引用传递。在子组件内修改它会影响父组件的状态,不管是使用哪种绑定类型。就变成了双向绑定了
3. 如果props是数组,则需要按照动态绑定来写,使得看成变量、表达式,否则会以字符串传递。
===更新2017/1/4
4. 父组件传进来的props作为子组件data的初始值存在的话,如果它变动,内部data是不能响应的,需要设置watch(props),保持data始终在props的基础上变动
再看看第二个扩展
react的props是单向数据流,而vue中还可以实现双向的绑定。
但是最好还是不要这么做,因为父组件有很多子组件,每个都进行双向绑定的话,会有各种冲突问题,而且光看父组件的信息,很难理解父组件的状态
<child :msg.sync="parentMsg"></child>
通常是用v-bind来绑定数据,实现js中传值使得数据渲染,在交互频繁的表单上,可以用v-model进行双向绑定。
也有双向绑定的含义,watch+反向set
//child
<modal :category="category" title="禁发" :order="order" :show.sync="showModal"></modal>
parent会对showModal这个变量进行变动。
//parent button点击响应事件
showDetail(){
console.log(" ==== ", this.showModal);
this.showModal = true;
},
在modal内部
<div class="modal" v-show="show"> //here
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true" @click="closeModal">×</button>
<h4 class="modal-title">{{category}}</h4>
</div>
export default {
name:"PopModal",
props:["category","order","show"], //表明从父元素传递下来
data () {
return{
}
}
method(){
closeModal(){
this.show = false;
},
}
需要注意的是,如果modal绑定的时候是单向的,即 :show = "showModal",那么子组件内部使得show = false的时候,父组件的showModal还是保持true的状态。那么会导致父的状态是显示,子状态是不显示,那么点击 showPop按钮的时候是无法显示的。应该改为双向上。
//update
<modal :category="category" title="禁发" :order="order" :show.sync="showModal"></modal>
<style lang="scss" scoped>
.modal{
display: block;
display: flex;
align-items:center;
justify-content:center;
background-color: rgba(11, 11, 11, 0.6);
.action{
cursor: pointer;
}
}
.modal-dialog{
max-width: 30%;
}
</style>
<ul class="nav nav-tabs">
<li class=""><a v-link=" '/event/list' " >信息列表</a></li>
<li><a v-link=" '/event/create' " >创建事件</a></li>
</ul>
这边的v-link 跟v-on一样,里面的默认是一个变量,如果想传递字符串进去,需要另加单引号
同理,@click,看这个例子
// toggleActive()里面的如果直接是A,会认为是一个变量,无法得到,需要变成字符串
<li :class="['tab-item',isA?'tab-active':''] " @click="toggleAcitive('A')"><a v-link=" '/event/list' " >信息列表</a></li>
<li :class="['tab-item',!isA?'tab-active':''] " @click="toggleAcitive('B')"><a v-link=" '/event/create' ">创建事件</a></li>
3, class 动态绑定
<li class="pageList[0]===1?'disabled':''">
这样是无法识别的,里面不是三元符,而是就是 一个字符串,需要加bind绑定才会变成三元表达式
:class="[ 'tag', {active: item.id===filterCategory.id}]"
4,input checkbox绑定到一个数组的时候,需要指定他们的value,否则相当于一个,会同时选中或不选中,指定后才会各自控制。
handleEventEdited(data){
//直接更新
var temp = Object.assign({},this.eventList);
this.eventList = this.eventList.map(event=>{
if(event.name==data.name)
return Object.assign({},event,{name:data.newName});
else return event;
});
//发送请求
this.$http.post(server_path+"/event",data).then((response)=>{
console.log("事件修改成功");
},(err)=>{
//修改失败后回退
this.eventList = temp;
console.log("事件修改失败");
});
},
楼主最近的开发过程中遇到这么一个问题,单页应用,最外层组件为app.vue。内层靠路由嵌套了几个子组件。子组件页面一加载就需要去发请求获取数据,而请求的param里面依赖父组件获得的数据。
在no组件,no单页的情况下,这种可以用一个页面加载同步请求去搞定。但是现在不允许这样。还牵扯到该在哪个合适的生命周期里去发送请求的问题。
困惑点1:
之前写react的时候,官方建议在componentDidMount里面进行fetch,但是我比较疑惑的是为什么不在componentWillMount或者render里面操作。因为1,数据取得后就一直存在着,mount以后肯定可以显示。2,难道是因为willMount和render是在dom渲染,可能阻塞ui线程的问题。但是ajax是另开一个线程啊,应该是不影响的啊。
科普一下vue的生命周期,楼主大概打印了一下mount之前的执行顺序。
结合官网的生命周期列表,我们可以看到,都会经历如下的过程:
beforeCreated-> 生成data,computed 这些数据,初始化事件
->created,实例对象被创建
-> 在从created到beforeMount过程中编译模板(template)
-> 编译完成后将template插入el或者父html中,这就完成了mounted。
而对于父组件,因为嵌套了子组件,它的mount需要等到子组件都处理完,生成el并插入document后才算完成。也就解释了上面打印的内容。
现在的规划大概是这样的,在父组件created的时候去fetch数据。然后在子组件中用v-if='isParentDataGot' 来确定装载与否。因为上面我们说了,子组件先创建实例,去计算这些data,既然父组件数据还未获取。那么本组件v-if === false。不显示
但是子组件的生命周期还在进行。只是当父组件获取到后update,把数据附上去,
然后在mounted里面去发送自己的请求。
困惑点2:
楼主想知道是否可以在beforeMount里面return false来控制是否装载。
困惑点3:
一般是在mounted发送请求,那么vue现在的生命周期中,在created,beforeMount这些里面发送会有什么影响。
mouseenter mouseover区别
mouseenter只在刚进入某个元素时触发,不会冒泡
而mouseover在进入,以及在该元素上移动时都会触发
git远程合并
楼主是项目owner的话,接受远程pull request后merge到dev分支。
本地
git fetch bit-origin dev:new-branch
git checkout new-branch 查看最新代码。如果可以的话
git checkout dev
git merge new-branch。使得dev为最终代码
git remove new-branch