Vue.js无疑是最近最火的一套渐进式前端框架。Vue的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。其轻量级,渐进式的优点对开发者的吸引力毋庸置疑。我使用过两年的Angular,对Vue也充满了好奇,于是也想认识一下Vue。
Vue.js安装
主流的安装方式当然是使用vue-cli工具,这跟angular挺像的。但是作为刚入门的开发者,官方比较推荐的安装方式是直接引入script。vue脚本也分为开发版vue.js和生产版vue.min.js,开发环境下推荐使用vue.js,可以在开发过程中看到常见错误相关的警告。你可以选择使用CDN服务,直接引入这个脚本即可进行开发。
1 | <script src="https://cdn.jsdelivr.net/npm/vue@2.5.14/dist/vue.js"></script> |
我还是习惯直接把脚本下载到项目文件夹中。
1 | <script src="./lib/vue.js"></script> |
学习Vue
学习Vue.js最好的方法当然是把代码都撸一遍,这样印象会比较深刻。
v-if
这个指令类似于angular的*ngIf,作为一个结构性指令,用来控制元素的插入和移除。当v-if=”true”时,元素正常显示;反之元素则被移除。
v-show
这个指令达到的效果看起来与v-if是一样的,但是从本质上来讲是不同的。v-show其实仅仅从样式上来控制显示和隐藏,改变的是display属性。与jQuery的show()和hide()方法有异曲同工之妙。
插值表达式
1 | <span>{{ content }}</span> |
这个是数据绑定的标准写法,与angular是一样的。content变量的值改变时,页面渲染也随之变化。插值表达式中支持js表达式。
v-html
从字面意思能看出来,该指令绑定的值会输出html内容,类似于jQuery的html()方法。在angular中好像没有看到这个指令,我是自定义了一个directive来实现的。
属性绑定v-bind
这个指令用来绑定元素属性,通常用于向子组件传递props。比如子组件studentList内部需要属性id来做逻辑判断,这个id可以由父组件来传递,这里就可以使用到v-bind。
1 | <student-list v-bind:id="somevalue"></student-list> |
v-bind:可以缩写为:
1 | <student-list :id="somevalue"></student-list> |
事件绑定v-on
用来绑定事件,比如鼠标点击事件,可以这样写:
1 | <button v-on:click="toggleVueIf">Toggle VUE IF</button> |
v-bind:可以缩写为@:
1 | <button @click="toggleVueIf">Toggle VUE IF</button> |
v-for
v-for用来遍历数组或对象
(1)数组,接收的参数上可以是两个,顺序是value, index
1 | <ul v-for="(value, index) in vueForArray"> |
(2)对象,接收的参数上可以是三个,顺序是value, key, index
1 | <ul v-for="(value, key, index) in vueForObject"> |
计算属性computed
对于插值表达式中涉及到的复杂计算,建议用计算属性computed来替代。在new Vue时可以使用computed属性。
1 | // html中 |
这里只是一个倒序的算法,不算很复杂,只是举例说明。
watch属性
我们可以使用watch来进行侦听,来响应数据的变化。上面计算属性的应用,我们也可以改用watch来写:
1 | watch: { |
这里,我们通过侦听testMessage的变化来做出响应,用于改变reversedMessage的值。
ps:那么computed和watch的应用场景怎么区分?
个人认为,computed更适合做一些数据值的计算,而涉及到侦听某变量需要做一些业务处理时,建议使用watch。
class绑定
1 | <!-- 类似这种形式,与属性绑定大同小异。class的绑定值可以是键值对,也可以是数组。 --> |
style绑定
与class绑定类似,支持键值对语法(css键值对),也支持数组(多个样式对象同时作用)。
1 | <div :style="{ color: activeColor, fontSize: fontSize + 'px' }"></div> |
双向绑定v-model
这一特性与angular的[(ngModel)]是一致的。通常用于表单元素。
1 | <input v-model="message" placeholder="edit me"> |
不过v-model还支持很多修饰符,如
(1).lazy
1 | <!-- 在“change”时而非“input”时更新 --> |
(2).number
自动将用户的输入值转为数值类型
(3).trim
自动过滤用户输入的首尾空白字符
.sync
看名字就知道了,同步的意思,如果绑定的属性加上这个修饰符,就实现了双向绑定。.sync破坏了单向数据流,于2.0 中移除,但又在 2.3.0 版本后以语法糖形式重新引入。
1 | <comp :foo.sync="bar"></comp> |
父子组件通信
父组件通过属性传递数据给子组件props,而子组件以this.$emit(eventname, data)的方式发事件给父组件,父组件模板中需要绑定对应事件。
1 | // 父组件模板,通过绑定greet传递数据给子组件,@replay接收来自子组件的事件。 |
slot
类似angular的ng-content。父组件可以将想要的内容插在子组件的插槽中。子组件slot标签通过name属性区分插槽,如name=”slot1”,不写name属性的就是默认插槽了;而父组件要在传递给插槽的标签中加上slot属性来区分插在哪个槽中,如slot=”slot1”,如果不加slot属性,则自动插在默认插槽中。slot标签中的内容都被视为备用内容,如果父组件不给子组件传入内容,则会显示子组件slot标签中的备用内容。使用如下:
1 | <!-- 父组件模板 --> |
作用域插槽
官方提供的说明我不太看得懂,根据我个人的理解,一个很重要的应用场景就是用来抽象列表式组件。比如一个展示性的列表组件,但是具体展示图文,还是其他的,需要由其父组件来指定。我这里写了一个demo。
1 | <!-- 父组件模板 --> |
使用要点:
(1)父组件通过属性绑定将数据(一般是数组,毕竟是用于列表展示嘛)传递给子组件。
1 | <my-list :items="movies"></my-list> |
(2)父组件传递给子组件的内容用template标签包裹,template标签具备slot-scope=”props”,props来源于子组件slot标签绑定的属性集,而本例中slot标签绑定了item属性,所以template中的内容可以调用props.item下的属性。
动态组件
利用component标签及其is属性可以动态切换组件。curComponent的值为组件名。
1 | <component :is="curComponent"></component> |
keep-alive标签
利用keep-alive标签包裹component标签可以让切换组件保留在内存中,可以保留它的状态,避免重新渲染。
1 | <keep-alive> |
ref属性
ref属性实现了组件的引用,不过应当避免使用ref。
1 | <ref-comp ref="refComp"></ref-comp> |
transition过渡
在组件外包裹一层transition标签,name标识transition,即可为组件加上过渡效果。如:
1 | <transition name="fade"> |
在进入/离开的过渡中,会有 6 个 class 切换,默认 class 名称格式如下。
- fade-enter // 进入过渡开始,一般在这个class下定义-过渡开始时的css状态
- fade-enter-active // 进入过渡活跃状态,一般在这个-class下定义进入过渡过程中的动画
- fade-enter-to // 进入过渡结束,一般在这个class下定义过渡结束时的css状态。ps:离开过渡不再说明,类似开始过渡。
- fade-leave // 离开过渡开始
- fade-leave-active // 离开过渡活跃状态
- fade-leave-to // 离开过渡结束
我们也可以自定义过渡类名,需要增加transition标签的属性,这样就可以使用第三方的动画库了。用法如下:
1 | <transition name="fade" enter-active-class="animated tada" leave-active-class="animated bounceOutRight"> |
过渡效果主要的应用场景有:
- v-if
- v-show
- 动态组件
transition有着一系列javascript钩子函数,从字面意思可以与过渡的class对应起来,如下所示:
1 | <transition |
钩子函数都有参数el,用于引用添加了transition包裹的元素。enter和leave钩子函数中额外有一个参数done,done是一个回调函数,是必须在最后调用的。否则,它们会被同步调用,过渡会立即完成。
1 | enter: function (el, done) { |
有了js钩子函数,那么我就可以不使用class来定义过渡的效果了,我可以使用js动画库,如velocity.js,这个时候最好添加v-bind:css=”false”,Vue 会跳过 CSS 的检测。这也可以避免过渡过程中 CSS 的影响。
我们可以给元素设置初始渲染的过渡效果。
1 | <transition appear> |
appear拥有相同的class钩子和js钩子,也可以自定义类名。
多个元素的过渡
transition中多个元素过渡时,可以这样写,给每个元素加上key属性来作为唯一标识:
1 | <transition> |
上述代码也可以简写为绑定key的形式,而不再需要if,else:
1 | <transition> |
其中的isEditing ? ‘Save’ : ‘Edit’也可以抽象为一个computed属性。
除了多个元素的过渡,类似的还有动态组件的过渡。
1 | <transition name="fade-dynamic" mode="out-in"> |
mode属性定义了过渡模式,防止当前元素的离开与下一个元素的进入产生重叠现象:
- in-out:新元素先进行过渡,完成之后当前元素过渡离开。
- out-in:当前元素先进行过渡,完成之后新元素过渡进入。
列表过渡
列表过渡用到的组件是transition-group。transition-group会以真实的元素存在于html文档中,而transition是不存在于html文档中的。transition-group存在的形式由tag属性指定,如
1 | <transition-group name="group-list" tag="div"> |
为了让group-list的过渡效果平滑,有一个v-move属性,也是通过绑定class实现
1 | .group-list-move { |
另一种实现方式如下:
1 | .group-item { |
mixin
mixin是一种提高编写效率的写法,详情请参考mixin。
vue自定义指令
一个指令定义对象可以提供如下几个钩子函数。
- bind:只调用一次,指令第一次绑定到元素时调用。
- inserted:被绑定元素插入父节点时调用
- update
- componentUpdated
- unbind
目前未对指令进行深究,只写了一个简单的指令。
1 | directives: { |
vue组件生命周期
参考:
(1)Vue2.0 探索之路——生命周期和钩子函数的一些理解
(2)API
扫一扫下方小程序码或搜索Tusi博客
,即刻阅读最新文章!