函数式组件 vue3/vue2

133 阅读1分钟

app/小程序都不适用 因为无法监听操作dom

vue3写法

js文件
MessageBox为需要调用的组件

// vue3
import { render, createVNode } from "vue";
import MessageBox from "./index";

export default function (options = {}) {
    // 参数判断
    const messageOptions = {}
    if (typeof options === 'string') {
        messageOptions.content = options
    } else if (typeof options === 'object') {
        Object.assign(messageOptions, options)
    }
    // 生成一个MessageBox实例
    const mountNode  = document.createElement("div");
    //命名一个 后面可以依据这个名字删掉dom
    mountNode.setAttribute("name","mustdelete")

    //
    const app = createVNode(MessageBox, messageOptions);
    render(app, mountNode );
    document.body.appendChild(mountNode);
}

vue2写法

js文件
MessageBox为需要调用的组件

import MessageBox from './components/index.vue'

export default {
  install(Vue) {
    Vue.prototype.$toast = options => {
      const toaseOptions = {}

      // 参数判断
      if (typeof options === 'string') {
        toaseOptions.text = options
      } else if (typeof options === 'object') {
        Object.assign(toaseOptions, options)
      }

      // 生成一个toast实例
      const toastConstructor = Vue.extend(MessageBox)
      const instance = new toastConstructor({
        propsData: toaseOptions,
      })
      // 并将此元素插入body中
      const el = instance.$mount().$el
      document.body.appendChild(el)
    }
  },
}

组件写法

如下例子,函数生成组件的时候立即(onMounted)触发组件,在组件生命周期结束时我们要remove掉组件Dom

<template>
  <view>
    <MessageBox ref="messageBoxRef"></MessageBox>
  </view>
</template>

<script setup>
import MessageBox from "./MessageBox.vue";
import { ref, onMounted } from 'vue';
const props = defineProps({
  content: {
    type: String,
    default: "是否确定"
  },
  onConfirm: {
    type: Function,
    default: null
  }
})
const messageBoxRef = ref(null);
function openMessageBox(options = {}) {
  messageBoxRef.value.open(options)
}
// 点击
function toSync() {
  openMessageBox({
    content: props.content,
    onConfirm: props.onConfirm,
    conClose:function () {
      let dom = document.getElementsByName("mustdelete")
      dom[0].remove()
    }
  })
}

onMounted(() => {
  toSync()
})

</script>

使用方法

以vue3写法为例

<template>
    <view>
        <view @click="toSync">打开二次确认...小程序/app都不行,因为不能操作dom</view>
    </view>
</template>

<script setup>
import messageBox from "./components/Vueuse";
import {
    ref
} from 'vue';
// 点击同步
function toSync() {
    messageBox({
        content: '确定?',
        onConfirm: function () {
            console.log("lll");
        }
    })
}
</script>