wangyue217 5 年 前
コミット
a7b6fe8f7c

+ 10 - 0
src/config.js

@@ -155,6 +155,16 @@ module.exports = {
           show: true,
           desc: '轻提示',
           author: 'undo'
+        },
+        {
+          version: '3.0.0',
+          name: 'Notify',
+          type: 'component',
+          cName: '消息提示',
+          desc: '在页面顶部展示消息提示,支持函数调用和组件调用两种方式',
+          sort: 4,
+          show: true,
+          author: 'wangyue217'
         }
       ]
     },

+ 35 - 0
src/packages/notify/demo.vue

@@ -0,0 +1,35 @@
+<template>
+  <div class="demo">
+    <h2>基础用法</h2>
+    <nut-cell :showIcon="true" :isLink="true" @click="notify1('通知内容')">
+      <span>
+        <label>基础用法</label>
+      </span>
+    </nut-cell>
+  </div>
+</template>
+
+<script lang="ts">
+import { createApp } from 'vue';
+import { createComponent } from '@/utils/create';
+import notify from './index';
+const { createDemo } = createComponent('notify');
+const app = createApp({});
+app.use(notify);
+export default createDemo({
+  props: {},
+  setup() {
+    const notify1 = () => {
+      notify('content');
+    };
+    return {
+      notify1
+    };
+  }
+});
+</script>
+
+<style lang="scss" scoped>
+.nut-temp {
+}
+</style>

+ 34 - 0
src/packages/notify/doc.md

@@ -0,0 +1,34 @@
+#  notify组件
+
+    ### 介绍
+    
+    基于 xxxxxxx
+    
+    ### 安装
+    
+    
+    
+    ## 代码演示
+    
+    ### 基础用法1
+    
+
+    
+    ## API
+    
+    ### Props
+    
+    | 参数         | 说明                             | 类型   | 默认值           |
+    |--------------|----------------------------------|--------|------------------|
+    | name         | 图标名称或图片链接               | String | -                |
+    | color        | 图标颜色                         | String | -                |
+    | size         | 图标大小,如 '20px' '2em' '2rem' | String | -                |
+    | class-prefix | 类名前缀,用于使用自定义图标     | String | 'nutui-iconfont' |
+    | tag          | HTML 标签                        | String | 'i'              |
+    
+    ### Events
+    
+    | 事件名 | 说明           | 回调参数     |
+    |--------|----------------|--------------|
+    | click  | 点击图标时触发 | event: Event |
+    

+ 2 - 0
src/packages/notify/index.scss

@@ -0,0 +1,2 @@
+.nut-notify {
+}

+ 143 - 0
src/packages/notify/index.ts

@@ -0,0 +1,143 @@
+import VanNotify from './index.vue';
+import {
+  createApp,
+  reactive,
+  Component,
+  nextTick,
+  getCurrentInstance,
+  h
+} from 'vue';
+
+let timer;
+let instance;
+const inBrowser = typeof window !== 'undefined';
+
+function isObject(val: unknown): val is Record<any, any> {
+  return val !== null && typeof val === 'object';
+}
+
+function parseOptions(message) {
+  return isObject(message) ? message : { message };
+}
+
+function useExpose(apis: Record<string, any>) {
+  const instance = getCurrentInstance();
+  if (instance) {
+    Object.assign(instance.proxy, apis);
+  }
+}
+function usePopupState() {
+  const state = reactive({
+    show: false
+  });
+
+  const toggle = (show: boolean) => {
+    state.show = show;
+  };
+
+  const open = (props: Record<string, any>) => {
+    Object.assign(state, props);
+
+    nextTick(() => {
+      toggle(true);
+    });
+  };
+
+  const close = () => {
+    toggle(false);
+  };
+
+  useExpose({ open, close, toggle });
+
+  return {
+    open,
+    close,
+    state,
+    toggle
+  };
+}
+function mountComponent(RootComponent: Component) {
+  const app = createApp(RootComponent);
+  const root = document.createElement('div');
+
+  document.body.appendChild(root);
+
+  return {
+    instance: app.mount(root),
+    unmount() {
+      app.unmount(root);
+      document.body.removeChild(root);
+    }
+  };
+}
+function initInstance() {
+  ({ instance } = mountComponent({
+    setup() {
+      const { state, toggle } = usePopupState();
+      return h('img', {});
+    }
+  }));
+}
+
+function Notify(options) {
+  if (!inBrowser) {
+    return;
+  }
+
+  if (!instance) {
+    initInstance();
+  }
+
+  options = {
+    ...Notify.currentOptions,
+    ...parseOptions(options)
+  };
+
+  instance.open(options);
+  clearTimeout(timer);
+
+  if (options.duration > 0) {
+    timer = setTimeout(Notify.clear, options.duration);
+  }
+
+  return instance;
+}
+
+function defaultOptions() {
+  return {
+    type: 'danger',
+    color: undefined,
+    message: '',
+    onClose: null,
+    onClick: null,
+    onOpened: null,
+    duration: 3000,
+    className: '',
+    background: undefined
+  };
+}
+
+Notify.clear = () => {
+  if (instance) {
+    instance.toggle(false);
+  }
+};
+
+Notify.currentOptions = defaultOptions();
+
+Notify.setDefaultOptions = options => {
+  Object.assign(Notify.currentOptions, options);
+};
+
+Notify.resetDefaultOptions = () => {
+  Notify.currentOptions = defaultOptions();
+};
+
+Notify.install = app => {
+  app.use(VanNotify);
+  app.config.globalProperties.$notify = Notify;
+};
+
+Notify.Component = VanNotify;
+
+export default Notify;

+ 47 - 0
src/packages/notify/index.vue

@@ -0,0 +1,47 @@
+<template>
+  <view class="nut-notify">
+    <nut-popup
+      v-model="curVisible"
+      position="top"
+      :style="{ color: color, background: background }"
+      :overlay="false"
+      :lockScroll="false"
+      :class="['nut-notify', `nut-notify--${type}`, { className }]"
+      @click="handleClick"
+      @opened="handleOpened"
+      @closed="handleClosed"
+    >
+      <template v-if="$slots.default">
+        <slot></slot>
+      </template>
+      <template v-else>{{ msg }}</template>
+    </nut-popup>
+  </view>
+</template>
+<script lang="ts">
+import { toRefs } from 'vue';
+import { createComponent } from '@/utils/create';
+import Popup from '@/packages/popup/index.vue';
+const { componentName, create } = createComponent('notify');
+
+export default create({
+  props: {
+    color: String,
+    message: [Number, String],
+    className: null,
+    background: String,
+    type: {
+      type: String,
+      default: 'danger'
+    }
+  },
+
+  setup(props, { slots }) {
+    return {};
+  }
+});
+</script>
+
+<style lang="scss">
+@import 'index.scss';
+</style>