两个核心
-
-
组件化
渐进式框架,自底向上增量开发的设计理念
Declarative Rendering: 声明式渲染,说人话:模板引擎,通过某种方式把数据变成html页面
Componet System: 组件系统,对可复用性组件化模板的封装
Client-Side Routing :路由系统,根据不同的url渲染不同的html
Large Scale State Management: 状态管理,维护应用中的数据
Build System : 构建系统:对于不用的库等。。。
引入vue.js
<script src="./js/vue.js"> </script>
new Vue();
Vue2中组件类别
----根组件
----在一个Vue 的应用中,有且仅有一个根组件,类似于html标签
---- new Vue => 一个应用
----可复用组件
----一个应用根组件中就是由N个可不用的组件组合而成的
1 //组件在创建的时候,可以接收一个配置参数,Vue内部就会根据这个配置参数(对象)类处理组件内部的一些逻辑(数据拦截,绑定,模板渲染) 2 let app=new Vue({ 3 //用来存储该组件需要使用到的数据 4 data:{ 5 title:'欢迎大家' 6 }, 7 // template 8 template:` 9 <div id="app"> 10 <h1>hello world<,h1> 11 <p>{{title}}</p> 12 </div>`, 13 //模板渲染完成以后的DOM的挂载点 ,类似于 appendChild 14 el:'#app' 15 });
1 //app就是一个组件实例对象,该对象提供组件的许多属性和方法 2 // _开头:组件内部私有属性和方法(不要去调用) 3 // $开头:组件对外提供的公有属性和方法 4 // 其他:我们用户(定义组件创建组件的程序员们自定义的) 5 let app=new Vue({ 6 //用来存储该组件需要使用到的数据 7 data:{ 8 n:1 9 }, 10 // template 11 template:` 12 <div id="app"> 13 <h1>hello<,h1> 14 <p>{{n}}</p> 15 </div>`, 16 //模板渲染完成以后的DOM的挂载点 ,类似于 appendChild 17 el:'#app' 18 });
1 //如果选项中没有template,但是有el选项,那么Vue会把el元素的outHtml作为template 2 <div id="app"> 3 <h1>hello<,h1> 4 <p>{{n}}</p> 5 </div> 6 let app=new Vue({ 7 el:'#app', 8 //用来存储该组件需要使用到的数据 9 data:{ 10 n:1 11 } 12 13 }); 14 15 //如果没有el,那么这个时候就没有挂载点 16 let app=new Vue({ 17 //用来存储该组件需要使用到的数据 18 data:{ 19 n:1 20 }, 21 template:` 22 <div id="app"> 23 <h1>hello<,h1> 24 <p>{{n}}</p> 25 </div>`, 26 //模板渲染完成以后的DOM的挂载点 ,类似于 appendChild 27 el:'#app' 28 29 }); 30 console.log(app); 31 如果没有el,可以通过$mount('#app')来手动挂载
html字符串模板=>vNode
vNode :虚拟结点
Node: 真实结点,也是一个js对象
数据交换
后端有数据
前端也会要用后端提供的数据
1、后端的数据类型(数据结构定义)和前端(js)数据类型并不一致
2、数据在传输过程中会转成二进制(没有什么数据类型)
语言之间(平台之间、网络)需要通过不同的手段方式去交换数据到当前这门语言对 应的数据结构,我们可以为这种交换数据定义一个通用格式(json)
dom
文档对象模型
html是一门语言
javascript也是一门语言
js为了能够操作html这种结构,需要对html进行解析,解析成js方便操作的数据,把html解析成js中的对象,用 js中的对象去描述html中的没一个节点
node对象就和页面中对应的标签有一定的关联关系,当我们操作对象的时候,对象的变化会同步更新到页面结构 (浏览器)
真实的DOM node
每次render之后都会调用patch方法 ,比较虚拟dom和真实dom之间的差异
指令
v-for
基于源数据多次渲染元素或模块。
示例
1 <div v-for="item in items"> 2 {{ item.text }} 3 </div>
1 <div v-for="(item, index) in items"></div> 2 <div v-for="(val, key) in object"></div> 3 <div v-for="(val, name, index) in object"></div>
v-bind
动态绑定attribute
示例
1 <!-- 绑定一个 attribute --> 2 <img v-bind:src="imageSrc">
v-model
双向绑定。
示例
1 <input v-model="message" placeholder="edit me"> 2 <p>Message is: {{ message }}</p>
自定义指令
一个指令定义对象可以提供如下钩子函数
bind:只调用一次,指令第一次绑定到元素时调用
inserted:被绑定元素插入父节点时调用
update:所在组件的VNode更新时调用。
全局注册示例
1 ## 自定义指令 2 3 一个指令定义对象可以提供如下钩子函数 4 5 bind:只调用一次,指令第一次绑定到元素时调用 6 7 inserted:被绑定元素插入父节点时调用 8 9 update:所在组件的VNode更新时调用。 10 11 全局注册示例
局部注册示例
1 directives: { 2 focus: { 3 // 指令的定义 4 inserted: function (el) { 5 el.focus() 6 } 7 } 8 }
methods
Vue示例中的方法。可以直接通过VM示例访问这些方法。方中的this自动绑定为Vue实例。
示例
1 var vm = new Vue({ 2 data: { a: 1 }, 3 methods: { 4 plus: function () { 5 this.a++ 6 } 7 } 8 }) 9 vm.plus()
computed计算属性
派生数据,根据已经存在的数据生成一组新的数据。一个属性的变化依赖于其他属性的变化时可以用计算属性,计算属性只能用于同步方式,不支持异步。
示例
1 computed: { 2 allChecked:{ 3 get(){ 4 return this.cartItems.every(cartItem=>cartItem.checked); 5 }, 6 set(newValue){ 7 //方法一 8 // this.cartItems.forEach(cartItem=>{ 9 // cartItem.checked=newValue; 10 // }) 11 //方法二 12 this.cartItems=this.cartItems.map(cartItem=>({ 13 ...cartItem, 14 checked:newValue 15 })); 16 } 17 }, 18 totalCount:function(){ 19 return this.cartItems.filter(n=>n.checked===true).length; 20 }, 21 totalMoney:function(){ 22 let totalMoney=new Number(0); 23 let selectedItems=this.cartItems.filter(n=>n.checked===true); 24 selectedItems.forEach(item=>{ 25 totalMoney+=(item.price/100*item.quantity).toFixed(2)*1; 26 }); 27 return totalMoney; 28 } 29 30 }
1 watch: { 2 visible:function(newValue,oldValue){ 3 if(newValue==true){ 4 this.open(); 5 } 6 } 7 }
data
Vue实例的数据对象。Vue将会递归将data的property转换为getter/setter,从而让data的property能够响应数据变化。
在可复用组件中,data必须声明为一个返回初始数据对象的函数,因为组件可能被用来创造多个实例,避免所有实例共享一个数据对象
props
props用于接收来自父组件的数据。props可以是数组或者对象。对象允许进行类型检测、自定义验证,默认值。
示例:
1 Vue.component('kkb-child',{ 2 // props: ['a','b'], 3 props: { 4 val:Number 5 }, 6 data(){ 7 return { 8 n:1 9 } 10 }
模板与渲染
html编译为render函数的过程
优先级:
render()>template
ast
抽象语法树=>生成各种代码:js,html,java,php
可复用组件
全局注册
全局可复用组件的定义,通过Vue.compent()
示例:
1 let Child=Vue.component('kkb-child',{ 2 //data必须是一个函数,因为可复用组件会有很多份,如果直接设置成对象, 3 //则会共享 4 data(){ 5 return { 6 n:1 7 } 8 }, 9 template:`<div>Child</div>` 10 })
调用
1 <div id="app"> 2 <!-- =>createElement('h1') --> 3 <h1>可复用组件</h1> 4 <hr> 5 <!-- =>new componentOptions.Ctor().render(); --> 6 <kkb-child></kkb-child> 7 <kkb-child></kkb-child> 8 </div>
只能在当前注册的组件内使用(不能在其他:父级,子级)
组件生命周期
基本生命周期有以下几个阶段
-
创建阶段
beforeCreate():在实例初始化之后,数据观测(data observer)和事件配置之前被调用
created():在实例创建完城后被立即调用,解析模板之前,在这个阶段可以做一些与数据有关,与挂载无关的事情。
-
挂载阶段
beforeMount():在挂载开始之前被调用
mounted():完成了模板解析以及挂载。可以通过DOM操作来对组件内部元素进行处理了
-
更新阶段
beforeUpdate():数据更新前调用,但是还没有对视图进行重新渲染
updated():由于数据的变化导致的视图重新渲染,可以通过DOM操作来获取视图最新状态
-
卸载阶段
beforeDestroy():实例销毁之前,一般用来处理一些不必要的冗余数据,例如,定时器
destroyed():Vue实例销毁后调用