这篇Vue学习笔记参考于Vue.js参考文档。仅供个人学习和复习用。
Vue.js介绍
- Vue.js是一套构建用户界面的渐进式框架。
- Vue只关注视图层,采用自底向上增量开发的设计。
- Vue的目标是通过尽可能简单的API实现响应的数据绑定和组合的视图组件。
生命周期
来源前端_周瑾的Vue-生命周期详解。
Vue实例有一个完整的生命周期,也就是说从开始创建、初始化数据、编译模板、挂载DOM、渲染-更新-渲染、卸载等一系列过程,统称为Vue实例的生命周期,钩子
就是在生命周期的某个阶段给你一个做某些操作的机会。
beforeCreate(创建前)
在实例初始化之后,数据观测和事件配置之前被调用,此时组件的选项还未创建,el和data并未初始化,因此无法访问methods、data、computed等的方法和数据。
created(创建后)
实例已经创建完成之后被调用,在这一步,实例已经完成以下配置:数据观测、属性和方法的运算,watch/event事件回调,完成了data数据的初始化,el没有。然而挂载阶段还没有开始,$el属性目前不可见,这是一个常用的生命周期,应为你可以调用methods中的方法,改变data中的数据,并且修改可以通过vue的响应式绑定体现在页面上,获取computed中的计算属性等等,通常我们可以在这里对实例进行预处理,也有一些人喜欢在这里发ajax请求,值得注意的是,这个周期中是没有什么方法来对实例化过程进行拦截的,因此假如有某些数据必须获取才允许进入页面的话,并不合适在这个方法发请求,建议在组件路由钩子beforeRouteEnter中完成。
beforeMount
挂载开始之前被调用,相关的render函数首次被调用(虚拟DOM),实例已完成以下的配置:编译模板,把data里面的数据和模板生成html,完成了el和data初始化,注意此时还没有挂载html到页面上。
mounted
挂载完成,也就是模板中的HTML渲染到HTML页面中,此时一般可以做一些ajax操作,mounted只会执行一次。
beforeUpdate
在数据更新之前被调用,发生在虚拟DOM重新渲染和打补丁之前,可以在钩子中进一步地更改状态,不会触发附加的重渲染过程。
updated(更新后)
在由于数据更改导致的虚拟DOM重新渲染和打补丁时调用,调用时,组件DOM已经更新,所以可以执行依赖于DOM的操作,然后在大多数情况下,应该避免在此期间更改状态,因为这会导致更新无限循环,该钩子在服务器端渲染期间不被调用。
beforeDeestroy(销毁前)
在实例销毁之前调用,实例任然完全可用,
- 这一步还可以用this来获取实例
- 一般在这一步做一些重置的操作,比如清除掉组件中的定时器和监听的DOM事件\
destroyed(销毁后)
在实例销毁之后调用,调用后,所有的事件监听器会被移出,所有的子实例也会被销毁,该钩子在服务器端渲染期间不被调用。
引用
在.html文件中通过如下方式引用
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
v-bind
v-bind会在渲染的DOM上应用特殊的响应式行为,v-bind:title=”message”表示将这个元素节点的title属性和Vue实例的message的值保持一致。
<div id="app">
<p>{{message}}</p>
<span v-bind:title="message">
鼠标悬停这里查看动态绑定的提示信息!~~~
</span>
</div>
<script>
var vm = new Vue({
el:'#app',
data: {
message:'hello,Vue的世界开始于'+ new Date().toLocaleString()
}
})
</script>
条件与循环
v-if
v-if会根据属性传来的true或false来判断执行。
<div id="app2">
<p v-if="aa">我现在aa的值是true</p>
<p v-else>我现在aa的值是false</p>
</div>
<script>
var vm2 = new Vue({
el:"#app2",
data: {
aa: true
}
})
</script>
v-for
<div id="app3">
<ol>
<li v-for="todo in todos">
{{todo.text}}
</li>
</ol>
</div>
<script>
var vm3 = new Vue({
el:'#app3',
data:{
todos:[
{text:"学习java"},
{text:"学习Vue"},
{text:"学习MySql"}
]
}
})
</script>
v-for指令可以绑定数组的数据来渲染一个项目列表。
v-for=”todo in todos”表示遍历出todos中的每一个todo对象。
v-on
v-on指令可以添加一个事件监听器。
<div id="app4">
<p>{{message}}</p>
<button v-on:click="reverseMessage">反转消息</button>
</div>
<script>
var vm4 = new Vue({
el: '#app4',
data: {
message: "hello,Vue!"
},
methods: {
reverseMessage: function () {
this.message = this.message.split('').reverse().join('')
}
}
})
</script>
v-model
v-model能实现表单输入和应用状态之间的双向绑定。
<div id="app5">
<p>{{message}}</p>
<input type="text" v-model="message">
</div>
<script>
var vm5 = new Vue({
el:'#app5',
data:{
message: "hello,Vue大神!"
}
})
</script>
可以观察到当前端页面的的input标签中输入内容 message也会随之改变。
计算属性 reversedMessage
调用方法时,每次都需要进行计算,既然有计算过程则必定产生系统开销,如果结果不经常变化,此时可以考虑将这个结果缓存起来,采用计算属性可以很方便的做到这一点,计算属性的主要特性就是为了将不经常变化的计算结果进行缓存,以节约我们的系统开销。
<div id="app6">
<p>{{message}}{{currentTime1()}}</p>
<p>{{message}}{{currentTime2}}</p>
</div>
<script>
var vm6 = new Vue({
el:'#app6',
data:{
message:"当前时间戳为:"
},
methods: {
currentTime1:function () {
return Date.now();//返回一个时间戳
}
},
computed:{//计算属性 : methods,computed 方法名最好不要重名,否则只会调用methods中的同名方法。
currentTime2:function () {
this.message;
return Date.now();//返回一个时间戳
}
}
})
</script>
计算属性是基于它们的响应式依赖进行缓存的。只在相关响应式依赖发生改变时它们才会重新求值。这就意味着只要 message 还没有发生改变,多次访问 reversedMessage 计算属性会立即返回之前的计算结果,而不必再次执行函数。
我们可以使用 methods 来替代 computed,效果上两个都是一样的,但是 computed 是基于它的依赖缓存,只有相关依赖发生改变时才会重新取值。而使用 methods ,在重新渲染的时候,函数总会重新调用执行。可以说使用 computed 性能会更好,但是如果你不希望缓存,你可以使用 methods 属性。
组件
全局组件 Vue.component
<div id="app7">
<button-counter></button-counter>
<button-counter></button-counter>
<button-counter></button-counter>
</div>
<script>
//全局组件
//定义一个名为button-counter的组件
Vue.component("button-counter",{
data:function () {
return{
count:0
}
},
template:'<button v-on:click="count++">你点击了{{count}}次 </button>'
})
//注意需要在Vue实例化之前注册组件否则无法使用
new Vue({
el:'#app7'
})
</script>
注意这里踩过个坑,组件的注册需要在Vue实例化之前,否则Vue的实例无法使用组件中的template元素。
组件可以复用
在上述例子中,当点击按钮时,每个组件都会各自独立维护它的count。因为你每用一次组件,就会有一个它的新实例被创建。
data必须是个函数
当我们定义这个<button-counter>组件时,你可能会发现它的data并不是像这样直接提供一个对象:
data: {
count: 0
}
取而代之的是,一个组件的data选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝:
data: function () {
return {
count: 0
}
}
如果Vue没有这条规则,点击一个按钮其他复用实例就会受到一样的影响。
Prop
prop是子组件用来接受父组件传递过来的数据的一个自定义属性。父组件的数据需要通过props把数据传给子组件,子组件需要显式地使用props选项声明”prop”。
<div id="app0">
<input type="text" v-model="Parentmessage">
<show v-bind:message="Parentmessage"></show><!--将父组件中的Parentmessage的值绑定传递给子组件props中的message中-->
</div>
<script>
Vue.component('show',{
props:['message'],
template:'<p>输入信息:{{message}}</p>'
})
var vm0 = new Vue({
el:"#app0",
data:{
Parentmessage:''
}
})
</script>
用 v-bind 绑定 HTML 特性到一个表达式,也可以用 v-bind 动态绑定 props 的值到父组件的数据中。每当父组件的数据变化时,该变化也会传导给子组件:
局部组件
<div id="app8">
<title-component></title-component>
</div>
<script>
//局部组件
var vm8 = new Vue({//创建根实例
el:'#app8',
components:{
'title-component':{//<title-component>只能在父模板可用
template: '<h1>这是局部组件</h1>'
}
}
})
</script>