vue基础及高级用法(二)

7 篇文章 0 订阅

6. Vue.nextTick

  • Vue.nextTick 会在dom渲染之后出发,以获取最新dom节点
  • Vue 异步队列使用 Promise.then、MutationObserver 和 setImmediate,如果不支持会采用 setTimeout(fn, 0) 代替。
this.$nextTick( () => {
// code
})
使用 Vue.nextTick 异步渲染的好处
  • 汇总data的修改,一次性更新视图。
  • 减少dom操作次数,提高性能。

7. ref属性

  • 在DOM 元素上使用,引用指向 DOM 元素;
  • 在子组件上使用,引用就指向组件实例,可调用子组件的data和mothods等。
$refs 在组件渲染之后生效,不是响应式的。应该避免在模板或计算属性中访问。
<!-- dom 元素 -->
<p ref="p">hello</p>

<!-- 子组件 -->
<child-component ref="child"></child-component>
this.$refs.xxx();

8. 动态组件:根据条件加载不同组件模板

<div id="app">
    <button @click="currentIndex = 0">
        1
    </button>
    <button @click="currentIndex = 1">
        2
    </button>
    <component :is="currentTabComponent"></component>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    Vue.component('t-one', {
        template: `
            <div>one</div>
        `
    })
    Vue.component('t-two', {
        template: `
            <div>two</div>
        `
    })
    const app = new Vue({
        el: '#app',
        data: {
            currentIndex: 0,
            status:['t-one','t-two']
        },
        computed: {
            currentTabComponent() {
                return this.status[this.currentIndex]
            }
        }
    });
</script>

9. vue组件异步加载

  • 只有用该组件到时才会加载。
  • 一般用于加载大组件。
// 具体用法
// a: () => import('./components/a.vue')
new Vue({
    ...rest,
    components: {
        a: () => import('./components/a.vue')
    }
})

10. keep-alive

keep-alive 是 Vue 内置的缓存组件,避免使包含的组件重新渲染。
大致用法

<keep-alive>
    <KeepAliveStageA v-if="state === 'A'"/>
    <KeepAliveStageB v-if="state === 'B'"/>
</keep-alive>

具体案例
app.vue

<template>
    <div>
        <button @click="changeState('A')">A</button>
        <button @click="changeState('B')">B</button>
        
        <keep-alive>
            <KeepAliveStageA v-if="state === 'A'"/>
            <KeepAliveStageB v-if="state === 'B'"/>
        </keep-alive>
    </div>
</template>

<script>
import KeepAliveStageA from './components/KeepAliveStateA'
import KeepAliveStageB from './components/KeepAliveStateB'

export default {
    components: {
        KeepAliveStageA,
        KeepAliveStageB
    },
    data() {
        return {
            state: 'A'
        }
    },
    methods: {
        changeState(state) {
            this.state = state
        }
    }
}
</script>

子组件A,子组件B同理

<template>
    <p>state A</p>
</template>

<script>
export default {
    mounted() {
        // eslint-disable-next-line
        console.log('A mounted')
    },
    destroyed() {
        // eslint-disable-next-line
        console.log('A destroyed')
    }
}
</script>

11. mixin,混入:抽离组件公共逻辑

不足

  • 多个mixin可能会造成命名冲突
  • mixin和组件出现多对多关系时,复杂度较高

用法

<template>
    <div>
        {{name}},{{city}}
        <button @click="showName">显示姓名</button>
    </div>
</template>

<script>
import myMixin from './mixin'
export default {
    mixins: [myMixin], // 可以添加多个,会自动合并起来
    data() {
        return {
            name: '你好'
        }
    },
    methods: {
    },
    mounted() {
        // eslint-disable-next-line
        console.log('component mounted', this.name)
    }
}
</script>

mixin.js

export default {
    data() {
        return {
            city: '北京'
        }
    },
    methods: {
        showName() {
            // eslint-disable-next-line
            console.log(this.name)
        }
    },
    mounted() {
        // eslint-disable-next-line
        console.log('mixin mounted', this.name)
    }
}

12. vuex:实现Vue多个组件响应式共享状态的管理工具。

核心功能
  • State :定义全局共享的state变量

第一步:在仓库store中定义需要全局共享的state变量

state: {
    age: 25
}

第二步:在对应的组件中获取并显示在页面上

<p>{{$store.state.age}}</p>
  • Getters:相当于组件中的computed计算属性。

第一步:在仓库store中定义好getters

getters: {
    getAge(state) {
        return state.age + 1;
    }
}

第二步:在对应的组件中获取并显示在页面上

<p>{{$store.getters.getAge}}</p>
  • Mutations:修改state变量

第一步:在仓库store中定义需求调用的mutation方法

mutations: {
    incre(state, payload) {
        state.age += payload.age;
    }
}

第二步:在对应组件中定义触发更改状态的模板和方法

// template
<button @click="add">增加</button>

// script
methods: {
    add() {
        this.$store.commit('incre', {age: 1});
    }
}
  • Actions:只有它可以为异步函数,可以整合多个mutation。

第一步:在仓库store中定义需求调用的mutation方法

actions: {
    increAsyn({commit}, payload) {
        commit('incre', payload);
    }
}

第二步:在对应组件中定义触发更改状态的模板和方法

// template
<button @click="addAsyn">异步增加</button>

// script
addAsyn() {
    this.$store.dispatch('increAsyn', {age: 1});
}
  • Modules

第一步:在仓库store中定义不同的模块以及modules方法

// 创建 moduleA.js
const moduleA = {
    state: {
        name: 'txm',
        age: 25
    },
    getters: {},
    mutations: {},
    actions: {}
}
// 创建 moduleB.js
const moduleB = {
    state: {
        name: 'sxm',
        age: 22
    },
    getters: {},
    mutations: {},
    actions: {}
}

// 在index.js中要import
modules: {
    a: moduleA,
    b: moduleB
}

第二步:在对应的组件中获取并显示在页面上

<p>{{$store.state.a.age}}</p>
<p>{{$store.state.b.age}}</p>
辅助函数:设置为组件内的computed、method
  • mapState

第一步:在对应的组件中从vuex取出mapState

import {mapState} from 'vuex';

获取仓库store里的状态

computed: {
    ...mapState([
        'age'
    ])
}

第二步:在对应的组件中获取并显示在页面上

<p>{{age}}</p>
  • mapGetters

第一步:在对应的组件中从vuex取出mapGetters

import {mapGetters} from 'vuex';

通过组件中的计算属性进行获取:

computed: {
    ...mapGetters([
        'getAge'
    ])
}

第二步:在对应的组件中获取并显示在页面上

<p>{{getAge}}</p>
  • mapMutations

第一步:在对应的组件中从vuex取出mapMutations

import {mapMutations} from 'vuex';

在组件的methods属性中获取仓库store中的mutations方法,然后在methods里对应的方法中执行也可以携带参数。

methods: {
    add() {
        // this.$store.commit('incre', {age: 1});
        this.incre({age: 1});
    },
    // 相当于定义了一个 incre 方法
    ...mapMutations([
        'incre'
    ])
}
  • mapActions

第一步:在对应的组件中从vuex取出mapActions

import {mapActions} from 'vuex';

在组件的methods属性中获取仓库store中的actions方法,然后在methods里对应的方法中执行也可以携带参数。

methods: {
    addAsyn() {
        // this.$store.dispatch('increAsyn', {age: 1});
        this.increAsyn({age: 1});
    },
    // 相当于定义了一个 increAsyn 方法
    ...mapActions([
        'increAsyn'
    ])
}

13. vue-router

路由模式
  • hash 模式:默认配置。
    通过window.onhashchange监听路由变化
  • H5 history 模式:不带#,更好看(官方说法)。
    通过history.pushStatewindow.onpopstate监听路由变化
两者选择
  • 两者的url发生变化,会发生页面跳转,但不会刷新页面。
  • to B的系统推荐hash,简单易用。
  • to C的系统可以考虑H5 historyseo更友好,但需要服务端支持。
基本使用、参数、懒加载
<!-- 一般在app.vue中 -->
<!-- 路由链接 -->
<router-link to="/">Home</router-link> 
<!-- 路由占位符 -->
<router-view/>
const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home
  },
  {
    path: '/about',
    name: 'About',
    // 路由懒加载
    // /* webpackChunkName: "about" */ 将懒加载的组件按组,打包在异步块中
    component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
  },
  {
    path: '/about1',
    name: 'About1',
    // 路由懒加载
    // /* webpackChunkName: "about" */ 将懒加载的组件按组,打包在异步块中
    component: () => import(/* webpackChunkName: "about" */ '../views/About1.vue')
  },
  {
    path: '/pay',
    name: 'Pay',
    // 路由懒加载
    // /* webpackChunkName: "pay" */ 将懒加载的组件按组,打包在异步块中
    component: () => import(/* webpackChunkName: "pay" */ '../views/Pay.vue')
  },
  // 携带参数的路由
  {
    path: '/user/:id',
    // 加载页面时,会一同加载
    component: User
  }
]
  • 组件获取路由参数
<!-- 在路由组件中使用参数 -->
<div>User {{ $route.params.id }}</div>
<!-- 在js中使用 -->
this.$route.params.id
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值