如何动态调整vue组件中的文本大小

Posted

技术标签:

【中文标题】如何动态调整vue组件中的文本大小【英文标题】:how to dynamically resize text in a vue component 【发布时间】:2021-01-17 14:19:59 【问题描述】:

我已经构建了一个应用程序,其中包含可以放入仪表板的不同小部件。每个小部件都包含一个用户希望看到的组件(有点像 grafana,如果您曾经看过它)。

问题:当用户拖动 grid-item 来增加或减小尺寸时,如何更新我的组件内部的 html 以适应新项目的大小?

我尝试过的:

尝试将 p 标签包装在 SVG 中并使用视口。 尝试将我的尺寸更改为 VW 以按视口动态缩放,但视口不是组件的,而是整个水疗中心的。 我尝试使用 this.$parent 获取父级大小,并进行了一些数学运算以获取文本大小并将其动态分配给组件,但这非常混乱。此外,显示的尺寸也不正确。

下面是我使用 vue-grid-layout 包的网格代码

<grid-layout
  ref="widgetGrid"
  :layout.sync="widgets"
  :col-num="12"
  :row-
  :is-draggable="editable"
  :is-resizable="editable"
  :is-mirrored="false"
  :responsive="true"
  :autoSize="editable"
  :prevent-collision="false"
  :vertical-compact="false"
  :margin="[10, 10]"
  :use-css-transforms="true"
  @layout-updated="layoutUpdatedEvent"
>
  <grid-item
    :ref="`widget_$widget.i`"
    v-for="widget in widgets"
    :key="widget.i"
    :x="widget.x"
    :y="widget.y"
    :w="widget.w"
    :h="widget.h"
    :i="widget.i"
    :static="!editable"
  >
    <template>
      <component
        :is="widget.WidgetType"
        :setup="false"
        :widgetConfig="widget.WidgetConfig"
      ></component>
    </template>
  </grid-item>
</grid-layout>

我正在尝试调整其文本大小的组件如下。这是一个 vue 文件,我已经包含了样式。

<template>
  <div>
    <div id="clock">
      <p class="date"> date </p>
      <p class="time"> time </p>
    </div>
  </div>
</template>

<script>
export default 
  data() 
    return 
      time: '',
      date: '',
      week: ['SUN', 'MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT'],
      ticker: null
    ;
  ,
  created() 
    this.ticker = setInterval(this.updateTime, 1000);
  ,
  mounted() 
    this.showDate =
      this.widgetConfig?.Settings?.find((x) => x.Key === 'ShowDate').Value ||
      false;
    this.showTime =
      this.widgetConfig?.Settings?.find((x) => x.Key === 'ShowTime').Value ||
      false;
  ,
  methods: 
    updateTime() 
      let cd = new Date();
      this.time =
        this.zeroPadding(cd.getHours(), 2) +
        ':' +
        this.zeroPadding(cd.getMinutes(), 2) +
        ':' +
        this.zeroPadding(cd.getSeconds(), 2);

      this.date =
        this.zeroPadding(cd.getFullYear(), 4) +
        '-' +
        this.zeroPadding(cd.getMonth() + 1, 2) +
        '-' +
        this.zeroPadding(cd.getDate(), 2) +
        ' ' +
        this.week[cd.getDay()];
    ,
    zeroPadding(num, digit) 
      let zero = '';
      for (let i = 0; i < digit; i++) 
        zero += '0';
      
      return (zero + num).slice(-digit);
    
  ,
;
</script>

<style lang="scss" scoped>
html,
body 
  height: 100%;

body 
  background: #0f3854!important;
  background: radial-gradient(ellipse at center, #0a2e38 0%, #000000 70%)!important;
  background-size: 100%;

p 
  margin: 0;
  padding: 0;

#clock 
  font-family: 'Share Tech Mono', monospace;
  color: #ffffff;
  text-align: center;
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  color: #daf6ff;
  text-shadow: 0 0 20px rgba(10, 175, 230, 1), 0 0 20px rgba(10, 175, 230, 0);
  .time 
    letter-spacing: 0.05em;
    font-size: 1vw;
    padding: 5px 0;
  
  .date 
    letter-spacing: 0.1em;
    font-size: 1vw;
  
  .text 
    letter-spacing: 0.1em;
    font-size: 1vw;
    padding: 20px 0 0;
  

</style>

Nuxt 配置

module.exports = 
  head: 
    titleTemplate: '',
    title: 'QVue',
    meta: [
       charset: 'utf-8' ,
       name: 'viewport', content: 'width=device-width, initial-scale=1' ,
       hid: 'description', name: 'description', content: 'QVue Web UI' ,
    ],
    link: [ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' ],
  ,
  css: [],
  plugins: [
     src: '@/plugins/vueGrid', s-s-r: false 
  ],
  publicRuntimeConfig: ,
  privateRuntimeConfig: ,
  components: true,
  buildModules: [
    '@nuxtjs/vuetify'
  ],
  modules: [
    '@nuxtjs/axios'
  ],
  axios: 
  ,
  build: 
  ,
  render: 
    compressor: false,
  ,
  srcDir: 'client/',
;

【问题讨论】:

别忘了clearTimeout in destroyed... @MichalLevý 感谢您的推荐! 【参考方案1】:

如果您想调整clock 组件的文本大小,一种解决方案是使用您已经提到的svg -&gt; viewbox。但是你需要使用&lt;text&gt; 而不是&lt;p&gt;

下面是演示:

Vue.component('v-clock',
    template:`
      <svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
        <text x="0" y="25" fill="red">date</text>
        <text x="0" y="75" fill="red">time</text>
      </svg>
    `,
  data() 
    return 
      time: '',
      date: '',
      week: ['SUN', 'MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT'],
      ticker: null
    ;
  ,
  created() 
    this.ticker = setInterval(this.updateTime, 1000);
  ,
  mounted() 
    this.showDate =
      this.widgetConfig?.Settings?.find((x) => x.Key === 'ShowDate').Value ||
      false;
    this.showTime =
      this.widgetConfig?.Settings?.find((x) => x.Key === 'ShowTime').Value ||
      false;
  ,
  methods: 
    updateTime() 
      let cd = new Date();
      this.time =
        this.zeroPadding(cd.getHours(), 2) +
        ':' +
        this.zeroPadding(cd.getMinutes(), 2) +
        ':' +
        this.zeroPadding(cd.getSeconds(), 2);

      this.date =
        this.zeroPadding(cd.getFullYear(), 4) +
        '-' +
        this.zeroPadding(cd.getMonth() + 1, 2) +
        '-' +
        this.zeroPadding(cd.getDate(), 2) +
        ' ' +
        this.week[cd.getDay()];
    ,
    zeroPadding(num, digit) 
      let zero = '';
      for (let i = 0; i < digit; i++) 
        zero += '0';
      
      return (zero + num).slice(-digit);
    
  
)

new Vue (
  el:'#app',
  data () 
    return 
      size: 100
    
  
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<div id="app">
  <input v-model.number="size" type="range" min="50" max="500"/>
  <div :style="width: size + 'px', height: size + 'px'" style="border: solid 1px blue">
    <v-clock></v-clock>
  </div>
</div>

【讨论】:

除了你的展示之外,我还需要做什么才能让 svg 元素在 nuxt 中特别工作。你的建议是我尝试的第一件事。当我使用 vue 开发工具检查它时,我看到所有数据都设置正确并且组件出现,但是当我使用 svg 时没有呈现任何 html 元素。我从字面上复制了您的组件 html 内容并删除了该组件中的所有其他内容。 您可以将您的nuxt.config.js 添加到问题中吗?以及您的终端或浏览器控制台中的任何错误? 控制台没有错误。 Nuxt 配置已添加。 我无法重现您遇到的问题(查看code sandbox)。 我能够实现 vue-grid 包并结合我们的示例使其工作,但遇到了我将处理的其他问题。我认为您提供了正确的答案只是出于某种原因它无法在我的本地 nuxt 服务器上运行,这是我必须弄清楚的。非常感谢今天的帮助!

以上是关于如何动态调整vue组件中的文本大小的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 props 动态挂载 vue 组件

Vue 组件仅在 FirebaseUI 重定向后在控制台悬停、窗口调整大小等时更新

vue中父组件如何动态修改子组件的值?

vue 开发系列 VUE 动态组件的应用

来吧!一文彻底搞定Vue组件!

如何将某个 HTML 中的 Vue 组件添加到另一个 Vue 组件?