通过这段时间的学习,我对于vue.js有了一定的了解。
下面是我的一些学习心得,主要分为三部分:
- vue.js相关概念
- 工具和插件使用
- 学习感想
相关概念
什么是Vue.js
Vue.js是一个用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。
Vue.js采用MVVM的设计模式(M-Model,V-View,VM-ViewModel),将数据和视图分离,用数据来驱动视图。vue专注于view(视图层),view层的变化由数据操控,即所有的一切通过操作数据来进行,尽量避免操作dom树。与此同时,View和ViewModel之间通过双向绑定建立联系,即View变化,ViewMode也会发生相应的变化,反之亦然。
vue生命周期
每个 vue 实例创建时,都会经历一系列的初始化过程,这个过程就是生命周期。在周期中会调用相应的生命周期钩子。我们可以利用这些钩子,在合适的时机执行我们的业务逻辑。
如图所示,从实例开始创建到销毁的过程中有八个生命周期钩子,常用的有
- created 实例创建完成后调用,此阶段完成了数据的观测等,但尚未挂载, $el 还不可用。需要初始化处理一些数据时会比较有用
- mounted el 挂载到实例上后调用,一般我们的第一个业务逻辑会在这里开始
- beforeDestroy 实例销毁之前调用。主要解绑一些使用 addEventListener 监听的事件等。
指令
指令是vue 模板中最常用的一项功能,它带有前缀v-。指令的主要职责就是当其表达式的值改变时,相应地将某些行为应用到 DOM 上。常用的指令有
- v-bind:动态更新html上的属性
- v-model:用在表单控件元素上创建双向数据绑定的。根据控件类型v-model自动选取正确的方法更新元素。
- v-for:循环渲染
- v-if:根据表达式的值在DOM中生成或移除一个元素。
- v-show:根据表达式的值控制元素显示隐藏,类似display:block/none
- v-else:跟着v-if或者v-show使用
- v-on:绑定事件监听器
注:一般来说,v-if有更高的切换消耗,而v-show有更高的初始渲染消耗。因此,如果需要频繁的切换,则使用v-show较好;如果在运行时条件不大可能改变,则使用v-if较好。
插值与表达式
双大括号'{{}}'是最基本的文本插值方法,会自动将双向绑定的数据实时显示出来
在'{{}}'中,除了简单的绑定属性值外,还可 使用 JavaScript 表达式进行简单的运算, 三元运算等。因为文本插值只支持单个表达式,如果表达式过长或者逻辑复杂时可以使用计算属性
<div id=" app ">
{{book}} //显示《Vue.js实战》
{{price / 10}}//显示3
{{isOk?'yes':'no'}}//显示no
</div>
<script>
var app =new Vue({
el:'#app',
data:{
book:'《Vue.js 实战》',
price:'30',
isOk:false
}
})
</script>
计算属性与方法
所有的计算属性都以函数的形式写在 Vue 实例内的 computed 选项内,最终返回计算后的结果。每一个计算属性都有一个getter方法和setter方法,分别用来读取和写入,绝大多数情况下,我们只会用默认的 getter 方法来读取计算属性,所以声明计算属性时直接使用默认的写法,不声明getter和setter,但是在使用vuex结合表单时,在计算属性中就需要getter和setter方法,否则修改表单会报错。
<div id=" app ">
{{text.split(',').reverse().join(',')}}
{{reverseText}}
</div>
<script>
var app =new Vue({
el:'#app',
data:{
text:'123,456'
},
computed:{
reverseText:function(){
return this.text.split(',').reverse().join(',')
}
}
})
</script>
vue中方法都写在实例的methods属性中。Vue.js将methods 里的方法也代理了,所以也可以像访问 Vue 数据那样来调用方法
<div id=" app ">
{{reverseText}}
</div>
<script>
var app =new Vue({
el:'#app',
data:{
text:'123,456'
},
methods:{
reverseText:function(){
return this.text.split(',').reverse().join(',')
}
}
})
</script>
从上面两段代码可以发现使用methods的方法可以起到和计算属性相同的属性,但是计算属性和方法还是有区别的。计算属性是基于它的依赖缓存的。 个计算属性所依赖的数据发生变化时,它才会重新取值,所以text 只要不改变,计算属性也就不更新,但methods不同,只要重新渲染就会被调用,函数也会执行。
使用计算属性还是 methods 取决于你是否需要缓存,当遍历大数组和做大量计算时,应当使用计算属性,除非你不希望得到缓存。
数据双向绑定
<div id="app">
<input type="text" v-model=" name" placeholder="你的名字"
<hl>你好,{{ name }}</hl>
</div>
<script>
var app = new Vue({
el: '#app',
data:{
name:''
})
</script>
上面代码体现了vue的数据双向绑定功能,input标签使用v-model指令绑定了数据name,v-model是一个双向绑定指令,所以用户在输入框中输入时,会更新数据name的值,当使用app.name = 'XXX'更新数据时输入框中内容也会发生改变。
组件
任何一个页面都可以划分成很多功能独立的组件,然后像搭积木一样搭建页面。
组件是可复用的vue实例,和new Vue 接收相同的选项,例如 data、computed、watch、methods 以及生命周期钩子等。仅有的例外是像 el 这样根实例特有的选项。
需要注意的一点是:组件中的data必须是一个函数,这样组件复用时每个组件才能维护自己独立的数据,否则复用的组件共用一份数据。
注册
组件必须先注册才能使用,注册有两种方式:全局注册和局部注册。全局注册后任何vue实例都可以调用。
组件都只是通过 Vue.component 全局注册的
<div id="app">
<my-component></my-component>
</div>
<script>
Vue.component('my-component', {
// ... options ...
})
var app =new Vue({
el :'#app'
})
</script>
在vue实例中,可以使用components选项局部注册组件,注册的组件只在该实例作用域下有效。
<div id="app ">
<my-component></my-component>
</div>
<script>
var Child = {
template:'<div>局部注册组件的内容</div>'
}
var app =new Vue((
el:'app',
components:{
'my-component':Child
}
})
</script>
通信
- 父->子
父组件通过props向子组件传递数据
<div id="app">
<my-component :message="parentMessage"></my-component>
</div>
<script>
Vue.component('my-component', {
props:['message'],
template:'<div>{{message}}</div>'
})
var app =new Vue({
el :'#app',
data(){
parentMessage:'哈哈哈',
}
})
</script>
- 子->父
子组件通过$emit触发事件,父组件通过v-on来监听子组件的事件
<div id="app">
<p>总数:{{total}}</p>
<my-component @increase="handleTotal"></my-component>
</div>
<script>
Vue.component('my-component', {
data(){
count:0
},
template:'<div><button @click="handler">+</button></div>',
methods:{
handler:function(){
this.count++;
this.$emit('increase',this.count);
}
}
})
var app =new Vue({
el :'#app',
data(){
total:0
},
methods:{
handleTotal:function(val){
this.total = total;
}
}
})
</script>
- 兄弟组件
将数据上传至共同父组件中,再由父组件传递给子组件
为了便于开发,Vue 推出了一个状态管理工具 Vuex,可以很方便实现组件之间的参数传递
虚拟dom
之前有简单了解react前端框架,react使用了虚拟DOM来提高性能,合并Dom操作,加快页面的刷新速度。vue2.0加入了虚拟dom的概念,虚拟dom操作相对快速。通过对虚拟DOM进行diff,逐步找到更新前后虚拟dom的差异,然后更新变化的部分,减少了因为页面重排dom树结构变化产生的性能耗费。
工具和插件的使用
在使用vue写项目时,通常会结合webpack打包工具,vuex状态管理工具以及vue-router前端路由管理等工具。
webpack
在使用webpack时,首先要配置webpack.config.js文件,配置入口文件,出口文件,loaders和plugins,配置完成后,启动项目webpack会自动分析模块间引用关系,将用到的模块进行打包。而且webpack有丰富的插件可以使用。
vuex
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。使用时需要在main.js中引入,同时使用vue.use(vuex),然后创建store,传入根组件,这样每个子组件都能获取store中的state,state不能直接改变,只能通过显式的提交mutations。vuex还提供了getters,actions和modules等选项。getters可以将计算属性中处理从store获得数据的过程提取出来实现复用,mutation 里不应该异步操作数据,所以有了 actions选项 ,action和mutation很像,但是action里面提交的是mutation,并且可以异步操作业务逻辑。最后一个选项是 modules ,它用来将 store 分割到不同模块。当你的项目足够大时, store 里的state, getters, mutations, actions 会非常多,都放在 rnain.js 里显得不是很友好,使用 modules 可以把它们写到不同的文件中。每个 module 拥有自己的 state getters, mutations, actions ,而且可以多层嵌套。
const moduleA = {
state: { . . . } ,
mutations: { . . . } ,
actions: { . . . ) ,
getters: { . . . )
}
const moduleB = {
state: { . . . } ,
mutations: { . . . } ,
actions: { . . . ) ,
getters: { . . . )
}
const store= new Vuex . Store ( {
modules : {
a: moduleA,
b: moduleB
}
})
vue-router
使用vue和vue-router构建单页应用会非常简单,添加vue-router和添加vuex的过程相似,都是在main.js中引入,在使用vue.use(vue-router),创建routes并挂载到根组件。vue-router每个路由映射一个组件,当路由匹配时加载相应的组件。目前自己用到的就是普通路由以及动态路由,嵌套路由只是了解但是没有使用
vue-source/axios
vue-resource是一个通过XMLHttpRequest或者JSONP技术实现异步加载服务端数据的插件,vue2.0以后,vue就不再对vue-resource进行更新,而是推荐axios
学习感想
学习vue之后,最大的感受就是几乎不需要手动去操作DOM元素了,只需要把元素和数据绑定起来,更新了数据后,vue就会自动更新DOM元素,比起在js中获取元素设置相关属性,方便了很多。而且vue的事件绑定都是在HTML中绑定,跟在JS中获取元素然后添加事件相比,代码的可读性提高很多,也有利于前端代码的封装。在使用vue写项目时,首先是搭建环境,这里可以使用vue-cli脚手架搭建项目,vue-cli提供了丰富的选项,可以帮我们搭建好项目框架,然后自己再引入需要的插件、配置工具,常常需要的就是vuex,vue-router以及axios和webpack,这些与vue结合使得构建vue项目更加容易。
网友评论