Поддержка веб-компонента Vue не устанавливается через атрибут html

У меня есть веб-компонент vue с числовой опорой, и в результате некоторого тестирования я обнаружил, что выполнение чего-то подобного не работает при установке значения опоры...

<script src = "https://unpkg.com/vue@2"></script>
<script src = "./mycomponents.js"></script>

<my-component myProp = "40"></my-component>

Но это будет...

<script src = "https://unpkg.com/vue@2"></script>
<script src = "./mycomponents.js"></script>

<my-component id = "mycmp"></my-component>

<script type = "module">
const myComponent = document.getElementById("mycmp");
myComponent.myProp = 40;
</script>

Пример кода компонента:

<template>
    <p>{{myProp}}</p>
</template>

<script>
export default {
    name: 'MyComponent',
    props: {
        myProp: {
            type: Number,
            default: 0
        }
    }
}
</script>

Я предполагаю, что это связано с синхронизацией, например, когда вы делаете это через атрибуты html, компонент еще не закончил должным образом инициализироваться? Хотя все примеры, которые я видел о других людях, использующих веб-компоненты vue, казалось, предполагали, что это должен быть довольно простой вариант использования. Надеюсь, это просто я делаю какую-то глупость.

Любая помощь очень ценится!

Атрибуты тега HTML по определению являются строковыми значениями. Свойство вашего компонента должно быть определено как type: [String, Number], а затем везде, где вы обращаетесь к реквизиту, вы должны принудить его к номеру.

IVO GELOV 06.05.2022 14:28

Я не очень хорошо знаком с Vue.js, но не могли бы вы попробовать my-prop = "40" вместо myProp = "40". Он может вести себя так же, как data-* атрибуты, которые должны быть data-my-attr в HTML, но доступны через elm.dataset.myAttr в JavaScript.

3limin4t0r 06.05.2022 15:26

@3limin4t0r спасибо! Вот что это было. Я так привык устанавливать реквизиты компонента, когда он уже находится в контексте vue, то есть родительский компонент устанавливает реквизит дочернего компонента. В этом случае имя свойства можно использовать в html как есть. Похоже, что то же самое неверно при доступе в качестве веб-компонента из обычного html. Спасибо за вашу помощь

JCoyle 06.05.2022 21:17

@IVOGELOV выглядит так, как будто vue на самом деле справляется с приведением значения свойства к числу, я просто не осознавал, что мне нужно использовать кебаб-кейс для имени свойства. Спасибо, но я не знал, что мы можем позволить vue prop принимать массив типов.

JCoyle 06.05.2022 21:19

HTML, на который вы ссылаетесь при использовании имен атрибутов camelCase в ваших компонентах Vue, предварительно обрабатывается компилятором Vue-template-compiler, который вас прощает. Однако браузеры переводят в нижний регистр все имена атрибутов (и не прощают) — и не конвертируют из camelCase в kebab-case.

IVO GELOV 07.05.2022 11:18
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
5
47
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы можете попробовать setAttribute for prop преобразовать его в строку:

<my-component></my-component>

<script type = "module">
  const myComp= document.querySelector("my-component");
  myComp.setAttribute("my-prop", JSON.stringify(40));
</script>

затем в вашем компоненте получите реквизит как строку и преобразуйте его в число (или, если вам нужен объект JSON.parse):

<template>
  <p>{{ myPropNr }}</p>
</template>

props: {
  myProp: {
     type: String,
     default: 0
  }
},
computed: {
  myPropNr() {
    return Number(this.myProp)
  }
}

Если бы я использовал javascript для извлечения элемента, а затем установил реквизит, это уже работало бы в примере, который я привел со своим вопросом. Я больше пытался выяснить, почему установка свойства через атрибут html не работает.

JCoyle 06.05.2022 21:22

@JCoyle Эй, приятель, я думаю, потому что вы можете передавать только строку таким образом, поэтому вы можете использовать JSON.stringify и JSON.parse, чтобы получить что-то другое, чем строка

Nikola Pavicevic 06.05.2022 21:40

Мне было интересно, сделает ли это это, поэтому я добавил в свой код некоторые средства защиты от этого, но похоже, что если вы установите тип свойства как число, тогда vue фактически автоматически выполнит преобразования для вас. Оказалось, что проблема заключалась в том, что мне просто нужно было использовать kebab-case для имени свойства. Таким образом, выполнение чего-то вроде <my-component my-prop = "40"></my-component> теперь работает отлично.

JCoyle 06.05.2022 22:31
Ответ принят как подходящий

Атрибуты HTML часто не совпадают 1 к 1 с JavaScript характеристики. В этом сценарии атрибут HTML для Vue.js перевод свойства аналогичен переводу data-* атрибуты.

Name conversion

dash-style to camelCase conversion

A custom data attribute name is transformed to a key for the DOMStringMap entry by the following:

  1. Lowercase all ASCII capital letters (A to Z);
  2. Remove the prefix data- (including the dash);
  3. For any dash (U+002D) followed by an ASCII lowercase letter a to z, remove the dash and uppercase the letter;
  4. Other characters (including other dashes) are left unchanged.

camelCase to dash-style conversion

The opposite transformation, which maps a key to an attribute name, uses the following:

  1. Restriction: Before transformation, a dash must not be immediately followed by an ASCII lowercase letter a to z;
  2. Add the data- prefix;
  3. Add a dash before any ASCII uppercase letter A to Z, then lowercase the letter;
  4. Other characters are left unchanged.

For example, a data-abc-def attribute corresponds to dataset.abcDef.

Применяя это к вашему сценарию, мы можем пропустить шаг 2 (т. data- часть) и напишите атрибут так:

<my-component my-prop = "40"></my-component>

Другие вопросы по теме