vue
之前的博客里面,我们讲了vue的数据绑定以及它的用法,而由于之前一直用react开发,难免会进行相互比较,那么这一篇就以与react联系的角度来看看vue的一些特性。
ps:之前的数据绑定,因为当时公司的版本是旧的,为了继续在前fe的基础上继续写,不得已用的是0.12的版本,今天这篇的版本是1.0:)
组件化
props:
查看vue component教程,总结来说,它是react props的扩展版本。
(1)相同的地方在于:props也是默认单向数据流,从父组件传递属性到子组件。
(2)之所以说扩展,体现在两个方面:
- 扩展一:props in vue == [伪]props in react;
- 扩展二:props in vue 可单向,可双向绑定数据。
让我们看第一个扩展。
vue的props提供了两种使用方法,静态的+动态绑定。
用react的方式来理解的话:
- props == 子组件默认的不可变属性。
- 绑定的props== props in react。
默认情况下,props只负责传递父组件传给它的属性,且当组件加载后只传递一次,我们可以看到,下面的静态绑定demo中,虽然跟父model同名,但是只解析为字符串,只有变成动态绑定的props,才会解析为从父元素传递下来的变量。每次父组件的相关数据进行变化时,子组件便会随之更改,类似于react中的props.
See the Pen vue组件化demo by lu (@luchen) on CodePen.
|
|
|
|
注意点:
- js中的camel写法对应于html中的kebab-case
- 如果 prop 是一个对象或数组,是按引用传递。在子组件内修改它会影响父组件的状态,不管是使用哪种绑定类型。就变成了双向绑定了
- 如果props是数组,则需要按照动态绑定来写,使得看成变量、表达式,否则会以字符串传递。
===更新2017/1/4 - 父组件传进来的props作为子组件data的初始值存在的话,如果它变动,内部data是不能响应的,需要设置watch(props),保持data始终在props的基础上变动
再看看第二个扩展
react的props是单向数据流,而vue中还可以实现双向的绑定。
但是最好还是不要这么做,因为父组件有很多子组件,每个都进行双向绑定的话,会有各种冲突问题,而且光看父组件的信息,很难理解父组件的状态
|
|
通常是用v-bind来绑定数据,实现js中传值使得数据渲染,在交互频繁的表单上,可以用v-model进行双向绑定。
计算属性
也有双向绑定的含义,watch+反向set
双向props示例
|
|
parent会对showModal这个变量进行变动。
|
|
在modal内部
|
|
|
|
需要注意的是,如果modal绑定的时候是单向的,即 :show = “showModal”,那么子组件内部使得show = false的时候,父组件的showModal还是保持true的状态。那么会导致父的状态是显示,子状态是不显示,那么点击 showPop按钮的时候是无法显示的。应该改为双向上。
|
|
开发杂项
scope 限制css
A组件,B组件都引入到组件C中,但是A,B都有同样的样式.class name,那么会冲突,因此需要用scope 去进行限制,而且需要注意的是在style里面进行 import,scope是不起作用的。只能inline css12345678910111213141516<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>vue-router 注意事项
1234
<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,看这个例子
123
// 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>
class 动态绑定
1<li class="pageList[0]===1?'disabled':''">这样是无法识别的,里面不是三元符,而是就是 一个字符串,需要加bind绑定才会变成三元表达式
input checkbox绑定到一个数组的时候,需要指定他们的value,否则相当于一个,会同时选中或不选中,指定后才会各自控制。
ajax ui体验优化
12345678910111213141516171819handleEventEdited(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分支。
本地12345git fetch bit-origin dev:new-branchgit checkout new-branch 查看最新代码。如果可以的话git checkout devgit merge new-branch。使得dev为最终代码git remove new-branch