error
, а не warning
- меня всегда вымораживает.watch
- это внутренняя особенность Vue, и работает она только на реактивных свойствах. const cookies = Vue.observable({});
(function update(prevString) {
const cookieString = document.cookie;
if (prevString !== cookieString) {
const cookieObject = Object.fromEntries(
cookieString.split(/; */)
.map(
c => c
.split('=', 2)
.map(decodeURIComponent)
)
);
for (const [name, value] of Object.entries(cookies)) {
if (name in cookieObject) {
if (cookieObject[name] === value)
delete cookieObject[name];
} else {
Vue.delete(cookies, name);
}
}
for (const [name, value] of Object.entries(cookieObject)) {
Vue.set(cookies, name, value);
}
}
setTimeout(update, 100, cookieString);
}());
Vue.util.defineReactive(Vue.prototype, '$cookies', cookies);
Теперь можешь делать так this.$watch('$cookies.cookie_name', () => {...})
this.$cookies.cookie_name = 'cookie_value'
- тут уж самостоятельно) Promise.all
:function XMLHttpPromise(method, url, data) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open(method, url);
xhr.onload = () => {
if (xhr.status === 200 && xhr.readyState === 4)
resolve(xhr.responseText);
else
reject("Error");
}
xhr.onerror = xhr.ontimeout = reject;
xhr.send(data);
})
}
Promise.all([
XMLHttpPromise('GET', `style.css`),
XMLHttpPromise('GET', `xmlData.html`)
]).then(([value, secondValue]) => {
console.log(value);
console.log(secondValue);
}).catch(console.error);
Иначе зачем вообще нужны алиасы в ts?
paths
запилили, чтобы отразить поведение модных сборщиков, типа webpack, а не наоборот. Т.е. предполагается, что paths
используются только когда уже есть сборщик который осуществляет всю логику, а не как первичный источник конфигурации. require
, очевидно, исполняется* во время создания(декларации) экспортируемого объекта, задолго до того как этот объект попадёт в Vue и превратится в Vue-компонент.require
, очевидно, исполняется в глобальном контексте, в котором недоступен (какой-либо) this
.<template>
<div>
<component :is="SvgView" class="sp-svg-styles"/>
</div>
</template>
<script>
export default{
props:['name'],
computed: {
SvgView() {
return require('./../Icons/'+this.name+'.svg');
}
}
}
</script>
require
на самом деле работает на этапе компиляции, подготавливая и загружая в бандл все файлы по маске ./../Icons/*.svg
, а на этапе исполнения заменяется внутренней функцией, возвращающей значение по имени. class A {
static bool: boolean = true;
}
class B extends A {
static readonly bool = true;
}
class C extends A {
static readonly bool = false;
}
function func<T extends typeof A, P = T['bool'] extends true ? number : string>(param: P) { }
func<typeof B>(123); //ok
func<typeof B>('random string'); //not ok
func<typeof C>(123); //not ok
func<typeof C>('random string'); //ok
const elementDefaults = {
'welcome': {
placeholder: 'Type welcome message...',
question: '',
isDescription: false,
description: '',
startButtonText: 'Start',
},
'checkbox': {
placeholder: 'Type question or statement...',
question: '',
isDescription: false,
description: '',
options: [] as string[],
multiple: false,
},
'dropdown': {
placeholder: 'Type question here...',
question: '',
isDescription: false,
description: '',
options: [] as string[],
},
'rating': {
placeholder: 'Type question...',
question: '',
isDescription: false,
description: '',
steps: 10,
defaultRate: 0,
shape: 'stars',
},
'text': {
placeholder: 'Type question...',
question: '',
isDescription: false,
description: '',
maxLength: 99999,
},
'slider': {
placeholder: 'Type question...',
question: '',
isDescription: false,
description: '',
steps: 10,
},
'thanks': {
placeholder: 'Type message...',
question: '',
isDescription: false,
description: '',
}
}
export function getElementSettings<E extends keyof typeof elementTypes>(type: E) {
if(!(type in elementDefaults)) throw new Error("element type doesn't match!");
return elementDefaults[type];
}
type ElementSetting = {
placeholder: string;
question: string;
isDescription: boolean;
description: string;
}
type ElementSettings = {
welcome: ElementSetting & {
startButtonText: string;
},
checkbox: ElementSetting & {
options: string[];
multiple: boolean;
},
dropdown: ElementSetting & {
options: string[];
},
rating: ElementSetting & {
steps: number;
defaultRate: number;
shape: string;
},
text: ElementSetting & {
maxLength: number;
},
slider: ElementSetting & {
steps: number;
},
thanks: ElementSetting
}
const elementDefaults: ElementSettings = {
'welcome': {
placeholder: 'Type welcome message...',
question: '',
isDescription: false,
description: '',
startButtonText: 'Start',
},
'checkbox': {
placeholder: 'Type question or statement...',
question: '',
isDescription: false,
description: '',
options: [],
multiple: false,
},
'dropdown': {
placeholder: 'Type question here...',
question: '',
isDescription: false,
description: '',
options: [],
},
'rating': {
placeholder: 'Type question...',
question: '',
isDescription: false,
description: '',
steps: 10,
defaultRate: 0,
shape: 'stars',
},
'text': {
placeholder: 'Type question...',
question: '',
isDescription: false,
description: '',
maxLength: 99999,
},
'slider': {
placeholder: 'Type question...',
question: '',
isDescription: false,
description: '',
steps: 10,
},
'thanks': {
placeholder: 'Type message...',
question: '',
isDescription: false,
description: '',
}
}
export function getElementSettings<E extends keyof ElementSettings>(type: E): ElementSettings[E] {
if(!(type in elementDefaults)) throw new Error("element type doesn't match!");
return elementDefaults[type];
}
viewBox
, то и координаты будут те же:<svg width="14" height="12" viewBox="0 0 14 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<polyline points="2,5.75 5.75,10.75 12,2" fill="none" stroke="#1E2321" />
</svg>
viewBox
- это размер координатной сетки, и координаты должны ему, очевидно, соответствовать.