1. 虚拟 DOM 原理 http://www.cnblogs.com/lvyongbo/p/5931636.html
单向数据流和双向数据流区别 说到底就是 (value 的单向绑定 + onChange 事件侦听)的一个语法糖,你如果不想用 v-model,像 React 那样处理也是完全可以的。单向数据流和双向数据流
2. 深扒 强烈推荐:双向数据绑定的 3 种实现方式 读懂源码:一步一步实现一个 Vue 响应式绑定参考 virtual dom 和 diff 算法参考 理解 vue 实现原理,实现一个简单的 Vue 框架 vue 源码分析之如何实现 observer 和 watcher vue 的 diff 算法学习
3. 总结 1.observe:主要是通过遍历 Object.defineProperty 为每个属性添加 get 和 set 方法 2.监听队列:
1 2 3 4 5 6 7 8 9 10 11 export default class Dep { constructor() { this.subs = [] //这个就是监听队列的数组 } addSub(sub){ this.subs.push(sub) //将要监听的属性放进去 } notify(){ this.subs.forEach(sub=>sub.update()) //在属性的set方法里会触发notify方法,进行遍历这些被监听或变化了的属性,进行dom更新 } }
订阅者–分辨是主动触发还是自动触发 单线程,当调用 watch 的时候会触发调用 get,这时候先标记一个全局变量,然后在普通属性里会判断是否含有这个变量,有的话就是自动触发,没有的话就是手动调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 export default class Watcher { ....省略未改动代码.... get(){ Dep.target = this //此处简化。。要区分fuction还是expression const value = this.vm._data[this.expOrFn] Dep.target = null return value } } export function defineReactive (obj, key, val) { var dep = new Dep() var childOb = observe(val) Object.defineProperty(obj, key, { enumerable: true, configurable: true, get: ()=>{ // 说明这是watch 引起的 if(Dep.target){ dep.addSub(Dep.target) } return val }, set:newVal=> { var value = val if (newVal === value) { return } val = newVal childOb = observe(newVal) dep.notify() } }) }
4.自定义插件 5.directive 用法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 //var app = document.createElement('app'); //document.getElementsByTagName('div')[0].appendChild(app); Vue.component('abc', { template: '<div>abc content</div>' }); Vue.directive('tip', { bind: function() { console.log('bind'); }, inserted: function(el) { var abc = document.createElement('abc'); el.appendChild(abc); new Vue({ el: el }); console.log('inserted'); }, update: function() { console.log('update'); }, componentUpdated: function() { console.log('componentUpdated'); }, unbind: function() { console.log('unbind'); } }) Vue.component('app', { beforeCreate: function() { console.log('beforeCreate') }, created: function() { console.log('created') }, beforeMount: function() { console.log('beforeMount') }, mounted: function() { console.log('mounted') }, beforeUpdate: function() { console.log('beforeUpdate') }, updated: function() { console.log('updated') }, activated: function() { console.log('activated') }, deactivated: function() { console.log('deactivated') }, beforeDestroy: function() { console.log('beforeDestroy') }, destroyed: function() { console.log('destroyed') }, template: '<div>test app content</div>' }); new Vue({ created: function() { //document.getElementsByTagName('div')[0].appendChild(app); }, el: 'div' });
6.Vue.component 的 Vue.extend 的区别 Vue.extend 写法
1 2 3 var newDemo = Vue.extend(Demo); new newDemo().$mount().$el;
Vue.component 写法
1 2 3 4 Vue.component('demo' , Demo); var newDemo = Vue.component('demo' ); new newDemo().$mount().$el;
vue-resource 1 2 3 4 5 6 7 8 9 10 11 12 13 // 全局 Vue.http.options.root = 'http://zhuanzhuan.58.com/zz/transfer'; // 交互请求的根目录地址 Vue.http.options.xhr = { withCredentials: true }; //XMLHttpRequest.withCredentials 开启CORS Vue.http.options.credentials = true; // 也是开启CORS Vue.http.interceptors.push((request, next) => {}); //自定义拦截器,预处理和后处理的要求 // 局部独立定义 export const replaycomment = (params) => { return Vue.http.post(API.REPLAY_COMMENT, params, { credentials: true, emulateJSON: true, }); };
参考文档
this 丢失 像 ajax 等异步操作,会丢失 this,而取不到属性值 避免方法:使用箭头函数
Vue 改变数组时,属性不监听 用 slice 先取出来
1 this .cateIdArr = this .getCateIdArr.slice();
不要同时监听 下边这两个是有区别的!!computed
是计算:别的数据改变,这个属性计算watch
是监听 不要一个属性在两个里都写,否则返回 undefined
v-model 返回值 数据类型为字符串 所以只有""
时为假,其他都为真
父组件与子组件通信 没有用 v-bind 传入的是字符串 用了 v-bind 传入的就是一个 js 表达式
1 2 3 4 <comp some-prop ="1" > </comp > <comp v-bind:some-prop ="1" > </comp >
#子组件内操作,同时父组件同时改变 父组件传过来的数据可以是一个对象, 在子组件对该对象进行修改, 被修改的同时也会修改父组件的数据了参考
CORS 跨域问题 服务器端开启
1 2 Access-Control-Allow-Credentials: true // 开启coockie验证 Access-Control-Allow-Origin: http://m.zhuanzhuan.58.com
Vue 设置
1 2 3 4 Vue.http.interceptors.push((request, next ) => { request.credentials = true ; next((response ) => {}); });
vue-resource progress 1 2 3 4 5 6 7 8 9 10 11 12 13 14 this .$http .post(url, data, { progress: function (event ) { if (event.lengthComputable) { let percentComplete = Math .round((event.loaded * 100 ) / event.total); console .log(percentComplete.toString() + '%' ); } else { console .log('不支持' ); } }, }) .then((response ) => { console .log(JSON .parse(res.body)); });
vue 无法监听到最开始属性值是 undefined 的属性 必须在 data 内先声明,才能进行监听
vuex 注意 1.修改状态必须通过 mutations/actions 修改,否则报错 2.用 v-model 的时候是双向绑定,vuex 并不是,需要将需要监听的值设成双向绑定
6 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 computed: { ...mapGetters([ 'commentData', 'replyParam', 'askParam', 'answerParam', 'sheetActions' ]), sheetVisible: { // 因sheetAction用了v-model 所以需要进行双向绑定 // getter get: function () { return this.$store.state.commentDetail.sheetVisible; }, // setter set: function (newValue) { this.changeSheetVisible(newValue); // 必须通过mutations修改 } } },
写法:
1 2 3 4 5 const store = new Vuex.Store({ modules: { account: { namespaced: true, // module assets state: { ... }, // module state is already nested and not affected by namespace option getters: { isAdmin () { ... } // -> getters['account/isAdmin'] }, actions: { login () { ... } // -> dispatch('account/login') }, mutations: { login () { ... } // -> commit('account/login') } } } })
Vue Cli 深入认识 深入认识 vue-cli:能做的不仅仅是初始化 vue 工程 vue-cli 简介(中文翻译) vue-cli 是如何工作的
监听对象内属性的变化 1 2 3 4 5 6 7 8 9 10 computed: { newIndex () { return this.swipeData.index; } }, watch: { newIndex () { this.scrollTo(this.swipeData.index); } },
思想:曲线救国,先计算,再监听这个计算值的变化
keep-alive 记录高度 vue-router 实现 vue 使用 keep-alive 保持滚动条位置的实现
1 2 3 4 5 6 7 8 9 10 11 12 const router = new Router({ scrollBehavior(to, from , savedPosition) { if (savedPosition) { return savedPosition; } else { return { x : 0 , y : 0 }; } }, mode: 'history' , base: '/u/zzlease/' , routes, });
接入 ts 用 TypeScript 来写 Vue! vue + typescript 新项目起手式 一起来拥抱强大的 TypeScript 吧
指令详解 vue 自定义指令 VNode 详解 官方文档
原理文章 keep-alive实现原理 面向源码研究Nuxt.js