首先是Vue的官网:https://cn.vuejs.org/
查看官方文档是学习Vue框架的非常必要的环节之一
Vue是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。
Vue和angular、react并列为三大主流框架,而和后两者想对比,Vue更为轻量,并且最易上手。
Vue是一种MVVM开发模式的框架,相比于以前MVP模式的开发,它可以使我们只需要关注数据的操作即可,而不是使用大量的js去操作dom,大大的简化了代码,加快了项目的开发速度,并且代码易于管理。
在使用Vue时,可以从网上下载vue.js,引入到项目中去,像引入jQuery一样,也可以使用vue-cli来建立vue项目,针对初学者,推荐第一种方法。
建立Vue项目(自然是hello world):
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title> hello world </title> <script src="./vue.js" type="text/javascript"> </script> </meta> </head> <body>
<div id="app">
{{content}}
</div>
<script type="text/javascript">
var app=new Vue({
el:'#app',
data:{ content:"hello world" }
})
</script>
</body>
</html>
v-是vue的指令:
v-model可以实现vue的数据双向绑定;
v-on绑定事件
使用v-on为button绑定一个alertMessage的事件,在vue的methods中写一个alertMessage的function,这时点击button就会弹窗显示message的数据内容
v-on可以简写为@,v-bind可以简写为: ;
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title> TodoList </title> <script src="./vue.js" type="text/javascript"> </script> </meta> </head> <body> <div id="app"> <input type="text" v-model="inputValue"/> <button v-on:click="handleBtnClick"> submit </button> <ul> <li v-for="item in list"> {{item}} </li> </ul> </div> </body> <script type="text/javascript"> var app=new Vue({ el:"#app", data:{ list:['todo','doing','done'], inputValue:'' }, methods:{ handleBtnClick:function() { if(this.inputValue!=""){ this.list.push(this.inputValue); this.inputValue=''; } } } }) </script> </html>
组件:
组件系统是 Vue 的另一个重要概念,因为它是一种抽象,允许我们使用小型、独立和通常可复用的组件构建大型应用。一个应用、一个界面可以分化成一个个的小的组件。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title> TodoList </title> <script src="./vue.js" type="text/javascript"> </script> </meta> </head> <body> <div id="app"> <input type="text" v-model="inputValue"/> <button @click="handleBtnClick"> submit </button> <ul> <todo-item @delete="handleItemDelete" :content="item" :index="index" v-for="(item,index) in list"> </todo-item> </ul> </div> </body> <script type="text/javascript"> //全局组件 // Vue.component("TodoItem",{ // props:['content'], // template:"<li>{{content}}</li>" // }) // 局部组件 var TodoItem={ props:['content','index'], template:"<li @click='handleItemClick'>{{content}}</li>", methods:{ handleItemClick:function(){ this.$emit("delete",this.index); } } } var app=new Vue({ el:"#app", components:{ TodoItem:TodoItem }, data:{ list:[], inputValue:'' }, methods:{ handleBtnClick:function() { if(this.inputValue!=""){ this.list.push(this.inputValue); this.inputValue=''; } else{ alert("请输入"); } }, handleItemDelete:function(index){ this.list.splice(index,1); } } }) </script> </html>
Vue的组件可以分为全局组件和局部组件,全局组件不需要再次声明,而局部组件需要去components中声明一下;
组件命名推荐使用驼峰式例如TodoItem,但是在使用时要变成todo-item;
可以使用v-bind从父组件向子组件传值,使用this.$emit()从子组件向父组件传值;
写一个组件,首先在组件中定义一个自定义属性props接口,为组件的提供content、index变量,先将list的内容赋值给item,在子组件中显示content内容并且将index标号赋值,
并且为生成的li中添加一个事件handleItemClick,在子组件中编写此事件的方法,每当点击时执行 this.$emit("delete",this.index);将index传递到父组件,并执行
父组件的handleItemDelete事件,然后删除对应标号的内容;
除了数据属性,Vue 实例还暴露了一些有用的实例属性与方法。它们都有前缀 $
,以便与用户定义的属性区分开来。例如:vm.$data === data // => true
vm.$el === document.getElementById('example') // => true
$watch 是一个实例方法
vm.$watch('a', function (newValue, oldValue) {
// 这个回调将在 `vm.a` 改变后调用
})
v-for是循环遍历指令;
生命周期的钩子(需要在实际开发中注意)
比如 created
钩子可以用来在一个实例被创建之后执行代码,也有一些其它的钩子,在实例生命周期的不同阶段被调用,
如 mounted
、updated 和 destroyed
。生命周期钩子的 this
上下文指向调用它的 Vue 实例。
不要在选项属性或回调上使用箭头函数,比如 created: () => console.log(this.a)
或 vm.$watch('a', newValue => this.myMethod())
。
因为箭头函数是和父级上下文绑定在一起的,this
不会是如你所预期的 Vue 实例,
经常导致 Uncaught TypeError: Cannot read property of undefined
或 Uncaught TypeError: this.myMethod is not a function
之类的错误。
通过使用 v-once指令,你也能执行一次性地插值,当数据改变时,插值处的内容不会更新;
{{}}的方式赋值会将内容默认为文本,而如果需要的内容是HTML的话就需要v-html了;比如:content的值为<span style="color:red">this is should red.</span>
<p>Using mustaches: {{ content }}</p> 显示<span style="color:red">this is should red.</span>
<p>Using v-html directive: <span v-html="content"></span></p>显示this is should red.
计算属性
<div id="example">
<p>Original message: "{{ message }}"</p>
<p>Computed reversed message: "{{ reversedMessage }}"</p>
</div>
var vm = new Vue({
el: '#example',
data: {
message: 'Hello'
},
computed: {
// 计算属性的 getter
reversedMessage: function () {
// `this` 指向 vm 实例
return this.message.split('').reverse().join('')
}
}
})
方法:
<p>Reversed message: "{{ reversedMessage() }}"</p>
// 在组件中
methods: {
reversedMessage: function () {
return this.message.split('').reverse().join('')
}
}
方法会在执行行刷新数值,而计算属性只有在它依赖的属性改变时才可以改变,计算属性只在相关依赖发生改变时它们才会重新求值。
这就意味着只要 message
还没有发生改变,多次访问 reversedMessage
计算属性会立即返回之前的计算结果,而不必再次执行函数。
这会大大的加快运行速度。但是
computed: {
now: function () {
return Date.now()
}
}
这也同样意味着下面的计算属性将不再更新,因为 Date.now()
不是响应式依赖:
计算属性和侦听属性
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title> TodoList </title> <script src="./vue.js" type="text/javascript"> </script> </meta> </head> <body> <div id="demo"> {{ fullName }} </div> </body> <script type="text/javascript"> var vm = new Vue({ el: '#demo', data: { firstName: 'Foo', lastName: 'Bar', fullName: 'Foo Bar' }, watch: { firstName: function (val) { this.fullName = val + ' ' + this.lastName }, lastName: function (val) { this.fullName = this.firstName + ' ' + val } } }) </script> </html>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title> TodoList </title> <script src="./vue.js" type="text/javascript"> </script> </meta> </head> <body> <div id="demo"> {{ fullName }} </div> </body> <script type="text/javascript"> var vm = new Vue({ el: '#demo', data: { firstName: 'Foo', lastName: 'Bar' }, computed: { fullName: { // getter get: function () { return this.firstName + ' ' + this.lastName }, // setter set: function (newValue) { var names = newValue.split(' ') this.firstName = names[0] this.lastName = names[names.length - 1] } } } }) </script> </html>
可以看到计算属性好多了;
虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的侦听器。这就是为什么 Vue 通过 watch
选项提供了一个更通用的方法,来响应数据的变化。
当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。