Javascript 使用条件呈现时未注册Vue 2-@单击事件回调

Javascript 使用条件呈现时未注册Vue 2-@单击事件回调,javascript,vue.js,svg,vuejs2,Javascript,Vue.js,Svg,Vuejs2,我最近遇到了在svg按钮上注册事件回调的问题。我想有条件地呈现按钮,但我的@click事件回调未注册。即使条件最初为真,也会发生这种情况。卸下v-if使一切正常。这应该发生吗?这方面的解决办法是什么 注意:如果我不使用showControls变量,而只提供v-if=true,它似乎可以工作 以下是我的组件代码: <template> <div id="svg-container" class="svg-container">

我最近遇到了在svg按钮上注册事件回调的问题。我想有条件地呈现按钮,但我的@click事件回调未注册。即使条件最初为真,也会发生这种情况。卸下v-if使一切正常。这应该发生吗?这方面的解决办法是什么

注意:如果我不使用
showControls
变量,而只提供
v-if=true
,它似乎可以工作

以下是我的组件代码:

<template>
  <div id="svg-container" class="svg-container">

    <svg id="svg-canvas-outer" viewBox="0 0 1000 1000">
      <svg id="svg-canvas-inner" :viewBox="viewBox">
        <slot id="svg-content"></slot>
      </svg>

      <g transform="translate(30,30)" v-if="showControls"> <!-- using conditional rendering here breaks my @click callbacks --> 
        <g class="svg-button btn btn-primary" @click="zoomIn"> <!-- zoomIn not called when conditionally rendering-->
          <circle class="button" cx="0" cy="0" r="20"/>
          <path d="M 0 10 H 10 V 0 H 20 V 10 H 30 V 20 H 20 V 30 H 10 V 20 H 0 Z" fill="white"
                transform="translate(-15,-15)"/>
        </g>
        <g class="svg-button" transform="translate(-25, 25)" @click="resetView"> <!-- resetView not called when conditionally rendering-->
          <rect fill="black" height="30" width="50"/>
          <text dominant-baseline="middle" fill="white" text-anchor="middle" transform="translate(25, 15)">RESET</text>
        </g>
        <g class="svg-button" transform="translate(0, 80)" @click="zoomOut"> <!-- zoomOut not called when conditionally rendering-->
          <circle class="button" cx="0" cy="0" fill="black" r="20"/>
          <path d="M0 10 H 30 V20 H0 Z" fill="white" transform="translate(-15,-15)"/>
        </g>
      </g>

    </svg>
  </div>
</template>

<script>
  export default {
    name: 'SvgContainer',
    props: ['width', 'height'],
    data() {
      return {
        showControls: true,
        controlsWidthBase: 60,
        controlsHeightBase: 120,
        viewBoxWidth: this.width,
        viewBoxHeight: this.height,
        viewBoxScale: 1.0,
        viewBoxX: 0,
        viewBoxY: 0,
        startPoint: null,
        endPanX: 0,
        endPanY: 0,
        currentlyPanning: false,
        svgElement: undefined,
        mousePos: '',
      };
    },
    computed: {
      viewBox() {
        return `${this.viewBoxX} ${this.viewBoxY} ${this.scaledViewBoxWidth} ${this.scaledViewBoxHeight}`;
      },
      viewBoxPretty() {
        return `${this.viewBoxX.toFixed(2)} ${this.viewBoxY.toFixed(2)} ${this.scaledViewBoxWidth.toFixed(2)} ${this.scaledViewBoxHeight.toFixed(2)}`;
      },
      controlsWidth() {
        return this.controlsWidthBase * this.viewBoxScale;
      },
      controlsHeight() {
        return this.controlsHeightBase * this.viewBoxScale;
      },
      scaledViewBoxWidth() {
        return this.viewBoxWidth * this.viewBoxScale;
      },
      scaledViewBoxHeight() {
        return this.viewBoxHeight * this.viewBoxScale;
      },
    },
    methods: {
      fromPercentagePosX(perc) {
        return (perc / 100) * this.scaledViewBoxWidth;
      },
      fromPercentagePosY(perc) {
        return (perc / 100) * this.scaledViewBoxHeight;
      },
      onMouseEnter() {
        this.showControls = true;
      },
      zoomIn() {
        this.viewBoxScale *= 0.8;
      },
      zoomOut() {
        this.viewBoxScale /= 0.8;
      },
      resetView() {
        this.viewBoxScale = 1.0;
        this.viewBoxX = 0;
        this.viewBoxY = 0;
      },
      onScroll(event) {
        event.preventDefault();
        const normalizedDelta = event.wheelDelta / 120;
        normalizedDelta < 0 ? this.zoomOut() : this.zoomIn();
      },
      bindEvents() {
        this.svgElement = document.getElementById('svg-canvas-inner');
        const container = document.getElementById('svg-container');
        container.addEventListener('mousedown', this.startPan);
        container.addEventListener('mousemove', this.pan);
        container.addEventListener('mouseup', this.onMouseLeave);
        container.addEventListener('mouseenter', this.onMouseEnter);
        container.addEventListener('mouseleave', this.onMouseLeave);
        container.addEventListener('wheel', this.onScroll);
      },
      startPan(event) {
        this.currentlyPanning = true;
        this.startPoint = this.getMouseSVGPosition(event);
      },
      pan(event) {
        const panCoord = this.getMouseSVGPosition(event);

        if (this.currentlyPanning) {
          event.preventDefault();
          this.panX(panCoord.x - this.startPoint.x);
          this.panY(panCoord.y - this.startPoint.y);
        }

        this.mousePos = `${panCoord.x.toFixed(2)},${panCoord.y.toFixed(2)}`;
      },
      panX(amount) {
        this.viewBoxX -= amount;
      },
      panY(amount) {
        this.viewBoxY -= amount;
      },
      onMouseLeave(event) {
        this.currentlyPanning = false;
        this.startPoint = null;
        this.showControls = false;
      },
      getMouseSVGPosition(event) {
        const invertedCTM = this.svgElement.getScreenCTM().inverse();
        const point = this.svgElement.createSVGPoint();
        point.x = event.clientX;
        point.y = event.clientY;
        return point.matrixTransform(invertedCTM);
      },
    },
    mounted() {
      this.bindEvents();
    },
  };
</script>

<style scoped>

</style>

重置
导出默认值{
名称:“SvgContainer”,
道具:[“宽度”、“高度”],
数据(){
返回{
showControls:对,
controlsWidthBase:60,
控制基地:120,
viewBoxWidth:this.width,
viewBoxHeight:this.height,
viewBoxScale:1.0,
viewBoxX:0,
viewBoxY:0,
起始点:空,
endPanX:0,
完:0,,
当前平移:错误,
svgElement:未定义,
鼠标垫:'',
};
},
计算:{
视图框(){
返回`${this.viewBoxX}${this.viewBoxY}${this.scaledViewBoxWidth}${this.scaledViewBoxHeight}`;
},
viewBoxPretty(){
返回“${this.viewBoxX.toFixed(2)}${this.viewBoxY.toFixed(2)}${this.scaledViewBoxWidth.toFixed(2)}${this.scaledViewBoxHeight.toFixed(2)}”;
},
controlsWidth(){
返回this.controlsWidthBase*this.viewBoxScale;
},
控制权{
返回this.controlsHeightBase*this.viewBoxScale;
},
scaledViewBoxWidth(){
返回this.viewBoxWidth*this.viewBoxScale;
},
scaledViewBoxHeight(){
返回this.viewBoxHeight*this.viewBoxScale;
},
},
方法:{
fromPercentagePosX(perc){
返回(perc/100)*此.scaledViewBoxWidth;
},
fromPercentagePosY(perc){
返回(perc/100)*此.scaledViewBoxHeight;
},
onMouseEnter(){
this.showControls=true;
},
zoomIn(){
此.viewBoxScale*=0.8;
},
zoomOut(){
这个.viewBoxScale/=0.8;
},
resetView(){
这个.viewBoxScale=1.0;
this.viewBoxX=0;
this.viewBoxY=0;
},
onScroll(活动){
event.preventDefault();
常量normalizedDelta=event.wheelDelta/120;
normalizedDelta<0?this.zoomOut():this.zoomIn();
},
bindEvents(){
this.svgElement=document.getElementById('svg-canvas-inner');
const container=document.getElementById('svg-container');
container.addEventListener('mousedown',this.startPan);
container.addEventListener('mousemove',this.pan);
container.addEventListener('mouseup',this.onMouseLeave);
container.addEventListener('mouseenter',this.onMouseCenter);
container.addEventListener('mouseleave',this.onMouseLeave);
container.addEventListener('wheel',this.onScroll);
},
startPan(活动){
this.currentlyPanning=true;
this.startPoint=this.getMouseSVGPosition(事件);
},
潘(活动){
const panCoord=this.getMouseSVGPosition(事件);
如果(当前平移){
event.preventDefault();
this.panX(panCoord.x-this.startPoint.x);
this.panY(panCoord.y-this.startPoint.y);
}
this.mousePos=`panCoord.x.toFixed(2)},${panCoord.y.toFixed(2)};
},
panX(金额){
this.viewBoxX-=金额;
},
公司(金额){
this.viewBoxY-=金额;
},
休假(活动){
this.currentlyPanning=false;
this.startPoint=null;
this.showControls=false;
},
getMouseSVGPosition(事件){
const=this.svgElement.getScreenCTM().inverse();
常量点=this.svgElement.createSVGPoint();
point.x=event.clientX;
point.y=event.clientY;
返回点矩阵变换(DCTM);
},
},
安装的(){
这是bindEvents();
},
};

当触发
mouseup
事件时,元素将隐藏

删除此行:

 //container.addEventListener("mouseup", this.onMouseLeave);

下面是一个工作示例:

只使用css(如“显示”或“隐藏”)怎么样?