Vue.js 的核心是一个允许采用简洁的模板语法来声明式地将数据渲染进 DOM 的系统
核心思想是:数据驱动、组件系统。
var obj = {}; var demo = document.querySelector('#demo') var inp = document.querySelector('#inp') Object.defineProperty(obj, 'name', { get: function () { return val; }, set: function (newVal) { //当该属性被赋值的时候触发 inp.value = newVal; demo.innerHTML = newVal; } }) inp.addEventListener('input', function (e) { // 给obj的name属性赋值,进而触发该属性的set方法 obj.name = e.target.value; }); obj.name = 'fei'; //在给obj设置name属性的时候,触发了set这个方法
Object.defineProperty()
方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。
Object.defineProperty(obj, prop, descriptor)
obj
要在其上定义属性的对象。
prop
要定义或修改的属性的名称。
descriptor
将被定义或修改的属性描述符。
11个生命周期函数
beforecreated:el 和 data 并未初始化 -------------在实例初始化之后,数据观测 (data observer) 和 event/watcher 事件配置之前被调用。
created:完成了 data 数据的初始化,el没有 -----------在实例创建完成后被立即调用。在这一步,实例已完成以下的配置:数据观测 (data observer),属性和方法的运算,watch/event 事件回调。然而,挂载阶段还没开始,$el 属性目前不可见。
beforeMount:完成了 el 和 data 初始化 --------在挂载开始之前被调用:相关的 render 函数首次被调用。该钩子在服务器端渲染期间不被调用。
mounted :完成挂载--------el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子。如果 root 实例挂载了一个文档内元素,当 mounted 被调用时 vm.$el 也在文档内。注意 mounted 不会承诺所有的子组件也都一起被挂载。如果你希望等到整个视图都渲染完毕,可以用 vm.$nextTick 替换掉 mounted:
mounted: function () {
this.$nextTick(function () {
// Code that will run only after the
// entire view has been rendered
})
}
该钩子在服务器端渲染期间不被调用。
beforeUpdate:数据更新时调用,发生在虚拟 DOM 打补丁之前。这里适合在更新之前访问现有的 DOM,比如手动移除已添加的事件监听器。该钩子在服务器端渲染期间不被调用,因为只有初次渲染会在服务端进行。
updated:由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。然而在大多数情况下,你应该避免在此期间更改状态。如果要相应状态改变,通常最好使用计算属性或 watcher 取而代之。注意 updated 不会承诺所有的子组件也都一起被重绘。如果你希望等到整个视图都重绘完毕,可以用 vm.$nextTick 替换掉 updated:
updated: function () {
this.$nextTick(function () {
// Code that will run only after the
// entire view has been re-rendered
})
}
该钩子在服务器端渲染期间不被调用。
activated:keep-alive 组件激活时调用。该钩子在服务器端渲染期间不被调用。
deactivated:keep-alive 组件停用时调用。该钩子在服务器端渲染期间不被调用。
beforeDestroy:实例销毁之前调用。在这一步,实例仍然完全可用。该钩子在服务器端渲染期间不被调用。
destroyed:Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。该钩子在服务器端渲染期间不被调用。
errorCaptured:2.50版本新增 当捕获一个来自子孙组件的错误时被调用。此钩子会收到三个参数: 错误对象、发生错误的组件实例以及一个包含错误来源信息的字符串。此钩子可以返回 false 以阻止该错误继续向上传播。
vue-cli 主要目录结构:
index.html:一般只定义一个空的根节点,在main.js里面定义的实例将挂载在#app节点下,内容通过vue组件填充。
src/ App.vue:是项目主组件,也是项目所有组件和路由的出口,之后它会被渲染到项目根目录的 index.html 中显示出来,我们可以在这里写一些适合全局的css样式。
src/ main.js:入口文件,引入了vue模块和app.vue组件以及路由router,我们需要在全局使用的一些东西也可以定义在这里面。
src/router index.js:路由配置文件。
指令:
v-bind 属性的绑定 简写 " : "
v-if 控制一个元素是否显示(会对DOM进行创建和删除操作 有较高的切换性能消耗)
v-show 控制一个元素是否显示(切换了元素的display:none/block;样式,有较高的初始渲染消耗)
v-for 数据循环
v-on 事件绑定 简写 " @ "
v-model 数据的双向绑定
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>计算器</title> <script src="https://cdn.jsdelivr.net/npm/vue"></script> </head> <body> <div id="app"> <input type="text" v-model="first" /> <select v-model="opt"> <option value="+">+</option> <option value="-">-</option> <option value="*">*</option> <option value="/">/</option> </select> <input type="text" v-model="last" /> <input type="button" value="=" @click="add"/> <input type="text" v-model="result" /> </div> </body> </html> <script type="text/javascript"> var Vue = new Vue({ el:"#app", data:{ first:0, last:0, result:0, opt:"+" }, methods:{ add(){ var jieguo = "parseInt(this.first)"+ this.opt + "parseInt(this.last)"; this.result= eval(jieguo); } } }) </script>
v-cloak 使用v-cloak 能够解决插值表达式闪烁的问题
[v-cloak] { display:none;}
v-on @ 事件修饰符:
.stop:等同于JavaScript中的event.stopPropagation(),防止事件冒泡
.prevent:等同于JavaScript中的event.preventDefault(),防止执行预设的行为(如果事件可取消,则取消该事件,而不停止事件的进一步传播)
.capture:与事件冒泡的方向相反,事件捕获由外到内
.self:只会触发自己范围内的事件,不包含子元素
.once:只会触发一次
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>vue跑马灯</title> <script src="https://cdn.jsdelivr.net/npm/vue"></script> </head> <body> <div id="app"> <input type="button" value="爱" @click="love"/> <input type="button" value="不爱" @click="anlove" /> <h4>{{msg}}</h4> </div> </body> </html> <script type="text/javascript"> var Vue = new Vue({ el:"#app", data:{ msg:"爱你一万年!!!", setId:null }, methods:{ love(){ if(this.setId != null){ return false; } this.setId = setInterval(() => { var str = this.msg.substring(0,1); var str2 = this.msg.substring(1); this.msg = str2 + str; }, 200) }, anlove(){ clearInterval(this.setId); this.setId = null; } } }) </script>
v-for:如果用v-for迭代数字的话,前面的count值从1开始
<p v-for = "count in 10">这是第{{ count }} 次循环</p>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>添加删除</title> <script src="https://cdn.jsdelivr.net/npm/vue"></script> <style type="text/css"> *{padding:0;margin:0;border:0;-webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box;} .add{padding:50px;} .add input{100px;border:1px #eee solid;height:40px;line-height:40px;text-align: center;} .biao{500px;margin-left:50px;} .biao ul li{overflow: hidden;border:1px #eee solid;line-height: 40px;} .biao ul li+li{border-top:none;} .biao ul li span{float: left;33.33%;text-align: center;cursor:pointer;} .biao ul li span+span{border-left:1px #eee solid;} </style> </head> <body> <div id="app"> <div class="add"> <input type="text" v-model="id"/> <input type="text" v-model="name"/> <input type="button" value="添加" @click="add"/> </div> <div class="biao"> <ul> <li v-for="item in list" :key="item.id"> <span>{{item.id}}</span> <span>{{item.name}}</span> <span @click="del(item.id)">删除</span> </li> </ul> </div> </div> </body> </html> <script type="text/javascript"> var Vue = new Vue({ el:"#app", data:{ id:"", name:"", list:[ {id: 1, name: '天籁' }, {id: 2, name: '雅阁' }, {id: 3, name: '帕萨特'} ] }, methods:{ add(){ var arr = {id:this.id,name:this.name} this.list.push(arr); }, del(id){ // console.log("aa"); this.list.some((item,i)=>{ if(item.id == id){ this.list.splice(i,1); } return true; }) } } }) </script>
组件化实例
<div id="app">
<app-nav></app-nav>
<app-view>
<app-sidebar></app-sidebar>
<app-content></app-content>
</app-view>
</div>
在子组件中定义data ,data必须是个函数而不能是个对象
data:function(){
return {
content: "xiaozhong"
}
}
在vue中我们可以通过ref="zjz"获取DOM节点 this.$refs.zjz. ,进而来操作DOM
vue中单向数据流概念:子组件中只能使用父组件中传过来的值,而不能更改,如需更改需克隆一份修改父组件通过属性的方式向子组件传值,子组件通过事件触发的方式向父组件传值
vue组件的属性使用和不使用冒号的区别:加冒号的,说明后面的是一个变量或者表达式;没加冒号的后面就是对应的字符串字面量!
非父子组件间的传值:{
1.vuex
2.发布订阅模式---总线机制---Bus---观察者模式 not_father_son.html
}
插槽(slot):具名插槽,作用域插槽
使用animate.css :只要在需要动画的标签外的transition标签里添加对应属性,比如enter-active-class=“animated swing”,leave-active-class=“animated shake”即可
js动画效果:注意事件函数中所传递的参数及某些事件函数返回的函数
1. 进入动画钩子:before-enter; enter; after-enter
2. 离开动画钩子:before-leave; leave; after-leave
3. 在enter钩子中的函数调用done()告诉VUE js动画完成
4. 使用velocity.js动画库实现动画:Velocity(el,{样式属性},{duration:1000,complete:done})
5. 中文文档:http://www.mrfront.com/docs/velocity.js/index.html