Skip to content

Commit

Permalink
feat: 二、数据结构设计与双向绑定实现
Browse files Browse the repository at this point in the history
  • Loading branch information
mengliang.wang committed Feb 5, 2021
1 parent 04656f4 commit 7b6db22
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 2 deletions.
20 changes: 20 additions & 0 deletions src/App.vue
Expand Up @@ -11,6 +11,26 @@ import { VisualEditor } from "../src/packages/visual-editor";
export default defineComponent({
name: "App",
components: { VisualEditor },
data() {
return {
jsonData: {
container: {
height: 500,
width: 800,
},
blocks: [
{
top: 100,
left: 100,
},
{
top: 200,
left: 200,
},
],
},
};
},
});
</script>

Expand Down
46 changes: 46 additions & 0 deletions src/packages/utils/useModel.tsx
@@ -0,0 +1,46 @@
import { computed, defineComponent, ref, watch } from "vue";

// 用jsx封装组件的时候,实现双向数据绑定
export function useModel<T>(getter: () => T, emitter: (val: T) => void) {
const state = ref(getter()) as { value: T };

watch(getter, (val) => {
if (val !== state.value) {
state.value = val;
}
});

return {
get value() {
return state.value;
},
set value(val: T) {
if (state.value !== val) {
state.value = val;
emitter(val);
}
},
};
}

// modelValue 外部可以用v-model绑定
export const TestUseModel = defineComponent({
props: {
modelValue: { type: String },
},
emits: {
"update:modelValue": (val?: string) => true,
},
setup(props, ctx) {
const model = useModel(
() => props.modelValue,
(val) => ctx.emit("update:modelValue", val)
);
return () => (
<div>
自定义输入框
<input type="text" v-model={model.value} />
</div>
);
},
});
13 changes: 11 additions & 2 deletions src/packages/visual-editor.tsx
@@ -1,7 +1,16 @@
import { defineComponent } from "vue";
import { defineComponent, PropType } from "vue";
import "./visual-editor.scss";
import { VisualEditorModelValue } from "./visual-editor.utils";

export const VisualEditor = defineComponent({
props: {},
props: {
modelValue: {
type: Object as PropType<VisualEditorModelValue>,
},
},
emits: {
"update:modelValue": (val?: VisualEditorModelValue) => true,
},
setup(props) {
return () => (
<div class="visual-editor">
Expand Down
12 changes: 12 additions & 0 deletions src/packages/visual-editor.utils.tsx
@@ -0,0 +1,12 @@
export interface VisualEditorBlockData {
top: number;
left: number;
}

export interface VisualEditorModelValue {
container: {
width: number;
height: number;
};
blocks: VisualEditorBlockData[];
}

0 comments on commit 7b6db22

Please sign in to comment.