2 方式绑定问题使用 Fast-UI + Vue.js ver。 2.6.11

2 Way binding issue using Fast-UI + Vue.js ver. 2.6.11

这是在版本 (package.json) 上测试的:

{
  "name": "fast-ui-vuejs-ver-2611-binding-issue",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint"
  },
  "dependencies": {
    "@microsoft/fast-components": "^2.10.1",
    "@microsoft/fast-element": "^1.5.1",
    "@vue/cli-plugin-babel": "4.1.1",
    "lodash-es": "^4.17.21",
    "vue": "^2.6.11",
    "vue-selector": "0.0.1"
  },
  "devDependencies": {
    "@vue/cli-plugin-eslint": "4.1.1",
    "@vue/cli-service": "4.1.1",
    "babel-eslint": "^10.0.3",
    "eslint": "^6.7.2",
    "eslint-plugin-vue": "^6.0.1",
    "vue-template-compiler": "^2.6.11"
  },
}

先决条件

  1. 使用 this URL 打开沙盒;
  2. 等待一切安装完成;
  3. 等到屏幕右侧出现滑块。

重现问题的步骤:

  1. 前后拖动滑块的拇指(手柄);
  2. 查看值(已按预期更改);
  3. 单击 +- 按钮;
  4. 再次尝试使用滑块;
  5. 返回 +- 按钮,然后单击一个或另一个。
实际结果:

在与不同 components/elements

交互后,绑定停止工作或至少不按预期工作
预期结果:

它必须在任何交互后工作。

我尝试过的东西:

自定义绑定指令的代码示例:

实现文件

Vue.directive("cd-bind", {
  bind(el, binding, vnode) {
    const inputHandler = (event) =>
      (vnode.context.$data[binding.expression] = event.target.value);
    el.addEventListener("input", inputHandler);
    el.addEventListener("change", inputHandler);
    el.addEventListener("slide", inputHandler);
  },
});

用法:

<fast-slider
      v-cd-bind="value"
      :value="value"
      :min="0"
      :max="20"
></fast-slider>
附加信息:

在一个元素失去焦点而另一个元素获得焦点后,绑定(或它的某些部分停止工作)。

Video on this issue

"EisenbergEffect" 提出的建议,可能会帮助别人找到解决问题的方法 site:

"For Aurelia, we had to add some special configuration to enable better two-way binding. I'm guessing that there's a similar need with Vue. Typically in a two-way or model bind scenario the framework needs to know how to correlate event names with the properties that change so it can add event listeners. My guess is that Vue doesn't know what events to attach because it only has code to handle built-in elements. As a next step, I think you may want to take a look and see if Vue offers an API to provide that data to their model binding system. Hopefully they do. In that case, we would just need to set that up properly for the components we publish...and add that to our documentation for Vue. Another issue may be related to whether Vue's binding is setting properties or attributes. They can be different and tend to be a little when it comes to input elements. Does: value set the value attribute or the value property?"

主要部件代码:
<template>
  <fast-card>
    <span style="color: white"
      >Current value:
      <b style="color: red; font-size: 150%">{{ value }}</b></span
    >
    <fast-slider
      :value="value"
      :max="max"
      :min="min"
      ref="comp"
      @change="change($event)"
    >
      <div
        slot="track"
        class="time-seeker__played"
        :style="{ width: timePlayedPercentage + '%' }"
      ></div>
    </fast-slider>

    <fast-card>
      <fast-button @click="value = value > 0 ? value - 1 : value"
        >-</fast-button
      >
      <fast-button @click="value = value < 20 ? value + 1 : value"
        >+</fast-button
      >
    </fast-card>
  </fast-card>
</template>

<script>
export default {
  name: "HelloWorld",
  data() {
    return {
      value: 3,
      min: 0,
      max: 20,
    };
  },
  computed: {
    timePlayedPercentage: function () {
      let value = Math.round((this.value * 100) / this.max);
      // console.log(value, "%");
      return value;
    },
  },
  methods: {
    change(e) {
      this.value = +e.target.value;
    },
  },
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss">
div {
  width: 100%;
}

.time-seeker__played {
  transition: width 75ms cubic-bezier(0.86, 0.05, 0.4, 0.96);
  background: red;
  height: 100%;
  border-radius: 15%;
}

fast-card {
  margin-block: 1rem;
}

fast-button {
  margin-inline-end: 1rem;
}
</style>

在向 FAST-UI 团队询问后,他们在他们的存储库中创建了一些 PR:

他们更新了这个项目的核心代码后,这个2向绑定就消失了!

但是,为了使这些工作正常,他们实现了一个名为 current-value(或 JS 中的 currentValue)的新 HTML 属性,该属性正在对其进行更改。

此功能适用于:

  • @microsoft/fast-foundation@2.23.0;
  • @microsoft/fast-components@2.14.2.

HTML/Vue 个组成部分的差异

之前

<fast-slider
      :value="value"
      :max="max"
      :min="min"
      ref="comp"
      @change="change($event)"
    >

之后

<fast-slider
      :current-value="value"
      :max="max"
      :min="min"
      ref="comp"
      @change="change($event)"
    >

感谢 FAST-UI 团队,这是完美运行的版本: open workable sandbox example

此外,还有另一个 PR 正在等待 28.10.2021 feat: add current-checked attribute to checkable form controls #5326 将添加 current-checked 属性以使其响应 UI/JS 更改。