Vue.extend()实现多个页面弹框登录(vue.use、vue.prototype)

49 篇文章 1 订阅
41 篇文章 0 订阅

官网照明:API — Vue.js

使用场景:使用基础 Vue 构造器,创建一个“子类”。当项目中想要每个页面或者特定的多个页面弹出、出现xxx内容时,可以使用Vue.extend()实现。

  • 场景1:只要登录后才能实现收藏,想在所有涉及到收藏的页面判断是否登录,没有登录的在点击收藏时弹出登录框。
  • 场景2:给每个页面增加一个回到首页的悬浮按钮。

代码实现: 

  •   先建一个LoginModal.vue文件将弹框内容实现;
<!-- 登录弹框 -->
<template>
    <view class="login-dialog">
        <uni-popup class="login-popup" ref="inputDialog">
            <view class="login-title">手机号登录</view>
            <!-- 基础表单校验 -->
            <uni-forms ref="valiForm" :rules="rules" :modelValue="valiFormData">
                <uni-forms-item name="mobilePhone">
                    <uni-easyinput trim="all" type="tel" v-model="valiFormData.name" focus placeholder="请输入手机号" />
                </uni-forms-item>
                <uni-forms-item name="validateCode">
                    <view class="form-item">
                        <uni-easyinput trim="all" v-model="valiFormData.age" placeholder="请输入6位验证码" />
                        <button class="form-item-code" type="primary" size="mini" plain="true" @click="getCode()" :disabled="isCodeDisabled">
                            {{ !isCodeDisabled ? '获取验证码' : count + 's' + '重新获取' }}
                        </button>
                    </view>
                </uni-forms-item>
            </uni-forms>
            <button @click="handleSubmit('valiForm')">登录</button>
        </uni-popup>
    </view>
</template>

<script>
export default {
    data() {
        return {
            isCheck: '',
            valiFormData: {
                mobilePhone: '',
                validateCode: '',
            },
            count: 60,
            timer: null,
            isCodeDisabled: false,
            userId: '',
            // 校验规则
            rules: {
                mobilePhone: {
                    rules: [
                        {
                            required: true,
                            errorMessage: '手机号码不能为空',
                        },
                        {
                            pattern: /^[1]([3-9])[0-9]{9}$/,
                            errorMessage: '手机号不合法!',
                        },
                    ],
                },
                validateCode: {
                    rules: [
                        {
                            required: true,
                            errorMessage: '验证码不能为空',
                        },
                        {
                            format: 'number',
                            maxLength: 6,
                            errorMessage: '验证码只能输入6个数字',
                        },
                    ],
                },
            },
        };
    },
    methods: {
        handleOpen() {
            this.$refs.inputDialog.open('bottom');
        },
        close() {
            this.$refs.inputDialog.close();
        },
        //获取短信验证码
        getCode() {
            this.$refs.valiForm
                .validateField(['mobilePhone'])
                .then(res => {
                    if (!this.timer) {
                        // 验证码接口
                        this.$api.getPhoneCode({ mobilePhone: res.mobilePhone }).then(res => {
                            if (res.result == 1) {
                                this.$msg.success('手机短信已发送!');
                            } else {
                                this.$msg.error('服务器错误!');
                            }
                        });
                        this.isCodeDisabled = true;
                        this.timer = setInterval(() => {
                            if (this.count > 0 && this.count <= 60) {
                                this.count--;
                            } else {
                                this.isCodeDisabled = false;
                                clearInterval(this.timer);
                                this.timer = null;
                                this.count = 60;
                            }
                        }, 1000);
                    }
                })
                .catch(err => {
                    console.log(err);
                });
        },
        handleSubmit(ref) {
            this.$refs[ref]
                .validate()
                .then(res => {
                    // 登录接口
                    this.$api
                        .login({
                            mobilePhone: res.mobilePhone,
                            validateCode: res.validateCode,
                        })
                        .then(res => {
                            if (res && res.ID_) {
                                this.$msg.success('登录成功!');
                                this.$refs.inputDialog.close();
                                location.reload();
                            } else {
                                this.$msg.error(res.message);
                                this.userId = '';
                                res.validateCode = '';
                            }
                        });
                })
                .catch(err => {
                    console.log('err', err);
                });
        },
    },
};
</script>
  • 创建一个LoginModal.js文件来将实例构造器挂载在页面上;
import Vue from "vue";
import Login from '@/pages/LoginModal.vue';

// 1.使用基础 Vue 构造器,创建一个“子类”;
const LoginModal = Vue.extend(Login);   
const LoginModalBox = (options = {}) => {
    // 2.创建 LoginModal 实例;
    let instance = new LoginModal();  //无传参
    // let instance = new LoginModal({
    //     data: {
    //         ...options, //有传参
    //     },
    // });
    // 3.实例构造器需要进行挂载到页面中;
    instance.$mount(); 
    // 4.通过$el属性来访问创建的组件实例;
    document.body.appendChild(instance.$el); 
    console.log(instance, 'instance');
    return instance;
};
// 5.两种方式将逻辑函数进行暴露,并且在mian.js引入挂载到全局;
// 5-1.Vue.prototype直接暴露;
export default LoginModalBox; 
// 5-2. vue.use()的install()暴露对象;
export default {
    install: (Vue) => {
        Vue.prototype.$loginModal = LoginModalBox;
    },
};

  •  在mian.js引入挂载到全局;
  1. 如果是使用的5-1的方式直接暴露,则在main.js中直接写:Vue.prototype.$loginModal = LoginModalBox;
  2. 如果是使用的5-2的install()方法来暴露一个对象,则在main.js中直接写:Vue.use(LoginModalBox);
import Vue from 'vue';
import store from './store/index'
import App from './App.vue';
import router from './router';
import LoginModalBox from '@/core/LoginModal.js'
Vue.config.productionTip = false;

// 方法一:在原型上定义,使其在每个Vue中的实例中可用;
Vue.prototype.$loginModal = LoginModalBox;
// 方法二:使用Vue.use
// Vue.use(LoginModalBox);

new Vue({
  router,
  store,
  render: h => h(App),
}).$mount('#app')
  • 使用创建的‘子类’;
handleLogin() {
    // 直接调用loginModal页面的方法
    this.$loginModal().handleOpen();
},

知识点:Vue.use 与 Vue.prototype 的区别

  1. Vue.prototype是在原型上定义,使其在每个Vue中的实例中可用。
  2. Vue.use()方法的核心就是Vue.prototype,只不过又封装了一层,执行install 方法,更加的灵活,扩展性更好。
  3. 两者没有本质区别。Vue.prototype适合于注册Vue生态外的插件,Vue.use适合于注册Vue生态内的插件。
  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值