vue#watch JavaScript Examples

The following examples show how to use vue#watch. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: createDirective.js    From fes.js with MIT License 6 votes vote down vote up
export default function createDirective(useAccess) {
    return {
        beforeMount(el) {
            const ctx = {};
            ctx.watch = (path) => {
                el._display = el._display || el.style.display;
                const access = useAccess(path);
                setDisplay(el, access);
                return watch(access, () => {
                    setDisplay(el, access);
                });
            };
            cache.set(el, ctx);
        },
        mounted(el, binding) {
            const ctx = cache.get(el);
            if (ctx.unwatch) {
                ctx.unwatch();
            }
            ctx.unwatch = ctx.watch(binding.value);
        },
        updated(el, binding) {
            const ctx = cache.get(el);
            if (ctx.unwatch) {
                ctx.unwatch();
            }
            ctx.unwatch = ctx.watch(binding.value);
        },
        beforeUnmount(el) {
            const ctx = cache.get(el);
            if (ctx.unwatch) {
                ctx.unwatch();
            }
        }
    };
}
Example #2
Source File: entry-client.js    From vitedge with MIT License 6 votes vote down vote up
export function usePageProps() {
  const { meta = {} } = useRoute() || {}

  // Props reactivity in dev
  if (import.meta.env.DEV) {
    const pageProps = shallowReactive(meta.state || {})

    watch(meta.hmr, () => {
      for (const key of Object.keys(pageProps)) {
        delete pageProps[key]
      }

      Object.assign(pageProps, meta.state || {})
    })

    return shallowReadonly(pageProps)
  }

  return shallowReadonly(meta.state || {})
}
Example #3
Source File: useChartResize.js    From ant-simple-pro with MIT License 6 votes vote down vote up
export function useChartResize(chartIns) {
  function onResize() {
    chartIns.value && chartIns.value.resize()
  }

  let timer = null

  watch(
    () => store.getters.collapsed,
    () => {
      timer = window.setTimeout(() => {
        onResize()
      }, 500)
    }
  )

  onMounted(() => {
    window.addEventListener('resize', onResize)
  })

  onBeforeUnmount(() => {
    window.removeEventListener('resize', onResize)
    timer && clearTimeout(timer)
  })
}
Example #4
Source File: useSpeechRecognition.js    From javascript-mini-projects with The Unlicense 5 votes vote down vote up
export default function useSpeechRecognition() {
  const isListening = ref(false);
  const note = ref("");
  const error = ref(null);

  const handleListen = () => {
    if (isListening.value) {
      recognition.start();
    } else {
      recognition.stop();
    }
  };

  const toggleListening = () => {
    isListening.value = !isListening.value;
  };

  recognition.onresult = (event) => {
    const transcript = Array.from(event.results)
      .map((result) => result[0])
      .map((result) => result.transcript)
      .join("");

    note.value = transcript;
  };

  recognition.onerror = (event) => {
    error.value = event.error;
  };

  watch(isListening, () => {
    handleListen();
  });

  return {
    toggleListening,
    note,
    error
  };
}
Example #5
Source File: useDarkMode.js    From website with MIT License 5 votes vote down vote up
export default function useDarkMode() {
	const isDarkMode = ref(false);

	const updateDarkModeClass = (value = isDarkMode.value) => {
		// set `class="dark"` on `<html>` element
		const htmlEl = window?.document.querySelector('html');
		htmlEl?.classList.toggle('dark', value);

		const systemDarkMode = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;

		if ((value && systemDarkMode) || (!value && !systemDarkMode)) {
			localStorage.removeItem('guide-color-scheme');
		} else if (value && !systemDarkMode) {
			localStorage.setItem('guide-color-scheme', 'dark');
		} else if (!value && systemDarkMode) {
			localStorage.setItem('guide-color-scheme', 'light');
		}
	}

	const mediaQuery = ref < MediaQueryList | null > (null)
	const onMediaQueryChange = (event) => {
		isDarkMode.value = event.matches;
	};

	onMounted(() => {
		// get stored preference and `prefers-color-scheme` media query and set the initial mode
		const userMode = localStorage.getItem('guide-color-scheme');
		mediaQuery.value = window.matchMedia('(prefers-color-scheme: dark)');
		isDarkMode.value = userMode === 'dark' || (userMode !== 'light' && mediaQuery.value.matches);

		// watch changes
		mediaQuery.value.addEventListener('change', onMediaQueryChange);
		watch(isDarkMode, updateDarkModeClass, { immediate: true });
	});

	onUnmounted(() => {
		mediaQuery.value?.removeEventListener('change', onMediaQueryChange);
	});

	return {
		isDarkMode,
	};
}
Example #6
Source File: use-auto-theme.js    From konsta with MIT License 5 votes vote down vote up
useAutoTheme = (props, autoThemeDetection = true) => {
  const themeState = ref(props.theme);

  /* eslint-disable no-restricted-globals */
  const setTheme = (newTheme) => {
    if (newTheme === 'ios' || newTheme === 'material') {
      if (themeState.value !== newTheme) {
        themeState.value = newTheme;
      }
    } else if (
      autoThemeDetection &&
      themeState.value === 'parent' &&
      typeof window !== 'undefined' &&
      typeof document !== 'undefined'
    ) {
      const htmlEl = document.documentElement;
      if (htmlEl) {
        if (htmlEl.classList.contains('ios')) {
          themeState.value = 'ios';
        } else if (
          htmlEl.classList.contains('md') ||
          htmlEl.classList.contains('material')
        ) {
          themeState.value = 'material';
        }
      }
    }
  };
  /* eslint-enable no-restricted-globals */

  watch(
    () => props.theme,
    (newTheme) => {
      setTheme(newTheme);
    }
  );
  onMounted(() => {
    setTheme(props.theme);
  });

  return themeState;
}
Example #7
Source File: useHotkeys.js    From ant-simple-pro with MIT License 5 votes vote down vote up
export function useHotkeys(keys, callback, options, deps) {
  if (Array.isArray(options)) {
    deps = options || []
    options = undefined
  }
  const elRef = ref()
  const {
    enableOnTags,
    filter,
    keyup,
    keydown,
    filterPreventDefault = true,
    enabled = true,
    enableOnContentEditable = false
  } = options || {}

  function keyHandler(keyboardEvent, hotkeysEvent) {
    if (filter && !filter(keyboardEvent)) {
      return !filterPreventDefault
    }

    // Check whether the hotkeys was triggered inside an input and that input is enabled or if it was triggered by a content editable tag and it is enabled.
    if (
      (isKeyboardEventTriggeredByInput(keyboardEvent) && !tagFilter(keyboardEvent, enableOnTags)) ||
      (keyboardEvent.target?.isContentEditable && !enableOnContentEditable)
    ) {
      return true
    }

    if (!elRef.value || document.activeElement === elRef.value) {
      callback(keyboardEvent, hotkeysEvent)
      return true
    }

    return false
  }

  function setHotKeys() {
    if (!enabled) {
      return
    }

    // In this case keydown is likely undefined, so we set it to false, since hotkeys needs the `keydown` key to have a value.
    if (keyup && keydown !== true) {
      options.keydown = false
    }

    hotkeys(keys, options || {}, keyHandler)
  }

  onMounted(() => {
    setHotKeys()
  })

  onUnmounted(() => {
    hotkeys.unbind(keys, keyHandler)
  })

  watch(deps ? deps.map(v => () => v) : [], () => { // eslint-disable-line
    setHotKeys()
  })

  watch([() => options, () => keys, () => enabled], () => {
    setHotKeys()
  })

  return elRef
}
Example #8
Source File: vue3-highcharts.js    From vue3-highcharts with MIT License 5 votes vote down vote up
vueHighcharts = defineComponent({
  name: 'VueHighchart',
  props: {
    type: {
      type: String,
      default: 'chart',
    },

    options: {
      type: Object,
      required: true,
    },

    redrawOnUpdate: {
      type: Boolean,
      default: true,
    },

    oneToOneUpdate: {
      type: Boolean,
      default: false,
    },

    animateOnUpdate: {
      type: Boolean,
      default: true,
    },
  },

  setup(props, { emit }) {
    const chartRef = ref(null);
    const chart = ref(null);

    const { options } = toRefs(props);

    if (options.value && Highcharts[props.type]) {
      watch(options, (newValue) => {
        if (chart.value) {
          chart.value.update(newValue, props.redrawOnUpdate, props.oneToOneOnUpdate, props.animateOnUpdate);
          emit('updated');
        }
      }, { deep: true });

      onMounted(() => {
        chart.value = Highcharts[props.type](chartRef.value, options.value, () => {
          emit('rendered');
        });
      });

      onUnmounted(() => {
        if (chart.value) chart.value.destroy();
        emit('destroyed');
      });
    } else if (!props.options) {
      console.warn('The "options" parameter is required.');
    } else {
      console.warn(`${props.type} is not a valid highcharts type or has not been imported`);
    }

    // Rather than returning a render function here. We'll return the chart ref and highcharts
    // instance so there exposed.
    return {
      chartRef,
      chart,
    };
  },

  render() {
    return h('div', {
      class: 'vue-highcharts',
      ref: 'chartRef',
    });
  },
})
Example #9
Source File: s3mlayer-style.js    From vue-iClient3D_for_Cesium with Apache License 2.0 4 votes vote down vote up
//语言资源

function s3mlayerStyle(props) {

    // 设置默认值数据
    let state = reactive({
        layerNames: [],   //当前存在的可选择s3m图层
        selectedLayerName: 'none',  //默认选择图层名称
        foreColor: "#ffffff",  //前景色
        lineColor: "rgba(27, 27, 27, 1)",  //线颜色
        selectedColor: "#A40FF4",  //选中色
        selectColorMode: 'mix',  //选中色模式
        bottomAltitude: 0,  //底部高程
        LODScale: 5,  //LOD
        layerTrans: 1,  //图层透明度
        fillStyle: 'fill',//填充风格
        visibleDistanceMin: 0,  //最小可见距离
        visibleDistanceMax: 10000,  //最大可见距离
    })

    // 传入props改变默认值
    if (props) {
        for (let key in props) {
            if (state.hasOwnProperty(key)) {
                state[key] = props[key]
            } else {
                tool.Message.errorMsg(resource.AttributeError + key);
            }
        }
    }

    // 初始化数据
    let layers, scene, selectedLayer;


    if (storeState.isViewer) {
        getLayerNames();
    }
    //viewer 初始化完成的监听
    watch(() => storeState.isViewer, val => {
        if (val) {
            getLayerNames();
        }
    });

    //监听图层加载完成
    watch(() => storeState.changeLayers, val => {
        getLayerNames();
    });

    //初始化图层
    function getLayerNames() {
        scene = viewer.scene;
        layers = viewer.scene.layers.layerQueue;
        if (layers && layers.length > 0) {
            layers.forEach((element, index) => {
                if (!state.layerNames.includes(element._name)) {
                    state.layerNames.push(element._name);
                }
            });
            if (state.selectedLayerName = 'none') {
                state.selectedLayerName = state.layerNames[0];
                selectedLayer = layers[0];
            }
        }
    }


    // 销毁
    onBeforeUnmount(() => {
        layers = scene = null;
    });


    // 监听
    watch(() => state.selectedLayerName, val => {
        let index = state.layerNames.indexOf(val)
        if (index == -1) return;
        selectedLayer = layers[index];
    });
    watch(() => state.foreColor, val => {
        if (selectedLayer)
            selectedLayer.style3D.fillForeColor = Cesium.Color.fromCssColorString(
                val
            );
    });
    watch(() => state.lineColor, val => {
        if (selectedLayer)
            selectedLayer.style3D.lineColor = Cesium.Color.fromCssColorString(
                val
            );
    });
    watch(() => state.selectedColor, val => {
        if (selectedLayer)
            selectedLayer.selectedColor = Cesium.Color.fromCssColorString(
                val
            );
    });
    watch(() => state.selectColorMode, val => {
        if (selectedLayer)
            selectedLayer.selectColorType = val === 'mix' ? 0 : 1;
    });
    watch(() => state.bottomAltitude, val => {
        if (selectedLayer)
            selectedLayer.style3D.bottomAltitude = Number(val);
        selectedLayer.refresh();
    });
    watch(() => state.fillStyle, val => {
        if (selectedLayer)
            switch (val) {
                case "fill":
                    selectedLayer.style3D.fillStyle = Cesium.FillStyle.Fill;
                    break;
                case "wireframe":
                    selectedLayer.style3D.fillStyle = Cesium.FillStyle.WireFrame;
                    selectedLayer.style3D.lineColor = Cesium.Color.fromCssColorString(
                        state.lineColor
                    );
                    break;
                case "fill-and-wireframe":
                    selectedLayer.style3D.fillStyle =
                        Cesium.FillStyle.Fill_And_WireFrame;
                    selectedLayer.style3D.lineColor = Cesium.Color.fromCssColorString(
                        state.lineColor
                    );
                    break;
                default:
                    break;
            }
        selectedLayer.refresh();
    });
    watch(() => state.LODScale, val => {
        if (selectedLayer)
            selectedLayer.lodRangeScale = Number(val);
    });
    watch(() => state.layerTrans, val => {
        if (selectedLayer)
            selectedLayer.style3D.fillForeColor.alpha = Number(val);
    });
    watch(() => state.visibleDistanceMin, val => {
        if (val == "") {
            val = 0.0;
        }
        if (selectedLayer)
            selectedLayer.visibleDistanceMin = Number(val);
    });

    watch(() => state.visibleDistanceMax, val => {
        if (val == "") {
            val = this.maxNumber;
        }
        if (selectedLayer)
            selectedLayer.cullEnabled = val;
        selectedLayer.visibleDistanceMax = Number(val);

    });



    return {
        ...toRefs(state),
    };
}
Example #10
Source File: index.js    From vue-json-schema-form with Apache License 2.0 4 votes vote down vote up
export default function createForm(globalOptions = {}) {
    const Form = {
        name: 'VueForm',
        props: vueProps,
        emits: ['update:modelValue', 'change', 'cancel', 'submit', 'validation-failed', 'form-mounted'],
        setup(props, { slots, emit }) {
            // global components
            const internalInstance = getCurrentInstance();
            if (!Form.installed && globalOptions.WIDGET_MAP.widgetComponents) {
                Object.entries(globalOptions.WIDGET_MAP.widgetComponents).forEach(
                    ([componentName, component]) => internalInstance.appContext.app.component(componentName, component)
                );

                // 只注册一次
                Form.installed = true;
            }

            // 使用provide 传递跨组件数据
            provide('genFormProvide', computed(() => ({
                fallbackLabel: props.fallbackLabel
            })));

            // rootFormData
            const rootFormData = ref(getDefaultFormState(props.schema, props.modelValue, props.schema, props.strictMode));
            const footerParams = computed(() => ({
                show: true,
                okBtn: '保存',
                okBtnProps: {},
                cancelBtn: '取消',
                ...props.formFooter
            }));

            // form组件实例,不需要响应式
            let formRef = null;

            // 更新formData
            const emitFormDataChange = (newValue, oldValue) => {
                // 支持v-model ,引用类型
                emit('update:modelValue', newValue);

                // change 事件,引用类型修改属性 newValue
                emit('change', {
                    newValue,
                    oldValue
                });
            };

            // 更新props
            const willReceiveProps = (newVal, oldVal) => {
                if (!deepEquals(newVal, oldVal)) {
                    const tempVal = getDefaultFormState(props.schema, props.modelValue, props.schema, props.strictMode);
                    if (!deepEquals(rootFormData.value, tempVal)) {
                        rootFormData.value = tempVal;
                    }
                }
            };

            // emit v-model,同步值
            watch(rootFormData, (newValue, oldValue) => {
                emitFormDataChange(newValue, oldValue);
            }, {
                deep: true
            });

            // schema 被重新赋值
            watch(() => props.schema, (newVal, oldVal) => {
                willReceiveProps(newVal, oldVal);
            });

            // model value 变更
            watch(() => props.modelValue, (newVal, oldVal) => {
                willReceiveProps(newVal, oldVal);
            });

            // 保持v-model双向数据及时性
            emitFormDataChange(rootFormData.value, props.modelValue);

            const getDefaultSlot = () => {
                if (slots.default) {
                    return slots.default({
                        formData: rootFormData,
                        formRefFn: () => formRef
                    });
                }

                if (footerParams.value.show) {
                    return h(FormFooter, {
                        globalOptions,
                        okBtn: footerParams.value.okBtn,
                        okBtnProps: footerParams.value.okBtnProps,
                        cancelBtn: footerParams.value.cancelBtn,
                        formItemAttrs: footerParams.value.formItemAttrs,
                        onCancel() {
                            emit('cancel');
                        },
                        onSubmit() {
                            // 优先获取组件 $$validate 方法,方便对 validate方法转换
                            (formRef.$$validate || formRef.validate)((isValid, resData) => {
                                if (isValid) {
                                    return emit('submit', rootFormData);
                                }
                                console.warn(resData);
                                return emit('validation-failed', resData);
                            });
                        }
                    });
                }

                return [];
            };

            return () => {
                const {
                    // eslint-disable-next-line no-unused-vars
                    layoutColumn = 1, inlineFooter, labelSuffix, isMiniDes, defaultSelectFirstOption, ...uiFormProps
                } = props.formProps;

                const { inline = false, labelPosition = 'top' } = uiFormProps;

                const schemaProps = {
                    schema: props.schema,
                    uiSchema: props.uiSchema,
                    errorSchema: props.errorSchema,
                    customFormats: props.customFormats,
                    customRule: props.customRule,
                    rootSchema: props.schema,
                    rootFormData: rootFormData.value, // 根节点的数据
                    curNodePath: '', // 当前节点路径
                    globalOptions, // 全局配置,差异化ui框架
                    formProps: {
                        labelPosition,
                        labelSuffix: ':',
                        defaultSelectFirstOption: true,
                        inline,
                        ...props.formProps
                    }
                };

                return h(
                    resolveComponent(globalOptions.COMPONENT_MAP.form),
                    {
                        class: {
                            genFromComponent: true,
                            formInlineFooter: inlineFooter,
                            formInline: inline,
                            [`genFromComponent_${props.schema.id}Form`]: !!props.schema.id,
                            layoutColumn: !inline,
                            [`layoutColumn-${layoutColumn}`]: !inline
                        },
                        setFormRef: (form) => {
                            formRef = form;
                            internalInstance.ctx.$$uiFormRef = formRef;

                            emit('form-mounted', form, {
                                formData: rootFormData.value
                            });
                        },
                        // 阻止form默认submit
                        onSubmit(e) {
                            e.preventDefault();
                        },
                        model: rootFormData,
                        labelPosition,
                        inline,
                        ...uiFormProps
                    },
                    {
                        default: () => [
                            h(
                                SchemaField,
                                schemaProps
                            ),
                            getDefaultSlot(),
                        ]
                    }
                );
            };
        },
    };

    Form.install = (vueApp, options = {}) => {
        vueApp.component(options.name || Form.name, Form);
    };

    return Form;
}
Example #11
Source File: clip-plane2.js    From vue-iClient3D_for_Cesium with Apache License 2.0 4 votes vote down vote up
//简单局部状态管理

function clipPlaneAnalysis(props) {
    // 设置默认值数据
    let state = reactive({
        isEdit: false,//是否编辑
        isEditZ: false,
        lineVisible: true,//是否显示绘制线
        PlanePositions: []
    });

    // 传入props改变默认值
    if (props) {
        for (let key in props) {
            if (state.hasOwnProperty(key)) {
                state[key] = props[key]
            } else {
                tool.Message.errorMsg(resource.AttributeError + key);
            }
        }
    }

    // 初始化数据
    let layers;
    let planePosition = [];

    /*
     ***平面分析模块***
    */

    //初始化分析区域 (后面有需要可以添加监听)
    if (props && props.PlanePositions) {
        clipPolygonUpdate(props.PlanePositions);
    }
    if (storeState.isViewer) {
        layers = viewer.scene.layers.layerQueue;
        if (!window.tooltip) {
            window.tooltip = createTooltip(viewer._element);
        }
    }
    //viewer 初始化完成的监听
    watch(() => storeState.isViewer, val => {
        if (val) {
            layers = viewer.scene.layers.layerQueue;
            if (!window.tooltip) {
                window.tooltip = createTooltip(viewer._element);
            }
        }
    })
    // 分析
    function clipPlaneStart(e) {
        e.preventDefault();
        tooltip.setVisible(false);
        tooltip.showAt(' <p>点击鼠标左键开始绘制</p><p>绘制三点确定一个平面</p><p>点击鼠标右键结束绘制</p>', '230px');
        if (!layers ) {
            layers = viewer.scene.layers.layerQueue;
        }
        for (let layer of layers) {
            layer.selectEnabled = false;
            // 设置被裁剪对象的颜色
            layer.clipLineColor = new Cesium.Color(1, 1, 1, 0);
        }
        // if (!window.handlerPolygon) {
        //     initHandler("Polygon");
        // }
        // handlerDrawing("Polygon", state.lineVisible).then(
        //     res => {
        //         let position = res.result.object.positions;
        //         clipPlaneUpdate(position);
        //         // handlerPolygon.polygon.show = false;
        //         // handlerPolygon.polyline.show = false;
        //         window.handlerPolygon.deactivate();
        //         tooltip.setVisible(false);
        //         if (state.isEdit) {
        //             Edit(planePosition, state.isEditZ, clipPlaneUpdate);
        //         }
        //     },
        //     err => {
        //         console.log(err);
        //     }
        // );

        if (!scene.pickPositionSupported) {
            alert("不支持深度纹理,无法绘制多边形,裁剪功能无法使用!");
        }
    };
    // 更新
    function clipPlaneUpdate(p) {
        planePosition = p;
        for (let layer of layers) {
            layer.clearCustomClipBox();
            layer.setCustomClipPlane(
                p[0],
                p[1],
                p[2]
            );
        }
    };

    // 清除
    function clearClipPlane(e) {
        e.preventDefault();
        tooltip.setVisible(false);
        planePosition = [];
        if (!window.handlerPolygon) return;
        clearHandlerDrawing("Polygon");
        for (let layer of layers) {
            layer.clearCustomClipBox();
        }
    };

    var handler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
    let arr = []
    let left_click = false;
    handler.setInputAction(function(e){
        var position = e.position; // 获取鼠标屏幕坐标
        var centerPosition = viewer.scene.pickPosition(position);
        arr[0] = centerPosition;
        left_click = true
        test()
       
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

    handler.setInputAction(function(e){
        if(left_click){
            var endPosition = viewer.scene.pickPosition(e.endPosition);
            arr[1] = endPosition
            
        }
    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
    handler.setInputAction(function(e){
        left_click = false;
        let obj = Cesium.Rectangle.fromCartesianArray(arr)
        let southeast = Cesium.Rectangle.southeast(obj) 
        let southwest = Cesium.Rectangle.southwest(obj) 
        let northwest = Cesium.Rectangle.northwest(obj) 
        let northeast = Cesium.Rectangle.northeast(obj) 
        let arr2 = [southeast,southwest,northwest,northeast];
        let arr4 = []
        arr2.forEach((p)=>{
            let arr3 = tool.CartographictoDegrees(p);
            arr4 =  arr4.concat(arr3)
        })
        console.log(arr4)
        clipPolygonUpdate(arr4)

    }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
    let shape
    function test(){
        shape = viewer.entities.add({
            name: 'Blue translucent, rotated, and extruded ellipse with outline',
            rectangle : {
                coordinates :  new Cesium.CallbackProperty(function () {
                    var obj=Cesium.Rectangle.fromCartesianArray(arr);
                    return obj;
                }, false),
                material : Cesium.Color.YELLOW.withAlpha(0.2),
                // height:Cesium.Cartographic.fromCartesian(arr[0]).height
            },
            classificationType: Cesium.ClassificationType.S3M_TILE, //面贴对象
        });

    }

        // 更新
        function clipPolygonUpdate(p) {
            for (let layer of layers) {
                layer.setModifyRegions([p], Cesium.ModifyRegionMode.CLIP_OUTSIDE);
            }
        };

    // 监听

    watch(() => state.isEdit, val => {
        if (val && window.handlerPolygon) {
            Edit(planePosition, state.isEditZ, clipPlaneUpdate);
        } else {
            clearEditHandler("Polygon");
            if (window.handlerPolygon && window.handlerPolygon.polygon) {
                window.handlerPolygon.polygon.show = false;
            }
        }
    });
    watch(() => state.isEditZ, val => {
        if (window.editHandler) {
            window.editHandler.isEditZ = val;
        }
    });


    // 销毁
    onBeforeUnmount(() => {
        layers = undefined;
    })

    return {
        ...toRefs(state),
        clipPlaneStart,
        clearClipPlane,
        planePosition
    };
}