Lenny-Hu / note

blog
5 stars 1 forks source link

在传统lamp中使用vue #72

Open Lenny-Hu opened 5 years ago

Lenny-Hu commented 5 years ago

// 定义vue插件、常量、过滤器等 common.js

(function () {
  // 定义公共常量
  window._constant = {
    httpBase: 'xx.php',
    navList: [
      {
        title: '基本知识',
        url: '/dianping/topics/laji/info'
      },
      {
        title: '垃圾查询',
        url: 'http://trash.lhsr.cn/sites/feiguan/trashTypes_3/TrashQuery.aspx'
      },
      {
        title: '每日签到',
        url: '/dianping/topics/laji/sign'
      },
      {
        title: '奖励兑换',
        url: '/dianping/topics/laji/duihuan'
      },
      {
        title: '签到日历',
        url: '/dianping/topics/laji/calendar'
      },
      {
        title: '签到排行',
        url: '/dianping/topics/laji/leaderboard'
      }
    ],
    prizeList: [
      {
        title: '风扇',
        integral: 40,
        n: 0 // 对应后台的兑换编号
      },
      {
        title: '指尖陀螺',
        integral: 60,
        n: 1
      },
      {
        title: '熊头抱枕',
        integral: 90,
        n: 2
      },
      {
        title: '博雅礼包',
        integral: 140,
        n: 3
      }
    ]
  };

  $(function () {
    // 消息控制
    var busPlugin = {
      install: function (Vue) {
        Vue.prototype.$bus = new Vue();
      }
    };

    // 过滤器
    Vue.filter('date', function (datetime, format) {
      format = format || 'YYYY年MM月DD日';
      if (!datetime) {
        return datetime || '';
      }
      if (/年|月|日/g.test(datetime)) {
        return datetime;
      }
      return dayjs(datetime).format(format);
    });

    // 加载中...插件
    var loadingInstance = null;
    var ModuleLoading = Vue.extend({
      template: '#tmp-loading',
      data: function () {
        return {
          visible: false,
          loadingText: ''
        }
      },
      methods: {
        show: function (text) {
          if (text) {
            this.loadingText = text;
          }
          this.visible = true;
        },
        close: function () {
          this.visible = false;
          this.loadingText = '';
        }
      }
    });

    var loadingPlugin = {
      install: function (Vue) {
        Vue.prototype.$loading = (function () {
          var instance = loadingInstance = new ModuleLoading();
          instance.vm = instance.$mount();
          document.body.appendChild(instance.vm.$el);
          return instance.vm;
        })();
      }
    };

    // 全局对话框组件
    Vue.component('m-dialog', {
      props: {
        value: Boolean,
        title: String
      },
      template: '#tmp-dialog',
      data: function () {
        return {};
      },
      methods: {
        close: function () {
          this.$emit('input', false);
          this.$emit('close');
        }
      },
      created: function () {
      }
    });

    // http请求
    $.ajaxSetup({
      dataType: 'json',
      beforeSend: function (jqXHR, settings) {
        if (settings.type == 'GET') {
          settings.url += '&_time=' + Date.now();
        }
      }
    });

    $(document).ajaxError(function (event, request, settings) {
      bm.alert({text: '请求发生错误:' + settings.url});
    });

    $(document).ajaxComplete(function () {
      loadingInstance && loadingInstance.close();
    });

    var httpPlugin = {
      install: function (Vue) {
        Vue.prototype.$http = $;
      }
    };

    // 公用请求方法
    var Mixins = new Vue({
      data: function () {
        return {
          user: {}
        };
      },
      computed: {
        isLogined: function () {
          return !!this.baseInfo.user.realName;
        }
      },
      methods: {
        getBaseInfo: function () {
          var _this = this;
          this.$http.get(window._constant.httpBase,
            {
              action: 'info'
            }
          ).then(function (res) {
            if (res.user.realName) {
              _this.$set(_this, 'user', res.user);
              _this.$bus.$emit('getUserInfo-done', res.user);
            } else {
              // 未登录用户,跳转登陆
              location.href = '/account/login?callback=' + location.pathname;
            }
          });
        }
      }
    });

    var mixinsPlugin = {
      install: function (Vue) {
        Vue.prototype.$mixin = Mixins;
      }
    };

    Vue.use(loadingPlugin);
    Vue.use(httpPlugin);
    Vue.use(mixinsPlugin);
    Vue.use(busPlugin);
  });
})();

common.phtml,使用 <?php include 'common.phtml'; ?> 进行加载公共html片段

<script type="text/x-template" id="tmp-dialog">
    <div class="m-dialog-box" v-if="value">
    <div class="m-dialog-inner">
      <div class="m-dialog-header">
        <!-- <h6 class="f-toe">{{title}}</h6> -->
        <slot name="header"></slot>
            </div>
      <div class="m-dialog-body">
        <span class="close" @click="close"></span>
                <slot></slot>
      </div>
      <div class="m-dialog-footer" v-if="$slots.footer">
        <slot name="footer"></slot>
      </div>
    </div>
  </div>
</script>

 <script type="text/x-template" id="tmp-loading">
    <div class="m-loading-box f-tac f-fs-12" v-if="visible">
    <div class="m-loading-inner s-bgc-fff">
      <div class="img-box">
        <img src="/dianping/www/images/common/hm_loading.gif" alt="">
      </div>
      <div class="loading-text">{{ loadingText || '加载中'}}</div>
    </div>
  </div>
</script>

实际业务使用

(function () {
  $(function () {
    var VM = new Vue({
      el: '#app',
      data: {
        loading: true,
        prizeList: window._constant.prizeList,
        showDlg: false,
        confirmInfo: {
          img: '',
          title: '',
          desc: '',
          okCb: null,
          cancelCb: null,
          showCancel: true
        }
      },
      computed: {
      },
      methods: {
        confirm: function () {
          this.showDlg = false;
          this.confirmInfo.okCb && this.confirmInfo.okCb.call(this);
        },
        cancel: function () {
          this.showDlg = false;
          this.confirmInfo.cancelCb && this.confirmInfo.cancelCb.call(this);
        },
        confirmDlg: function (params) {
          var iconClassMap = {
            1: 'fish',
            2: 'egg',
            3: 'rabbit',
            4: 'monster',
          };
          this.confirmInfo.title = params.title;
          this.confirmInfo.desc = params.desc;
          this.confirmInfo.showCancel = !!params.showCancel;
          this.confirmInfo.img = iconClassMap[params.icon];

          params.okCb && (this.confirmInfo.okCb = params.okCb);
          params.cancelCb && (this.confirmInfo.cancelCb = params.cancelCb);
          this.showDlg = true;
        },
        exchange: function (item) {
          // 检查完善信息
          var user = this.$mixin.user;
          if (!(user.realName && user.mobile && user.address)) {
            this.confirmDlg({
              icon: 4,
              title: '立即完善信息?',
              showCancel: true,
              okCb: function () {
                location.href = '/dianping/topics/laji/userinfo';
              }
            });
            return false;
          }

          // 检查积分
          if (user.score < item.integral) {
            this.confirmDlg({
              icon: 1,
              title: '您的<span class="s-fc-FF476A">积分不足</span>',
              desc: '请获得足够的积分后再来'
            });
            return false;
          }

          // 兑换确认提示
          this.confirmDlg({
            icon: 3,
            title: '确认兑换"<span class="s-fc-FF476A">' + item.title + '</span>"',
            showCancel: true,
            okCb: function () {
              this.postExchange(item.n);
            }
          });
        },
        postExchange: function (n) {
          // 请求兑换
          var _this = this;
          _this.$loading.show();
          _this.$http.post(window._constant.httpBase + '?action=duihuan', { jp: n })
            .done(function (res) {
              if (res.state == 1) {
                var arr = res.message.split(',');
                // 兑换成功
                _this.confirmDlg({
                  icon: 2,
                  title: '<span class="s-fc-FF476A">' + arr[0] + '</span>',
                  desc: arr[1] || ''
                });
                _this.$mixin.getBaseInfo();
              } else {
                bm.alert({text: res.message});
              }
            });
        }
      },
      mounted: function () {
        this.$loading.show();
        this.$mixin.getBaseInfo();
        this.loading = false;
      }
    });
  });

})();