This is because you have the <input type="radio"> inside your <label>, not next to it and the :focus property has to be on the <label> not on the <input type="radio"> radio which is hidden.
The dashed green border on :focus disappears after clicking on the label because the input will hold the :focus after clicking on it.
Here a working live Codepen (case: input and label are siblings)
.squareRadios {
  margin: 10px;
}
.squareRadios input[type="radio"] {
  opacity: 0;
  position: fixed;
  width: 0;
}
.squareRadios label {
  display: inline-block;
  background-color: #ddd;
  padding: 10px 20px;
  font-family: sans-serif, Arial;
  font-size: 16px;
  border: 2px solid #444;
  border-radius: 4px;
}
.squareRadios label:hover {
  background-color: red;
}
.squareRadios input[type="radio"]:checked + label {
  background-color: blue;
  border-color: #4c4;
}
.squareRadios label:focus {
  border: 2px dashed green;
  outline: none;
}
<div class="squareRadios">
  <input id="radio0" type="radio" value="0" name="squareradios" />
  <label tabindex="1" for="radio0">
    0
  </label>
  <input id="radio1" type="radio" value="1" name="squareradios" />
  <label tabindex="1" for="radio1">
    1
  </label>
  <input id="radio2" type="radio" value="2" name="squareradios" />
  <label tabindex="1" for="radio2">
    2
  </label>
  <input id="radio3" type="radio" value="3" name="squareradios" />
  <label tabindex="1" for="radio3">
    3
  </label>
  <input id="radio4" type="radio" value="4" name="squareradios" />
  <label tabindex="1" for="radio4">
    4
  </label>
  <input id="radio5" type="radio" value="5" name="squareradios" />
  <label tabindex="1" for="radio5">
    5
  </label>
</div>
 
 
EDIT
New Request:
I am also using Vue so it is recommended to put the input inside the label.
I would use JavaScript to handle this situation: toggle a class (I used a class called "checked") on the label to add the style.
var labels = document.querySelectorAll("label");
for (var i = 0; i < labels.length; i++) {
    labels[i].addEventListener(
        "click",
        function (e) {
            e.preventDefault();
            e.stopPropagation();
            if (this.classList.contains("checked")) {
                this.classList.remove("checked");
                this.firstElementChild.checked = false;
            } else {
                var checked = document.querySelector("label.checked");
                if (checked) {
                    checked.classList.remove("checked");
                    checked.firstElementChild.checked = false;
                }
                this.classList.add("checked");
                this.firstElementChild.checked = true;
            }
        },
        false
    );
}
.squareRadios {
  margin: 10px;
}
.squareRadios input[type="radio"] {
  opacity: 0;
  position: fixed;
  width: 0;
}
.squareRadios label {
  display: inline-block;
  background-color: #ddd;
  padding: 10px 20px;
  font-family: sans-serif, Arial;
  font-size: 16px;
  border: 2px solid #444;
  border-radius: 4px;
}
.squareRadios label:hover {
  background-color: red;
}
.squareRadios label.checked {
  background-color: blue;
  border-color: #4c4;
}
.squareRadios label:focus {
  border: 2px dashed green;
  outline: none;
}
<div class="squareRadios">
  <label tabindex="1">
    0
    <input name="squareradios" type="radio" value="0" />
  </label>
  <label tabindex="1">
    1
    <input name="squareradios" type="radio" value="1" />
  </label>
  <label tabindex="1">
    2
    <input name="squareradios" type="radio" value="2" />
  </label>
  <label tabindex="1">
    3
    <input name="squareradios" type="radio" value="3" />
  </label>
  <label tabindex="1">
    4
    <input name="squareradios" type="radio" value="4" />
  </label>
  <label tabindex="1">
    5
    <input name="squareradios" type="radio" value="5" />
  </label>
</div>
 
 
Here a working live Codepen (case: input is inside label)