关于javascript:每周总结-20210801-vue文档学习

vue学习

箭头函数

function() => {

}

js地位

JavaScript代码能够间接嵌在网页的任何中央,不过通常咱们都把JavaScript代码放到<head>中;
能够在同一个页面中引入多个.js文件,还能够在页面中屡次编写<script>js代码... </script>,浏览器依照程序顺次执行。

因为浏览器的平安限度,以file://结尾的地址无奈执行如联网等JavaScript代码,最终,你还是须要架设一个Web服务器,而后以http://结尾的地址来失常执行所有JavaScript代码。

js分号

JavaScript并不强制要求在每个语句的结尾加;

数字判断

惟一能判断NaN的办法是通过isNaN()函数

要特地留神相等运算符==。JavaScript在设计时,有两种比拟运算符:
第一种是==比拟,它会主动转换数据类型再比拟,很多时候,会失去十分诡异的后果;
第二种是===比拟,它不会主动转换数据类型,如果数据类型不统一,返回false,如果统一,再比拟。

这不是JavaScript的设计缺点。浮点数在运算过程中会产生误差,因为计算机无法准确示意有限循环小数。要比拟两个浮点数是否相等,只能计算它们之差的绝对值,看是否小于某个阈值:

Math.abs(1 / 3 - (1 - 2 / 3)) < 0.0000001; // true

动静语言与动态语言

变量自身类型不固定的语言称之为动静语言,与之对应的是动态语言。

动静参数

<a v-on:[eventName]="doSomething"> ... </a>

eventName的值为"focus"时,v-on:[eventName]将等价于v-on:focus

v-bind

v-bind:属性,单向绑定?

v-on

事件监听,v-on:click="",简写@click=""
2.6.0新增动静参数,能够依据条件响应不同的事件
须要留神的是,动静表达式中更不要有引号和空格,因为对于html的attribute名来说这些符号有效,同时浏览器会将attribute名转为小写,所以也不要有大写字符

<!-- 变量模式: -->
<template>
    <input @[type?up:down]="event1" id="dynamicParam" name="dynamicParam" type="text">
</template>
<script>
    export default{
        data(){
            return {
                type:false,
                up:'keyup',
                down:'keydown'
            }
        }
    }
</script>
<!-- 计算属性模式: -->
<template>
    <div class="dynamicParamter">    
         <label for="dynamicParam">动静参数</label>
        <input @[type]="event1" id="dynamicParam" name="dynamicParam" type="text">
        <button @click="type1=true">按键</button>
        <button @click="type1=false">键盘抬起</button>
    </div>
</template>
<script>
  export default{
    data(){
      return {
        href:'href',
        url:'',
        type1:null,
      }
    },
    methods:{
      event1(){
        console.log("触发"+(this.type)+'事件')
      }
    },
    computed:{
      type(){
        if(this.type1){
          return 'keyup'
        }else{
          return 'keydown'
        }
      }
    }
  }
</script>

防抖与节流

有些函数如mousemove触发的函数会在短时间内间断调用屡次,如果要使其在一段事件内只执行一次函数,就须要防抖与节流.
防抖:每隔一段事件才触发一次
节流:间断触发后,每隔一段时间才解决一次

//防抖
function debounce(fn, wait) {
 let timeout = null
 return function() {
  if(timeout !== null) clearTimeout(timeout)   
  timeout = setTimeout(fn, wait);
 }
}
function handle() {  
 console.log(Math.random())
}
window.addEventListener('scroll', debounce(handle, 1000))

计算属性

一般来说,模板要求简略的、申明性的,如<span>{{label}}</span>,然而有时会过于简单如:

<span>{{ author.books.length > 0 ? 'Yes' : 'No' }}</span>

尽管代码能够工作,然而过于简单,举荐应用计算属性来申明

<span>{{ publishedBooksMessage }}</span>
computed: {
    // 计算属性的 getter
    publishedBooksMessage() {
        // `this` points to the vm instance
        return this.author.books.length > 0 ? 'Yes' : 'No'
    }
}

计算属性与办法比拟:计算属性在响应式依赖扭转时才会从新求值,而函数在每次调用时都会从新执行

<span>{{ countBooks1() }}</span>
<span>{{ countBools2 }}</span>
methods:{
    countBooks1() {
        return books.length
    }
},
computed:{
    countBooks2() {
        return books.length
    }
}

计算属性能够设置setter和getter

computed: {
  fullName: {
    // getter
    get() {
      return this.firstName + ' ' + this.lastName
    },
    // setter
    set(newValue) {
      const names = newValue.split(' ')
      this.firstName = names[0]
      this.lastName = names[names.length - 1]
    }
  }
}

侦听器watch

能够在响应式数据变动的时候执行函数,相比于计算属性,watch能够执行异步操作如拜访api,然而开销比计算属性大

watch: {
    // whenever question changes, this function will run
    question(newQuestion, oldQuestion) {
        if (newQuestion.indexOf('?') > -1) {
            this.getAnswer()
        }
    }
}

truthiness真值

在js中,除了false0""nullundefinedNaN之外都为真值。

if (true)
if ({})
if ([])
if (42)
if ("foo")
if (new Date())
if (-42)
if (3.14)
if (-3.14)
if (Infinity)
if (-Infinity)

:class

:class="{ active: isActive }"class为isActive值,当isActivenul时,没有class。
此外,:class能够与class属性共存,:class内也能够有多个值,或者应用数组来提供class

<div :class="[activeClass, errorClass]"></div>
data() {
  return {
    activeClass: 'active',
    errorClass: 'text-danger'
  }
}

:style语法

:style的对象语法非常直观——看着十分像CSS,但其实是一个JavaScript对象。CSS property名能够用驼峰式(camelCase)或短横线分隔(kebab-case,记得用引号括起来)来命名

条件渲染

条件渲染有两种:v-ifv-show
v-if只有在条件为真时才渲染条件快,能够和v-else-ifv-else配合应用。
v-show总是会被渲染,虚实值变动体现为css的变动

v-for

能够来对应数组,也能够对应对象
对应数组时,两个参数顺次别离示意值和索引;
对应对象时,三个参数顺次别离示意值、键和索引。

<ul id="array-with-index">
  <li v-for="(item, index) in items">
    {{ parentMessage }} - {{ index }} - {{ item.message }}
  </li>
</ul>
<li v-for="(value, name, index) in myObject">
  {{ index }}. {{ name }}: {{ value }}
</li>

当v-for对应的数据中的数据项扭转了程序,vue不会挪动DOM元素来匹配数据,而是应用“就地更新”的策略,如果想要对应的DOM元素扭转地位,须要增加:key属性

数组更新检测

数组变更

以下函数能够触发视图更新

  • push()
  • pop()
  • shift()
  • unshift()
  • splice()
  • sort()
  • reverse()

    数组替换

    以下函数能够保留原来数组,且返回新的数组

  • filter()
  • concat()
  • slice()

显示过滤、排序数组

能够在v-for中应用计算属性或者办法

在组件上应用v-for

因为组件本人独立的作用域,所以在定义组件的时候要应用props来传递参数。

<div id="todo-list-example">
  <form v-on:submit.prevent="addNewTodo">
    <label for="new-todo">Add a todo</label>
    <input
      v-model="newTodoText"
      id="new-todo"
      placeholder="E.g. Feed the cat"
    />
    <button>Add</button>
  </form>
  <ul>
    <todo-item
      v-for="(todo, index) in todos"
      :key="todo.id"
      :title="todo.title"
      @remove="todos.splice(index, 1)"
    ></todo-item>
  </ul>
</div>
const app = Vue.createApp({
  data() {
    return {
      newTodoText: '',
      todos: [
        {
          id: 1,
          title: 'Do the dishes'
        },
        {
          id: 2,
          title: 'Take out the trash'
        },
        {
          id: 3,
          title: 'Mow the lawn'
        }
      ],
      nextTodoId: 4
    }
  },
  methods: {
    addNewTodo() {
      this.todos.push({
        id: this.nextTodoId++,
        title: this.newTodoText
      })
      this.newTodoText = ''
    }
  }
})

app.component('todo-item', {
  template: `
    <li>
      {{ title }}
      <button @click="$emit('remove')">Remove</button>
    </li>
  `,
  props: ['title']
})

app.mount('#todo-list-example')

事件处理

若在事件处理中要拜访原始的DOM事件,能够用非凡变量$event传入办法

<button @click="warn('Test', $event)">Submit</button>
warn(message, event) {
  if (event) {
    event.preventDefault()
  }
}

一个事件能够有多个办法解决,办法间应用逗号分隔

<button @click="one($event), two($event)">

event.preventDefault() 与 event.stopPropagation()

event.preventDefault()阻止事件的默认动作发送,比方点击勾选框不能切换勾选状态、在input框输出非规定内的字符就无奈输出等等。

event.stopPropagation()仍会执行默认动作,然而执行完后事件不再被分派到其余节点。

js冒泡与捕捉

首先咱们须要造成监听器的思维。在不应用任何框架的状况下,咱们在js中通过addEventListener办法给Dom增加事件监听。这个办法直译就是增加事件监听器。咱们对Dom的操作作为事件会从最里面的先人Dom逐渐传递到指标Dom(捕捉过程),而后再从指标的Dom原路传出去(冒泡过程)。通常咱们只监听冒泡过程。在vue中,当咱们增加了事件修饰符capture后,才会变成捕捉监听器。

所以vue中的.stop修饰符的进行流传就容易了解了,一般来说在冒泡监听时,是有内层的子DOM开始到外层的先人DOM,设置了.stop后,在本DOM处理事件后,事件便不再冒泡。

.self能够了解为跳过冒泡事件和捕捉事件,只有间接作用在该元素上的事件才能够执行。

事件修饰符

  • .stop 执行事件后进行流传
  • .prevent 不执行默认动作,相当于执行event.preventDefault()
  • .capture 由冒泡监听改为捕捉监听
  • .self 跳过冒泡事件和捕捉事件,只有间接作用在该元素上的事件才能够执行
  • .once 只执行一次
  • .passive 不会执行event.preventDefault()

按键修饰符

应用@监听键盘事件

<input @keyup.enter="submit" />
  • .enter
  • .tab
  • .delete (捕捉“删除”和“退格”键)
  • .esc
  • .space
  • .up
  • .down
  • .left
  • .right

润饰键

润饰键与惯例按键不同,只有在按住润饰键的状况下开释其它按键,能力触发事件。而单单开释润饰键也不会触发事件。

<!-- Ctrl + Click -->
<div @click.ctrl="doSomething">Do something</div>

键盘润饰键

  • .ctrl
  • .alt
  • .shift
  • .meta

鼠标润饰键

  • .left
  • .right
  • .middle

.exact 修饰符

.exact 修饰符容许你管制由准确的零碎修饰符组合触发的事件。

<!-- 即便 Alt 或 Shift 被一起按下时也会触发 -->
<button @click.ctrl="onClick">A</button>

<!-- 有且只有 Ctrl 被按下的时候才触发 -->
<button @click.ctrl.exact="onCtrlClick">A</button>

<!-- 没有任何零碎修饰符被按下的时候才触发 -->
<button @click.exact="onClick">A</button>

v-model

对于单选按钮,复选框及抉择框的选项,v-model 绑定的值通常是动态字符串 (对于复选框也能够是布尔值)
v-model有三种修饰符

  • .lazy 在“change”时而非“input”时更新
  • .number 将用户的输出值转为数值类型,如果这个值无奈被 parseFloat() 解析,则会返回原始的值
  • .trim 主动过滤用户输出的首尾空白字符

组件根底

因为组件是可复用的组件实例,所以它们与new Vue接管雷同的选项,例如datacomputedwatchmethods以及生命周期钩子等。通过component能够进行全局注册。

// 定义一个名为 button-counter 的新全局组件
app.component('button-counter', {
  data() {
    return {
      count: 0
    }
  },
  template: `
    <button @click="count++">
      You clicked me {{ count }} times.
    </button>`
})

prop

通过prop定义属性并向子组件传递数据

const app = Vue.createApp({})

app.component('blog-post', {
  props: ['title'],
  template: `<h4>{{ title }}</h4>`
})

app.mount('#blog-post-demo')

监听子组件事件

通过应用$emit来传入内部的事件名称,也能够将外部参数传出。

<div id="blog-posts-events-demo">
  <div v-bind:style="{ fontSize: postFontSize + 'em' }">
    <blog-post 
      v-for="post in posts" 
      :key="post.id" 
      :title="title"
      @enlarge-text="postFontSize += $event"></blog-post>
  </div>
</div>
app.component('blog-post', {
  props: ['title'],
  template: `
    <div class="blog-post">
      <h4>{{ title }}</h4>
      <button @click="$emit('enlarge-text', 0.1)">
        Enlarge text
      </button>
    </div>
  `
})

实现组件的v-model双向绑定

为了在组件中能够应用v-model,组件须要向外暴露出一个承受的prop,并且向内规定该数据的gettersettergettersetter能够通过计算属性实现。

<custom-input v-model="searchText"></custom-input>
app.component('custom-input', {
  props: ['modelValue'],
  template: `
    <input v-model="value">
  `,
  computed: {
    value: {
      get() {
        return this.modelValue
      },
      set(value) { this.$emit('update:modelValue', value)
      }
    }
  }
})

简略插槽

组件中在须要插入的地位应用<slot>标签,在应用组件时间接用组件名标签包裹。

<alert-box>
  Something bad happened.
</alert-box>
app.component('alert-box', {
  template: `
    <div class="demo-alert-box">
      <strong>Error!</strong>
      <slot></slot>
    </div>
  `
})

动静加载组件

应用属性:is能够地将简略组件载入到该地位。

<script src="https://unpkg.com/vue@next"></script>

<div id="dynamic-component-demo" class="demo">
  <button
     v-for="tab in tabs"
     v-bind:key="tab"
     v-bind:class="['tab-button', { active: currentTab === tab }]"
     v-on:click="currentTab = tab"
   >
    {{ tab.name }}
  </button>

  <component
      v-bind:is="currentTab.component"
    ></component>
</div>
const tabs = [
  {
    name: 'Home',
    component: {
      template: `<div class="demo-tab">Home component</div>`
    }
  },
  {
    name: 'Posts',
    component: {
      template: `<div class="demo-tab">Posts component</div>`
    }
  },
  {
    name: 'Archive',
    component: {
      template: `<div class="demo-tab">Archive component</div>`
    }
  }
]

const app = Vue.createApp({
  data() {
    return {
      tabs,
      currentTab: tabs[0]
    }
  },
  computed: {
    currentTabComponent() {
      return 'tab-' + this.currentTab.toLowerCase()
    }
  }
})

app.component('tab-home', {
  template: `<div class="demo-tab">Home component</div>`
})
app.component('tab-posts', {
  template: `<div class="demo-tab">Posts component</div>`
})
app.component('tab-archive', {
  template: `<div class="demo-tab">Archive component</div>`
})

app.mount('#dynamic-component-demo')

非凡DOM解析注意事项

形如<table><select><ul>等等这些标签对于哪些子标签能够呈现在其外部是由严格规定的(比方<tr>能够呈现在<table>中)。而有些标签如<li><tr><option>等只能呈现在特定的元素外部。如果在这些特定标签外部应用自定义的组件,可能会导致出错。此时能够应用v-is属性来帮忙解析组件。

<!-- 谬误 -->
<table>
  <blog-post-row></blog-post-row>
</table>

<!-- 正确 -->
<table>
  <tr v-is="'blog-post-row'"></tr>
</table>

深刻组件

组件命名

倡议应用kebab-case (短横线分隔命名)

部分注册

部分注册须要援用

import ComponentA from './ComponentA.vue'

export default {
  components: {
    ComponentA
  }
  // ...
}

prop类型

prop能够设置类型,在设置谬误时会在控制台提醒用户。

props: {
  title: String,
  likes: Number,
  isPublished: Boolean,
  commentIds: Array,
  author: Object,
  callback: Function,
  contactsPromise: Promise // 或任何其余构造函数
}

动静传入Prop

在传入值时,由两种形式:

<!-- 动态赋值 -->
<blog-post title="My journey with Vue"></blog-post>
<!-- 动静赋予一个变量的值 -->
<blog-post :title="post.title"></blog-post>

动态赋值vue会视为一个字符串,而v-bind或缩写:通知vue这是一个js表达式。

特地地,当一个对象的所有属性都须要传入时,能够应用不带参数的v-bind

post: {
  id: 1,
  title: 'My Journey with Vue'
}
<blog-post v-bind="post"></blog-post>
<!-- 等价于 -->
<blog-post v-bind:id="post.id" v-bind:title="post.title"></blog-post>

单向数据流

咱们曾经晓得,prop中定义内部传入的数据。如果咱们心愿这些数据成为本地数据,能够供子组件应用,并且在数据更新时,子组件也会更新,与此同时反过来不行(会避免从子组件意外变更父级组件的状态,从而导致你的利用的数据流向难以了解)的话,能够将定义在prop中的属性定义为一个data property或者计算属性。

// 定义为data
props: ['initialCounter'],
data() {
  return {
    counter: this.initialCounter
  }
}
// 定义为计算属性
props: ['size'],
computed: {
  normalizedSize: function () {
    return this.size.trim().toLowerCase()
  }
}

prop数据验证

能够定义数据类型、指定默认值和自定义验证规定。

app.component('my-component', {
  props: {
    // 根底的类型查看 (`null` 和 `undefined` 会通过任何类型验证)
    propA: Number,
    // 多个可能的类型
    propB: [String, Number],
    // 必填的字符串
    propC: {
      type: String,
      required: true
    },
    // 带有默认值的数字
    propD: {
      type: Number,
      default: 100
    },
    // 带有默认值的对象
    propE: {
      type: Object,
      // 对象或数组默认值必须从一个工厂函数获取
      default: function() {
        return { message: 'hello' }
      }
    },
    // 自定义验证函数
    propF: {
      validator: function(value) {
        // 这个值必须匹配下列字符串中的一个
        return ['success', 'warning', 'danger'].indexOf(value) !== -1
      }
    },
    // 具备默认值的函数
    propG: {
      type: Function,
      // 与对象或数组默认值不同,这不是一个工厂函数 —— 这是一个用作默认值的函数
      default: function() {
        return 'Default function'
      }
    }
  }
})

非Prop的Attribute继承

非Prop的Attribute,指的是不定义在prop中的属性,如classidstyle等等。在内部应用组件时并应用这些属性时,默认会继承给组件外部的根元素;如果根元素有多个或者想要继承到非根元素,能够应用v-bind="$attrs"$attrs包含组件propsemits property中未蕴含的所有属性 (例如classstylev-on监听器等)。)来选定一个DOM元素继承。

事件监听器的继承也同理,会默认继承到组件外部根元素。

<!-- 具备非prop attribute的Date-picker组件-->
<date-picker data-status="activated"></date-picker>

<!-- 渲染 date-picker 组件 -->
<div class="date-picker" data-status="activated">
  <input type="datetime" />
</div>

须要留神的是,如果要使非根节点继承,须要在组件的选项中设置inheritAttrs: false

app.component('date-picker', {
  inheritAttrs: false,
  template: `
    <div class="date-picker">
      <input type="datetime" v-bind="$attrs" />
    </div>
  `
})
<!-- Date-picker 组件 应用非 prop attribute -->
<date-picker data-status="activated"></date-picker>

<!-- 渲染 date-picker 组件 -->
<div class="date-picker">
  <input type="datetime" data-status="activated" />
</div>

自定义事件

命名举荐应用kebab-case(短横线连贯)的事件名,因为v-on事件监听器在DOM模板中会被主动转换为全小写。自定义事件能够和prop属性一样进行验证。

app.component('custom-form', {
  emits: {
    // 没有验证
    click: null,

    // 验证submit 事件
    submit: ({ email, password }) => {
      if (email && password) {
        return true
      } else {
        console.warn('Invalid submit event payload!')
        return false
      }
    }
  },
  methods: {
    submitForm() {
      this.$emit('submit', { email, password })
    }
  }
})

v-model参数与多个v-model绑定

在组件中,在prop中定义的属性,在内部能够用v-model:属性名的形式来进行多个v-model绑定。

自定义v-model修饰符

在组件中更能够自定义v-model修饰符。然而须要留神的是,修饰符的具体方法是写在属性的setter函数中,并且修饰符的名称为arg + "Modifiers"

<div id="app">
  <my-component v-model:name.capitalize="myText"></my-component>
  {{ myText }}
</div>
const app = Vue.createApp({
  data() {
    return {
      myText: ''
    }
  }
})

app.component('my-component', {
  props: {
    name: String,
    nameModifiers: {
      default: () => ({})
    }
  },
  methods: {
    emitValue(e) {
      let value = e.target.value
      if (this.modelModifiers.capitalize) {
        value = value.charAt(0).toUpperCase() + value.slice(1)
      }
      this.$emit('update:name', value)
    }
  },
  template: `<input
    type="text"
    :value="name"
    @input="emitValue">`
})

app.mount('#app')

插槽

在组件的模板中能够定义<slot>标签,能够替换为字符串、html代码或其余组件。当<slot>标签两头有内容时,这部分内容会作为默认。

<button type="submit">
  <slot>Submit</slot>
</button>

具名插槽

在须要多个插槽的状况下,为了辨认不同的插槽,须要给每一个插槽一个名字name,不带name的插槽会有一个隐含的名字“default”。在内部应用组件的具名插槽的时候,应用<template>v-slot批示插槽名称。留神必须应用v-slot时必须在<template>标签中。

<div class="container">
  <header>
    <slot name="header"></slot>
  </header>
  <main>
    <slot></slot>
  </main>
  <footer>
    <slot name="footer"></slot>
  </footer>
</div>
<base-layout>
  <template v-slot:header>
    <h1>Here might be a page title</h1>
  </template>

  <template v-slot:default>
    <p>A paragraph for the main content.</p>
    <p>And another one.</p>
  </template>

  <template v-slot:footer>
    <p>Here's some contact info</p>
  </template>
</base-layout>

若想让内部拜访组件外部的数据(比方用在插入内容时须要组件外部数据),能够将组件模板中插槽的属性设置为数据。

<slot name="slot1" :item="label"></slot>
<aaa>
  <template v-slot:slot1="slotProps">
    <p>{{slotProps.item}}</p>
  </template>
</aaa>

因为v-slot的值是作为函数参数作用的,所以能够写成任何可能作为函数定义中的参数的JavaScript表达式。

<!-- 重命名参数 -->
<todo-list v-slot="{ item: todo }">
  <i class="fas fa-check"></i>
  <span class="green">{{ todo }}</span>
</todo-list>
<!-- 参数默认值 -->
<todo-list v-slot="{ item = 'Placeholder' }">
  <i class="fas fa-check"></i>
  <span class="green">{{ item }}</span>
</todo-list>

v-slot同样能够应用动静参数<template v-slot:[dynamicSlotName]>

具名插槽的缩写

只有在有参数的状况下才能够缩写,应用#代替v-slot

<todo-list #default="{ item }">
  <i class="fas fa-check"></i>
  <span class="green">{{ item }}</span>
</todo-list>

提供与注入

如果在一个多层嵌套的组件链中,内层的组件要取得外层组件的数据,有两种办法:

第一种是后面讲过的设置prop,然而不不便的是这须要在每一层组件都设置prop,开发上略微有点麻烦;

第二种是父组件提供数据,子组件注入数据的模式,咱们能够应用provideinject对。父组件能够作为其所有子组件的依赖项提供程序,而不论组件层次结构有多深。这个个性有两个局部:父组件有一个provide选项来提供数据,子组件有一个inject选项来开始应用这个数据。

注入的数据默认是非响应式的,如果想要响应式的数据注入,须要调配一个组合式API computed属性。

// 父组件提供
app.component('todo-list', {
  data() {
    return {
      todos: ['Feed a cat', 'Buy tickets']
    }
  },
  provide() {
    return {
      todoLength1: this.todos.length,
      todoLength2: Vue.computed(() => this.todos.length) //响应式
    }
  },
  template: `
    ...
  `
})

app.component('todo-list-statistics', {
  inject: ['todoLength'],
  created() {
    console.log(`Injected property: ${this.todoLength1}`) // > 注入 property: John Doe
  }
})

保活标签keep-alive

在一些场景比方切换标签页中,不停地切换标签页会一直地从新渲染组件。应用保活标签<keep-alive>能够放弃这些组件的状态,以防止重复重渲染导致的性能问题。

<keep-alive>
  <component :is="currentTabComponent"></component>
</keep-alive>

异步组件

不是很懂,目前也临时用不到,等第二次浏览时再细究。

模板援用

如果须要在js中拜访组件,能够应用ref为组件或HTML元素指定援用ID。留神,因为$refs只会在组件渲染实现之后失效,应该防止在模板或计算属性中拜访$refs

<input ref="input" />
const app = Vue.createApp({})

app.component('base-input', {
  template: `
    <input ref="input" />
  `,
  methods: {
    focusInput() {
      this.$refs.input.focus()
    }
  },
  mounted() {
    this.focusInput()
  }
})

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理