使用场景:使用基础 Vue 构造器,创建一个“子类”。当项目中想要每个页面或者特定的多个页面弹出、出现xxx内容时,可以使用Vue.extend()实现。
- 场景1:只要登录后才能实现收藏,想在所有涉及到收藏的页面判断是否登录,没有登录的在点击收藏时弹出登录框。
- 场景2:给每个页面增加一个回到首页的悬浮按钮。
代码实现:
- <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>
- 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;
- },
- };
- 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 的区别
- Vue.prototype是在原型上定义,使其在每个Vue中的实例中可用。
- Vue.use()方法的核心就是Vue.prototype,只不过又封装了一层,执行
install
方法,更加的灵活,扩展性更好。- 两者没有本质区别。Vue.prototype适合于注册Vue生态外的插件,Vue.use适合于注册Vue生态内的插件。