1). 引入vue.js 2). 建立Vue实例对象(vm), 指定选项(配置)对象 el : 指定dom标签容器的选择器 data : 指定初始化状态数据的对象/函数(返回一个对象) 3). 在页面模板中使用{{}}或vue指令
el元素选择 element 指定dom标签容器的选择器 Vue就会管理对应的标签及其子标签
对象或函数类型 指定初始化状态属性数据的对象 vm也会自动拥有data中全部属性 页面中能够直接访问使用 数据代理: 由vm对象来代理对data中全部属性的操做(读/写)
包含多个方法的对象 供页面中的事件指令来绑定回调 回调函数默认有event参数, 但也能够指定本身的参数 全部的方法由vue对象来调用, 访问data中的属性直接使用this.xxx
包含多个方法的对象 对状态属性进行计算返回一个新的数据, 供页面获取显示 通常状况下是至关因而一个只读的属性 利用set/get方法来实现属性数据的计算读取, 同时监视属性数据的变化 如何给对象定义get/set属性 在建立对象时指定: get name () {return xxx} / set name (value) {} 对象建立以后指定: Object.defineProperty(obj, age, {get(){}, set(value){}})
包含多个属性监视的对象 分为通常监视和深度监视 'xxx' : { deep : true, handler : fun(value) } 另外一种添加监视方式: vm.$watch('xxx', funn)
利用vue去操控css的transition/animation动画 模板: 使用<transition name='xxx'>包含带动画的标签 css样式 .fade-enter-active: 进入过程, 指定进入的transition .fade-leave-active: 离开过程, 指定离开的transition .xxx-enter, .xxx-leave-to: 指定隐藏的样式 编码例子 .xxx-enter-active, .xxx-leave-active { transition: opacity .5s } .xxx-enter, .xxx-leave-to { opacity: 0 } <transition name="xxx"> <p v-if="show">hello</p> </transition>
vm/组件对象 生命周期图 主要的生命周期函数(钩子) created() / mounted(): 启动异步任务(启动定时器,发送ajax请求, 绑定监听) beforeDestroy(): 作一些收尾的工做
对须要显示的数据进行格式化后再显示
1). 定义过滤器 Vue.filter(filterName, function(value[,arg1,arg2,...]){ // 进行必定的数据处理 return newValue }) 2). 使用过滤器 <div>{{myData | filterName}}</div> <div>{{myData | filterName(arg)}}</div>
v-text/v-html: 指定标签体 * v-text : 看成纯文本 * v-html : 将value做为html标签来解析 v-if v-else v-show: 显示/隐藏元素 * v-if : 若是vlaue为true, 当前标签会输出在页面中 * v-else : 与v-if一块儿使用, 若是value为false, 将当前标签输出到页面中 * v-show: 就会在标签中添加display样式, 若是vlaue为true, display=block, 不然是none v-for : 遍历 * 遍历数组 : v-for="(person, index) in persons" * 遍历对象 : v-for="value in person" $key v-on : 绑定事件监听 * v-on:事件名, 能够缩写为: @事件名 * 监视具体的按键: @keyup.keyCode @keyup.enter * 中止事件的冒泡和阻止事件默认行为: @click.stop @click.prevent * 隐含对象: $event v-bind : 强制绑定解析表达式 * html标签属性是不支持表达式的, 就可使用v-bind * 能够缩写为: :id='name' * :class * :class="a" * :class="{classA : isA, classB : isB}" * :class="[classA, classB]" * :style :style="{color : color}" v-model * 双向数据绑定 * 自动收集用户输入数据 ref : 标识某个标签 * ref='xxx' * 读取获得标签对象: this.$refs.xxx
Vue.directive('my-directive', function(el, binding){ el.innerHTML = binding.value.toUpperCase() })
directives : { 'my-directive' : function(el, binding) { el.innerHTML = binding.value.toUpperCase() } }
<div v-my-directive='xxx'>
用来建立vue项目的工具包 建立项目: npm install -g vue-cli vue init webpack VueDemo 开发环境运行: cd VueDemo npm install npm run dev 生产环境打包发布 npm run build npm install -g serve serve dist http://localhost:5000
用来作项目编码规范检查的工具 基本原理: 定义了不少规则, 检查项目的代码一旦发现违背了某个规则就输出相应的提示信息 有相应的配置, 可定制检查
vue文件包含3个部分 <template> <div></div> </template> <script> export default { props: []/{} data(){}, computed: {} methods: {}, watch: {} filters: {} directives: {} components: {} } </script> <style> </style> 组件化编码的基本流程 1). 拆分界面, 抽取组件 2). 编写静态组件 3). 编写动态组件 初始化数据, 动态显示初始化界面 实现与用户交互功能 组件通讯的5种方式 props vue的自定义事件 pubsub第三方库 slot vuex(后面单独讲) props: 父子组件间通讯的基本方式 属性值的2大类型: 通常: 父组件-->子组件 函数: 子组件-->父组件 隔层组件间传递: 必须逐层传递(麻烦) 兄弟组件间: 必须借助父组件(麻烦) vue自定义事件 子组件与父组件的通讯方式 用来取代function props 不适合隔层组件和兄弟组件间的通讯 pubsub第三方库(消息订阅与发布) 适合于任何关系的组件间通讯 slot 通讯是带数据的标签 注意: 标签是在父组件中解析 vuex 多组件共享状态(数据的管理) 组件间的关系也没有限制 功能比pubsub强大, 更适用于vue项目
相关库: vue-resource: vue插件, 多用于vue1.x axios: 第三方库, 多用于vue2.x vue-resource使用 // 引入模块 import VueResource from 'vue-resource' // 使用插件 Vue.use(VueResource) // 经过vue/组件对象发送ajax请求 this.$http.get('/someUrl').then((response) => { // success callback console.log(response.data) //返回结果数据 }, (response) => { // error callback console.log(response.statusText) //错误信息 }) axios使用 // 引入模块 import axios from 'axios' // 发送ajax请求 axios.get(url) .then(response => { console.log(response.data) // 获得返回结果数据 }) .catch(error => { console.log(error.message) })
vue用来实现SPA的插件 使用vue-router 1. 建立路由器: router/index.js new VueRouter({ routes: [ { // 通常路由 path: '/about', component: about }, { // 自动跳转路由 path: '/', redirect: '/about' } ] }) 2. 注册路由器: main.js import router from './router' new Vue({ router }) 3. 使用路由组件标签: <router-link to="/xxx">Go to XXX</router-link> <router-view></router-view> 编写路由的3步 1. 定义路由组件 2. 映射路由 3. 编写路由2个标签 嵌套路由 children: [ { path: '/home/news', component: news }, { path: 'message', component: message } ] 向路由组件传递数据 params: <router-link to="/home/news/abc/123"> props: <router-view msg='abc'> 缓存路由组件 <keep-alive> <router-view></router-view> </keep-alive> 路由的编程式导航 this.$router.push(path): 至关于点击路由连接(能够返回到当前路由界面) this.$router.replace(path): 用新路由替换当前路由(不能够返回到当前路由界面) this.$router.back(): 请求(返回)上一个记录路由
github站点: https://github.com/vuejs/vuex 在线文档: https://vuex.vuejs.org/zh-cn/ 简单来讲: 对应用中组件的状态进行集中式的管理(读/写)
state: 驱动应用的数据源 view: 以声明方式将state映射到视图 actions: 响应在view上的用户输入致使的状态变化(包含n个更新状态的方法)
[外链图片转存失败(img-7zYqBi3G-1566803111088)(https://vuex.vuejs.org/zh-cn/images/flow.png)]css
多个视图依赖于同一状态 来自不一样视图的行为须要变动同一状态 之前的解决办法 * 将数据以及操做数据的行为都定义在父组件 * 将数据以及操做数据的行为传递给须要的各个子组件(有可能须要多级传递) vuex就是用来解决这个问题的
[外链图片转存失败(img-PD3yiIQB-1566803111091)(https://vuex.vuejs.org/zh-cn/images/vuex.png)]html
vuex管理的状态对象 它应该是惟一的 const state = { xxx: initValue }
包含多个直接更新state的方法(回调函数)的对象 谁来触发: action中的commit('mutation名称') 只能包含同步的代码, 不能写异步代码 const mutations = { yyy (state, data) { // 更新state的某个属性 } }
包含多个事件回调函数的对象 经过执行: commit()来触发mutation的调用, 间接更新state 谁来触发: 组件中: $store.dispatch('action名称') // 'zzz' 能够包含异步代码(定时器, ajax) const actions = { zzz ({commit, state}, data1) { commit('yyy', data2) } }
包含多个计算属性(get)的对象 谁来读取: 组件中: $store.getters.xxx const getters = { mmm (state) { return ... } }
包含多个module 一个module是一个store的配置对象 与一个组件(包含有共享数据)对应
export default new Vuex.Store({ state, mutations, actions, getters })
import {mapGetters, mapActions} from 'vuex' export default { computed: mapGetters(['mmm']) methods: mapActions(['zzz']) } {{mmm}} @click="zzz(data)"
import store from './store' new Vue({ store })
1.全部用vuex管理的组件中都多了一个属性$store, 它就是一个store对象 2.属性: state: 注册的state对象 getters: 注册的getters对象 3.方法: dispatch(actionName, data): 分发action
1.store.js import Vuex from 'vuex' export default new Vuex.Store({ state, mutations, actions, getters, modules }) 2.main.js import store from './store.js' new Vue({ store })
1.[].slice.call(lis): 将伪数组转换为真数组 2.node.nodeType: 获得节点类型 3.Object.defineProperty(obj, propertyName, {}): 给对象添加/修改属性(指定描述符) configurable: true/false 是否能够从新define enumerable: true/false 是否能够枚举(for..in / keys()) value: 指定初始值 writable: true/false value是否能够修改存取(访问)描述符 get: 函数, 用来获得当前属性值 set: 函数, 用来监视当前属性值的变化 4.Object.keys(obj): 获得对象自身可枚举的属性名的数组 5.DocumentFragment: 文档碎片(高效批量更新多个节点) 6.obj.hasOwnProperty(prop): 判断prop是不是obj自身的属性
1.经过一个对象代理对另外一个对象中属性的操做(读/写) 2.经过vm对象来代理data对象中全部属性的操做 3.好处: 更方便的操做data中的数据 4.基本实现流程 1). 经过Object.defineProperty()给vm添加与data对象的属性对应的属性描述符 2). 全部添加的属性都包含getter/setter 3). 在getter/setter内部去操做data中对应的属性数据
1.模板解析的关键对象: compile对象 2.模板解析的基本流程: 1). 将el的全部子节点取出, 添加到一个新建的文档fragment对象中 2). 对fragment中的全部层次子节点递归进行编译解析处理 * 对表达式文本节点进行解析 * 对元素节点的指令属性进行解析 * 事件指令解析 * 通常指令解析 3). 将解析后的fragment添加到el中显示 3.解析表达式文本节点: textNode.textContent = value 1). 根据正则对象获得匹配出的表达式字符串: 子匹配/RegExp.$1 2). 从data中取出表达式对应的属性值 3). 将属性值设置为文本节点的textContent 4.事件指令解析: elementNode.addEventListener(事件名, 回调函数.bind(vm)) v-on:click="test" 1). 从指令名中取出事件名 2). 根据指令的值(表达式)从methods中获得对应的事件处理函数对象 3). 给当前元素节点绑定指定事件名和回调函数的dom事件监听 4). 指令解析完后, 移除此指令属性 5.通常指令解析: elementNode.xxx = value 1). 获得指令名和指令值(表达式) 2). 从data中根据表达式获得对应的值 3). 根据指令名肯定须要操做元素节点的什么属性 * v-text---textContent属性 * v-html---innerHTML属性 * v-class--className属性 4). 将获得的表达式的值设置到对应的属性上 5). 移除元素的指令属性
1.数据绑定(model==>View): 1). 一旦更新了data中的某个属性数据, 全部界面上直接使用或间接使用了此属性的节点都会更新(更新) 2.数据劫持 1). 数据劫持是vue中用来实现数据绑定的一种技术 2). 基本思想: 经过defineProperty()来监视data中全部属性(任意层次)数据的变化, 一旦变化就去更新界面 3.四个重要对象 1). Observer * 用来对data全部属性数据进行劫持的构造函数 * 给data中全部属性从新定义属性描述(get/set) * 为data中的每一个属性建立对应的dep对象 2). Dep(Depend) * data中的每一个属性(全部层次)都对应一个dep对象 * 建立的时机: * 在初始化define data中各个属性时建立对应的dep对象 * 在data中的某个属性值被设置为新的对象时 * 对象的结构 { id, // 每一个dep都有一个惟一的id subs //包含n个对应watcher的数组(subscribes的简写) } * subs属性说明 * 当一个watcher被建立时, 内部会将当前watcher对象添加到对应的dep对象的subs中 * 当此data属性的值发生改变时, 全部subs中的watcher都会收到更新的通知, 从而最终更新对应的界面 3). Compile * 用来解析模板页面的对象的构造函数(一个实例) * 利用compile对象解析模板页面 * 每解析一个表达式(非事件指令)都会建立一个对应的watcher对象, 并创建watcher与dep的关系 * complie与watcher关系: 一对多的关系 4). Watcher * 模板中每一个非事件指令或表达式都对应一个watcher对象 * 监视当前表达式数据的变化 * 建立的时机: 在初始化编译模板时 * 对象的组成 { vm, //vm对象 exp, //对应指令的表达式 cb, //当表达式所对应的数据发生改变的回调函数 value, //表达式当前的值 depIds //表达式中各级属性所对应的dep对象的集合对象 //属性名为dep的id, 属性值为dep } 5). 总结: dep与watcher的关系: 多对多 * 一个data中的属性对应对应一个dep, 一个dep中可能包含多个watcher(模板中有几个表达式使用到了属性) * 模板中一个非事件表达式对应一个watcher, 一个watcher中可能包含多个dep(表达式中包含了几个data属性) * 数据绑定使用到2个核心技术 * defineProperty() * 消息订阅与发布 4.双向数据绑定 1). 双向数据绑定是创建在单向数据绑定(model==>View)的基础之上的 2). 双向数据绑定的实现流程: * 在解析v-model指令时, 给当前元素添加input监听 * 当input的value发生改变时, 将最新的值赋值给当前表达式所对应的data属性