Vue扩展

VueX

1. HTTP是无状态的,跨页面的数据无法共享,但Vue是单页面应用,VueX可以实现数据共享;
1. VueX的更新过程:Component --> Actions --> Mutations --> State --> Component
2. State:VueX管理的状态对象;
    const state = { --> 该对象应该是唯一的
        xxx: yyy ---> vuex管理的全局共享变量
    }
3. Mutations:包含多个直接更新State方法的对象;
    1. Action中的commit('Mutation的名称')触发更新;
    2. Mutation中只能包含同步代码,不能有异步代码
4. Actions:包含多个事件回调函数的对象;
    1. 执行commit()触发Mutation,间接更新state;
    2. 在组件中,$store.dispatch('action的名称')触发回调;
    3. Action中可以包含异步代码,如定时器、AJAX

使用VueX

1. npm/cnpm install --save vuex
2. 创建VueX的核心管理对象模块store.js
    1. VueX是Vue的插件,需要先导入Vue:import Vue from 'vue'
    import Vuex from 'vuex'
    Vue.use(Vuex)
    2. 暴露Vuex.Store的四个常用的对象
    const state = { count: 0 }  --> 用于初始化状态
    const getters = {
        evOrOdd(state) { --> 不需要手动调用,只需要读取属性值
            return state.count%2===0 ? '偶数' : '奇数'
        }
    }
    const actions = {
        increment({commit}, num) {
            commit('INCREMENT', {num}) -->提交给mutations的INCREMENT()
        },  ---> commit()传递的参数必须使用对象,参数为num
        decrement({commit, state}) { --> 使用state,vuex内部的解构赋值
            if(state.count === 10) return;
            commit('DECREMENT') ---> 提交给mutations的DECREMENT()
        },
        asyncCrement({commit}) {  ---> 在actions中执行异步逻辑
            setTimeout(() => {
                commit('DECREMENT')
            }, 1000)
        }
    }
    const mutations = {
        INCREMENT(state, {num}) { -->实参为num,使用的解构赋值接收实参
            state.count+=num  ---> 操作全局共享的变量
        },
        DECREMENT(state) { state.count-- }
    }
    export default new Vuex.Store({
        state, mutations, actions, getters-->包含多个getter计算属性的对象
    })
3. 在main.js中引入Vuex模块:import store from './store'
    new Vue({ ......,
        store -->映射store,那么组件对象就具有一个指向store对象的属性:$store
    })
4. 在vue组件中,使用store
    computed: {
        evOrOdd() { ---> 在计算属性中,获取store.count的属性值
            return this.$store.getters.evOrOdd
        }
    }
    methods: {
        increment(num) { ---> dispatch()触发actions中的increment()
            this.$store.dispatch('increment', num)
        },
        decrement() {
            this.$store.dispatch('decrement')
        },
    }
5. 简写形式:import { mapState, mapActions, mapGetters } from 'vuex'
    computed: {  --> 计算vuex属性的简写形式
        ...mapState(['count']),  ---> this.$store.state.count
        ...mapGetters(['evOrOdd']) -->this.$store.getters.evOrOdd()
    }, ---> count和evOrOdd都映射为当前组件对象的属性
    methods: { --> vuex:actions中的方法的简写形式
        ...mapActions(['increment', 'decrement', 'decrement'])
    } ---> increment、decrement、decrement也都映射为methods中的方法
Vue扩展_第1张图片
image
6. 如果actions、getters、mutations中的方法过多时,还可以拆分成一个个js模块;
7. watch也可以监听vueX中的数据变化
    computed: {   ---> 1.先使用计算属性返回vueX中的某个数据
        count() {
            this.$store.state.count 
        }
    }
    watch: {  ---> 2.再使用watch监听
        count: function(v1, v2) {
            v1:新值,v2:旧值
        }
    }

Vue补充

1. render(h):渲染函数
    new Vue({
        el: '#app',
        components: { App },
        template: '',
    })
    简写形式:
        new Vue({
            el: '#app',
            render: h => h(App),
        })
2. this.$nextTick(callback):等待下一次事件轮询时执行,下一次Event Loop
    1. 比如,v-html渲染html字符串是需要时间的,JS不能直接操作其中的DOM节点,需要等待下次
    事件轮询; 
data = 'HTML字符串' this.$nextTick(()=>{ let test = document.getElementById('test'); }) 2. $nextTick()与Vue钩子函数的实现原理是由浏览器的渲染机制决定的。 3. 便捷访问static目录下的图片: 4. 动态挂载组件 1. 创建Vue实例 let MyComponent = Vue.extend({ template: '
{{uname}}
', data: function(){ return { uname:'Mack' } }, method: { ... } }) 2. 动态挂载到指定DOM节点上: new MyComponent().$mount('#home'); ---> 方式一 new MyComponent({ el:'#home' }) ---> 方式二 3. 在文档之外渲染,随后再动态挂载 let component = new MyComponent().$mount() document.getElementById('home').appendChild(component.$el)

实现原理

1. Vue作为一个MVVM框架的基本实现原理:数据代理、模板解析、数据绑定
2. Vue涉及的核心技术:虚拟DOM、Diff算法
3. 关键性方法:Object.defineProperty(obj, prop, descriptor)

DocumentFragment

1. DocumentFragment:文档碎片,虚拟DOM对象,表示一个没有父级文件的最小文档对象;
2. 被当作一个轻量版的Document使用,用于存储已排好版的或尚未打理好格式的XML片段;
3. Document对应显示的页面,包含N个Element,更新Document内部的元素,界面也会更新;
4. DocumentFragment并不是真实DOM树的一部分,而是内存中保存N个Element的容器对象,
不与界面关联,它的变化不会引起DOM树的重新渲染,界面不变,且不会导致性能等问题;

数据代理

1. 数据代理:通过一个对象代理操作另一个对象中的属性;
2. Vue的数据代理:通过vm对象来代理data对象中的所有属性操作;
3. Vue数据代理的实现:vm中的_data属性代理了data对象
    1. 通过Object.defineProperty()给vm添加与data对象的属性对应的属性描述符,监视
    vm的属性变化;
    2. Object.defineProperty()会为vm中所有添加的属性提供getter/setter,它们内部
    去操作data中对应的属性数据。

模板解析

1. 创建DocumentFragment对象,递归遍历DOM树,将DOM节点添加进DocumentFragment中,
也即,将DOM节点映射到虚拟DOM对象中;
2. 解析大括号表达式({{name}})、一般指令、事件指令。

数据绑定

1. 一旦更新了data对象中的某个属性数据,所有界面上直接/间接使用此属性的节点都会更新;
2. 数据劫持:Vue中用来实现数据绑定的一种技术;
3. 劫持的基本思想:也是通过Object.defineProperty()为data对象中的属性添加setter/
getter,来监视所有属性数据的变化,并随之更新界面;
4. vm --> data --> 更新界面
5. 双向数据绑定:建立在单向数据绑定的基础之上;
    1. 在解析v-model指定时,给当前元素添加input监听;
    2. 当input的value发生变化时,将最新的指赋给当前表达式对应的data对象中的属性。

你可能感兴趣的:(Vue扩展)