Skip to content

Commit

Permalink
SVG 控件改为 Vue 组件
Browse files Browse the repository at this point in the history
现在属性可以双向监听了
  • Loading branch information
wherewhere committed Jul 10, 2024
1 parent efe5246 commit 8160e82
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 81 deletions.
6 changes: 3 additions & 3 deletions source/about/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ title: 关于
readme.textContent = "如果这里什么也没有,请";
let link = document.createElement("a");
link.href = "javascript:void(0)";
link.onclick = () => this.loadReadme();
link.onclick = () => this.loadReadmeAsync();
link.textContent = "刷新";
readme.appendChild(link);
readme.append("页面,或者前往这个");
Expand All @@ -38,9 +38,9 @@ title: 关于
readme.append("查看");
this.appendChild(this.message);
this.appendChild(this.readme);
this.loadReadme();
this.loadReadmeAsync();
}
async loadReadme() {
async loadReadmeAsync() {
if (this.isLoading) {
return;
}
Expand Down
169 changes: 91 additions & 78 deletions source/tools/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,14 @@ sitemap: false
</div>
</div>

<template id="value-change-host-template">
<slot></slot>
<template id="empty-slot-template">
<div>
<slot></slot>
</div>
</template>

<template id="svg-host-template">
<div v-html="innerHTML"></div>
</template>

<template id="settings-presenter-template">
Expand Down Expand Up @@ -160,50 +166,47 @@ sitemap: false
createApp({
data() {
return {
isMillisecond: false,
isMillisecond: "false",
timeStamp: Math.floor(Date.now() / 1000),
timeString: new Date().toISOString()
}
},
watch: {
isMillisecond(newValue, oldValue) {
if (newValue !== oldValue) {
this.timeStamp = Math.floor(oldValue ? this.timeStamp / 1000 : this.timeStamp * 1000);
this.timeStamp = Math.floor(oldValue === "true" ? this.timeStamp / 1000 : this.timeStamp * 1000);
}
}
},
methods: {
log(x) {
console.log(x);
},
navigate(src) {
location.href = src;
},
isMillisecond() {
this.isMillisecond === "true";
},
convertTimeStamp() {
const isMillisecond = this.isMillisecond;
const isMillisecond = this.isMillisecond();
const time = Math.floor(isMillisecond ? +this.timeStamp : this.timeStamp * 1000);
this.timeString = new Date(time).toISOString();
},
convertTimeString() {
const isMillisecond = this.isMillisecond;
const isMillisecond = this.isMillisecond();
const time = new Date(this.timeString);
this.timeStamp = isMillisecond ? time.getTime() : Math.floor(time.getTime() / 1000);
},
setDateTimeNow() {
const time = new Date();
const isMillisecond = this.isMillisecond;
const isMillisecond = this.isMillisecond();
this.timeStamp = isMillisecond ? time.getTime() : Math.floor(time.getTime() / 1000);
this.timeString = new Date().toISOString();
},
valueChanged(oldValue, newValue) {
console.log(oldValue, newValue);
}
}
}).component("value-change-host", {
template: "#value-change-host-template",
template: "#empty-slot-template",
props: {
modelValue: null,
valueName: String
valueName: String,
modelValue: String
},
emits: ['update:modelValue'],
watch: {
Expand All @@ -217,37 +220,89 @@ sitemap: false
}
}
}
},
modelValue(newValue, oldValue) {
if (newValue !== oldValue) {
const valueName = this.valueName;
if (valueName) {
const $el = this.$el;
if ($el instanceof HTMLElement) {
const element = $el.children[0];
if (element instanceof HTMLElement) {
element.setAttribute(valueName, newValue);
}
}
}
}
}
},
methods: {
registerObserver(valueName) {
const element = this.$el.nextElementSibling;
if (element instanceof HTMLElement) {
element.setAttribute(valueName, this.modelValue);
this.mutation = new MutationObserver((mutationsList, observer) => {
for (const mutation of mutationsList) {
if (mutation.type === "attributes" && mutation.attributeName === valueName) {
const target = mutation.target;
if (target instanceof HTMLElement) {
const value = target.getAttribute(valueName) === "true";
this.$emit('update:modelValue', value);
const $el = this.$el;
if ($el instanceof HTMLElement) {
const element = $el.children[0];
if (element instanceof HTMLElement) {
element.setAttribute(valueName, this.modelValue);
this.mutation = new MutationObserver((mutationsList, observer) => {
for (const mutation of mutationsList) {
if (mutation.type === "attributes" && mutation.attributeName === valueName) {
const target = mutation.target;
if (target instanceof HTMLElement) {
const value = target.getAttribute(valueName);
this.$emit('update:modelValue', value);
}
}
}
}
}).observe(
element,
{
attributes: true,
attributeFilter: [this.valueName]
}
);
}).observe(
element,
{
attributes: true,
attributeFilter: [this.valueName]
}
);
}
}
}
},
mounted() {
const valueName = this.valueName;
if (!valueName) { return; }
this.registerObserver(valueName);
if (valueName) {
this.registerObserver(valueName);
}
}
}).component("svg-host", {
template: "#svg-host-template",
props: {
src: String
},
data() {
return {
innerHTML: null
}
},
watch: {
src(newValue, oldValue) {
if (newValue !== oldValue) {
this.getSVGAsync(newValue).then(svg => this.innerHTML = svg);
}
}
},
methods: {
async getSVGAsync(src) {
if (src) {
try {
return await fetch(src)
.then(response => response.text());
}
catch (ex) {
console.error(ex);
}
}
return '';
}
},
mounted() {
this.getSVGAsync(this.src).then(svg => this.innerHTML = svg);
}
}).component("settings-presenter", {
template: "#settings-presenter-template"
Expand All @@ -256,48 +311,6 @@ sitemap: false
}).component("settings-expander", {
template: "#settings-expander-template"
}).mount("#vue-app");
if (!customElements.get("svg-host")) {
async function getSVG(src) {
if (src) {
try {
return await fetch(src)
.then(response => response.text());
}
catch (ex) {
console.error(ex);
}
}
return '';
}
class svgHost extends HTMLElement {
static get observedAttributes() {
return ["src"];
}
constructor() {
super();
this.isLoaded = false;
}
get src() {
return this.getAttribute("src");
}
set src(value) {
this.setAttribute("src", value);
}
connectedCallback() {
getSVG(this.src).then(svg => this.innerHTML = svg);
this.isLoaded = true;
}
attributeChangedCallback(name, oldValue, newValue) {
if (!this.isLoaded || oldValue === newValue) { return; }
switch (name) {
case "src":
getSVG(newValue).then(svg => this.innerHTML = svg);
break;
}
}
}
customElements.define("svg-host", svgHost);
}
</script>

<style>
Expand Down

0 comments on commit 8160e82

Please sign in to comment.