This is the 16th day of my participation in the August More Text Challenge. For details, see: August More Text Challenge

Turn a corner

Convention: Preface

This part was supposed to be about business components.

However, the relationship between the business component itself and the component library is not particularly large, but more a kind of work experience accumulation; Second, business components also involve some system components, so in a different order, let’s talk about system components first. Let’s talk about business components.

In my initial vision, system components are mainly those that provide information for project presentation, such as interactive feedback, information prompt, navigation prompt, etc. This section will also focus on a few common system components.

Prompt component.

The notification components are mostly viewed on mobile devices, and most of them are seen in in-app notifications.

But it’s also particularly useful on the PC side, for example, for bugs, or error notifications

Well, like the nugget’s message, it belongs to the writer’s message.

But have to make fun of a sentence, really unfriendly, reasonable, this kind of prompt should not be input box red box + nearby text prompt? Or something like the picture below.

Of course, this is a Notice component that is easier to distance from.

Components that start with the layout

Now that we’re going to do it, it’s natural to put down the nuggets and think about how common notifications of this kind should be designed.

On mobile, there are three major interactions to consider: top to bottom appearance, bottom to top hiding, user manual hiding notification, click event, title, content, icon,

On the PC, the content block remains the same, with the title, content, and icon, and should be optional except for the content. The appearance of the hidden way can be freely designed. And when the user mouse hover, judge that the user is viewing the content, pause the hidden countdown.

Look at the layout first.

block content
  transition(
    name="notice"
    @before="beforeLeave"
    @leave="leave"
    @after="afterLeave"
    appear
  )
    div(
      class="yx-notice-content-rect" 
      v-if="isShow"
      @mouseover="endTime"
      @mouseout="startTime"
    )
      div.yx-notice-content
        div(
          class="yx-notice-bar"
          v-if="duration"
          :class="type"
        )
          i(:style="{width: bar + '%'}")
        span(
          class="yx-notice-icon"
          v-if="type"
        )
          i(:class="[icon || iconType[type], type]")
        div.yx-notice-title {{title}}
        div(
          class="yx-notice-description"
          v-if="content"
        ) {{content}}
        span(
          class="yx-notice-close"
          @click="close"
        )
          i.yx-icon-x
Copy the code

By the way, there should be an icon for Success in the upper left corner, but I’m too lazy to fill the icon library, so it’s gone. Imagine.

In addition, there should be a close button in the upper right corner, and the same is true for laziness. Xi xi xi.

The logical part

The logical part is mainly to improve the several interactive parts just said.

First of all, from the hidden, the emergence of its own hidden nothing, CSS can also control, mainly when the mouse hover, stop the countdown.

// Control the progress of current notifications
const progress = () = > {
  if(s <= t) {
    bar.value = (s/t) * 100
    s += 100
  } else {
    endTime()
    close()
  }
}
// Start the timer
const startTime = () = > {
  if(props.duration > 0) time = setInterval(progress, 100)}// Pause/end the timer
const endTime = () = > {
  clearInterval(time)
  time = null;
}
Copy the code

Close notifications and click events.

// Turn off notifications
const close = () = > {
  isShow.value = false;
}
const emits = defineEmits(['click'])
const handleClick = () = > {
    // code
    
    emits('click')}Copy the code

The last

Finally, there is the mounting of events, which are typically mounted globally. However, the global mount is still within the component, which has little impact.

import element from './notice.vue';

let NoticeWrap;
// To generate the DOM, you don't need to write it in the template
function createNoticeWrap(){
  const NoticeWrap = document.createElement('div');
  NoticeWrap.className = 'yx-notice-wrap';
  document.body.appendChild(NoticeWrap)
  return NoticeWrap
}
// Mount to the root node
function createComponent(component, props){
  const vnode = h(component, props)
  render(vnode, document.createElement('div'))
  return vnode.component
}

function noticeCreate(props, type){
  if(! props.title){return 
  }
  if(type){
    props.type = type;
  }

  if(! NoticeWrap){ NoticeWrap = createNoticeWrap() }const component = createComponent(element, props);
  NoticeWrap.appendChild(component.vnode.el)
}

function notice(props){
  noticeCreate(props)
}
// Different types, passed to the component by props.; ['info'.'error'.'success'.'warning'].forEach(type= > {
  notice[type] = props= > noticeCreate(props, type)
})

export default notice;

----------------------------
/ / call

// main.js

import notice from '@/components/notice/index';
app.config.globalProperties.$notice = notice;

// pages

this.$notice.info({
  title: 'Notice Notice'.content: 'notice content'.// icon: '',
  // duration: ''
})
Copy the code

End of story, happy GG.