npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

w-qn-text

v2.0.12

Published

erhai 前端组件库

Readme

@weier/w-qn-text

  • 商家后台qn-text重构,内部集成 @weier/w-emoji-picker、@weier/w-upload 两个组件
// 安装
npm i @weier/w-qn-text -S

// 代码引入(可选)
import WQnText from "@weier/w-qn-text"

基础用法

常规用法

:::demo

<template>
<div>
  <w-qn-text
    rows="10"
    v-model="qntextVal"
    :simVariableList="simVariableList"
    :variableList="variableList"
    variableType='answer'
    envType='mock'
    @customChange='customChange'
    @selectCustomEmoji='selectCustomEmoji'
    :paginationChange='paginationFn'
    :maxlength="100"
    showWordLimit
  ></w-qn-text>
</div>
</template>
<script>

const urls = [
  'https://healthpro-test.oss-cn-hangzhou.aliyuncs.com/201903301001538299741d3ce4e1fe2d4848b8a569b3d7a698d8.jpg',
  'https://healthpro-test.oss-cn-hangzhou.aliyuncs.com/2019033010113820248946abf1ac344f40f8be926547471c2e89.jpg',
  'https://healthpro-test.oss-cn-hangzhou.aliyuncs.com/20190330100602062502bbe54e45733843bf8d0a508e0098476c.jpg',
  'https://healthpro-test.oss-cn-hangzhou.aliyuncs.com/201903301741011794688ac0fbb72f6440ed9943bc3df2d3b570.jpg',
  'https://healthpro-test.oss-cn-hangzhou.aliyuncs.com/20190414153450623578fbaa279606084b56bfa863528ca08b1c.jpg',
]
const generateImgObj = (src) => {
  const id = src + new Date().getTime()
  return {
    url: src,
    id
  }
}
const imgList = urls.map(src => generateImgObj(src))
export default {
  data(){
    return {
      qntextVal: '',
      simVariableList: [
        { value: '买家昵称', label: 'buyer_nick' },
        { value: '客服昵称', label: 'nick_name' },
        { value: '买家称呼', label: 'buyer_name' },
        { value: '换行符', label: 'line_feed_param' }
      ],
      variableList: [
        { value: '买家昵称', label: 'buyer_nick', modify: true },
        { value: '客服昵称', label: 'nick_name', modify: true },
        { value: '买家称呼', label: 'buyer_name', modify: true },
        { value: '换行符', label: 'line_feed_param', modify: true }
      ]
    }
  },
  methods: {
    customChange(res, callback){
      console.log(res)
      callback()
    },
    selectCustomEmoji(data){
      console.log(data)
    },
    paginationFn(options){
      console.log(options)
      return Promise.resolve({
        list: [...imgList],
        total: 40
      })
    }
  }
}
</script>

:::

variableType不填的情况

当未传 variableType 时,快捷变量无法使用,需要 传递 detectionVariableList 字段 ,以保证 添加变量功能的完整,如果detectionVariableList不传或者传个空数组,则不会展示 添加变量功能

:::demo

<template>
  <w-qn-text
    rows="10"
    v-model="qntextVal"
    :detectionVariableList="variableList"
    envType='mock'
    @customChange='customChange'
    @selectCustomEmoji='selectCustomEmoji'
    :paginationChange='paginationFn'
  ></w-qn-text>
</template>
<script>

const urls = [
  'https://healthpro-test.oss-cn-hangzhou.aliyuncs.com/201903301001538299741d3ce4e1fe2d4848b8a569b3d7a698d8.jpg',
  'https://healthpro-test.oss-cn-hangzhou.aliyuncs.com/2019033010113820248946abf1ac344f40f8be926547471c2e89.jpg',
  'https://healthpro-test.oss-cn-hangzhou.aliyuncs.com/20190330100602062502bbe54e45733843bf8d0a508e0098476c.jpg',
  'https://healthpro-test.oss-cn-hangzhou.aliyuncs.com/201903301741011794688ac0fbb72f6440ed9943bc3df2d3b570.jpg',
  'https://healthpro-test.oss-cn-hangzhou.aliyuncs.com/20190414153450623578fbaa279606084b56bfa863528ca08b1c.jpg',
]
const generateImgObj = (src) => {
  const id = src + new Date().getTime()
  return {
    url: src,
    id
  }
}
const imgList = urls.map(src => generateImgObj(src))
export default {
  data(){
    return {
      qntextVal: '',
      simVariableList: [
        { value: '买家昵称', label: 'buyer_nick' },
        { value: '客服昵称', label: 'nick_name' },
        { value: '买家称呼', label: 'buyer_name' },
        { value: '换行符', label: 'line_feed_param' }
      ],
      variableList: [
        { value: '买家昵称', label: 'buyer_nick', modify: true },
        { value: '客服昵称', label: 'nick_name', modify: true },
        { value: '买家称呼', label: 'buyer_name', modify: true },
        { value: '换行符', label: 'line_feed_param', modify: true }
      ]
    }
  },
  methods: {
    customChange(res, callback){
      console.log(res)
      callback()
    },
    selectCustomEmoji(data){
      console.log(data)
    },
    paginationFn(options){
      console.log(options)
      return Promise.resolve({
        list: [...imgList],
        total: 40
      })
    }
  }
}
</script>

:::

variableType='answer',全插槽自定义模式

:::demo

<template>
  <w-qn-text
    ref="wQnText"
    cols="30"
    rows="10"
    variableType='answer'
    v-model="qntextVal"
    envType='mock'
  >
    <template slot='variableQuick'>
      <el-popover placement="top-start" width="400" trigger="hover" :open-delay="300">
        <div class="customCheckbox">
          <span v-for="item in simVariableList" :key="item.label" class="cone" @click="addVariable(item)">{{ item.value }}</span>
        </div>
        <el-button slot="reference" type="text" style="margin:0 10px;" size="mini">
          插入变量
          <i class="el-icon-caret-top el-icon--right"></i>
        </el-button>
      </el-popover>
    </template>
    <template slot='variableSelect'>
      <el-select v-model="variableSelectValue" @change="addVariable">
        <el-option v-for="item in variableList" :key="item.value" :value="item" :label="item.value"></el-option>
      </el-select>
    </template>
    <template slot='position'>position slot</template>
  </w-qn-text>
</template>
<script>

export default {
  data(){
    return {
      qntextVal: '',
      simVariableList: [
        { value: '买家昵称', label: 'buyer_nick' },
        { value: '客服昵称', label: 'nick_name' },
        { value: '买家称呼', label: 'buyer_name' },
        { value: '换行符', label: 'line_feed_param' }
      ],
      variableList: [
        { value: '买家昵称', label: 'buyer_nick', modify: true },
        { value: '客服昵称', label: 'nick_name', modify: true },
        { value: '买家称呼', label: 'buyer_name', modify: true },
        { value: '换行符', label: 'line_feed_param', modify: true }
      ],
      variableSelectValue: ''
    }
  },
  methods: {
    addVariable(data){
      this.$refs.wQnText.insertVariable(data)
    }
  }
}
</script>

:::

w-qn-text Attributes

| 参数 | 说明 | 类型 | 可选值 | 默认值 | | ---- | ---- | --------- | ---------- | ------- | | value | 输入框内容 | String | —— | '' |
| variableList | 变量列表,下拉框使用 | Array | -- | [] | | filter | 是否需要对特殊字符过滤 | Boolean | -- | false | | simVariableList | 快捷变量列表 | Array | -- | [] | | detectionVariableList | 需要检验的变量列表,气泡弹窗使用 | {paramValue: String, position: Boolean, insertNum: Nunber}[] | -- | [] | | showEmoji | 是否显示表情 | Boolean | -- | true | | showCustomEmoji | 是否显示自定义表情 | Boolean | -- | true | | variableType | 变量类型,如果为'answer',显示变量快捷操作,如果为空显示 气泡变量添加 | String | -- | -- | | stopEnter | 是否支持enter换行 | Boolean | -- | false | | envType | 环境指向 | String | ['mock', 'dev', 'pre', 'prod'] | 'dev' | |customeUploadimagePics|触发上传回调|(e: event) => Promise<string[]>|--| false | | showWordLimit | textarea 文字限制,需要设置 maxlength 生效 | Boolean | -- | false | | | w-emoji-picker 组件参数 | | | | | platform | 平台类型 | String | ['qn', 'wx', 'ks'] | 'qn' | | paginationChange | 自定义表情查询方法(必须返回一个promise) | Function | -- | -- | | emojiList | 额外配置的emoji表情 | { "name": "", "code": "", "miniImg": "", "bigImg": "", "class": "" }[] | -- | [] | | sort | 自定义排序方法 | Function | -- | null | | hoverShowBig | hover显示大表情 | Boolean | -- | false | | | 自动透传 textarea 参数 | | | | | | 自动透传 w-emoji-picker 参数 | | | | | | 自动透传 w-upload 参数 | | | |

  • 注:paginationChange 需要返回一个promise,包含参数 list、total,pageSize可选,如果 pageSize 不返回,将使用默认值 15
  • list返回的 数据格式 {id: String, url: String},id、url 为必须 :::demo
<template>
  <w-qn-text
    rows="10"
    v-model="qntextVal"
    :simVariableList="simVariableList"
    :variableList="variableList"
    envType='mock'
    :paginationChange='paginationFn'
  ></w-qn-text>
</template>
<script>
const urls = [
  'https://healthpro-test.oss-cn-hangzhou.aliyuncs.com/201903301001538299741d3ce4e1fe2d4848b8a569b3d7a698d8.jpg',
  'https://healthpro-test.oss-cn-hangzhou.aliyuncs.com/2019033010113820248946abf1ac344f40f8be926547471c2e89.jpg',
  'https://healthpro-test.oss-cn-hangzhou.aliyuncs.com/20190330100602062502bbe54e45733843bf8d0a508e0098476c.jpg',
  'https://healthpro-test.oss-cn-hangzhou.aliyuncs.com/201903301741011794688ac0fbb72f6440ed9943bc3df2d3b570.jpg',
  'https://healthpro-test.oss-cn-hangzhou.aliyuncs.com/20190414153450623578fbaa279606084b56bfa863528ca08b1c.jpg',
]
const generateImgObj = (src) => {
  const id = src + new Date().getTime()
  return {
    url: src,
    id
  }
}
const imgList = urls.map(src => generateImgObj(src))
export default {
  data(){
    return {
      qntextVal: '',
      simVariableList: [
        { value: '买家昵称', label: 'buyer_nick' },
      ],
      variableList: [
        { value: '买家昵称', label: 'buyer_nick', modify: true },
      ]
    }
  },
  methods: {
    paginationFn(options){
      console.log(options)
      return Promise.resolve({
        list: [...imgList],
        total: 40,
        pageSize: 15
      })
    }
  }
}
</script>

:::

w-qn-text Events

| 事件名称 | 说明 | 参数 | | ---- | ---- | --------- | | selectCustomEmoji | 选择了自定义表情 | { type 类型 emoji、pic, id 图片id, url 图片地址 } | | customChange | 自定义表情变更 | { type 类型,add、delete,data 具体数据源,add情况下 为 添加图片的内容,delete 内部有 ids,为需要删除的图片id } |

w-qn-text Methods

| 方法名 | 说明 | 参数 | | ---- | ---- | --------- | | insertVariable | 插入值到内容区 | { value: 需要插入的值 } |

w-qn-text slots

| 插槽name | 说明 | | default | 默认插槽,在 variableType 不等于 answer的时候使用,在插入变量的按钮之后 |
| position | 位置插槽,在 variableType='answer'的时候使用,使用flex布局,在顶部最右侧 | | variableQuick | 快捷变量插槽,在 variableType='answer' 并且 simVariableLis 长度为0的时候使用 | | variableSelect | 下拉框变量插槽,在 variableType='answer' 并且 variableList 长度为0的时候使用 |

实现思路

  • 接入 w-emoji-picker 组件,来进行实现 emoji表情这块
  • 使用 textarea 来实现多行文本的输入,使用 preventDefault 来阻止 enter 的默认事件
  • 使用 selectionStart 来判断需要插入的位置,ie需要做特殊处理

其他备注

作者:基础建设组-尘寂