一、APP组件
<template>
<div>
<div>
<h3>自定义MyInput组件</h3>
<my-input v-model="mValue" />
{{ mValue }}
</div>
<hr />
<div>
<h3>自定义MyRadio组件</h3>
<my-radio v-model="sex" label="male" name="sex">男</my-radio>
<my-radio v-model="sex" label="female" name="sex">女</my-radio>
{{ sex }}
</div>
<hr />
<div>
<h3>自定义MyCheckbox组件</h3>
<my-checkbox v-model="hobbies" label="yy" name="hobbies">游泳</my-checkbox>
<my-checkbox v-model="hobbies" label="ts" name="hobbies">跳水</my-checkbox>
<my-checkbox v-model="hobbies" label="dq" name="hobbies">打球</my-checkbox>
{{ hobbies }}
</div>
</div>
</template>
<script>
import MyInput from "./MyInput.vue";
import MyRadio from "./MyRadio.vue";
import MyCheckbox from "./MyCheckbox.vue";
export default {
name: "App",
components: { MyInput, MyRadio, MyCheckbox },
data() {
return {
mValue: 50,
sex: "",
hobbies: [],
};
},
};
</script>
二、MyInput组件
<template>
<div>
<label>输入内容</label>
<!-- 第一种: -->
<!-- 用vueComponent实例自带的$attrs来接收父组件传递过来的value属性 -->
<!-- <input :value="$attrs.value" @input="handleInput"/> -->
<!-- 第二种: -->
<!-- <input :value="value" @input="handleInput"/> -->
<!-- 第三种: -->
<input :value="mValue" @input="handleInput" />
</div>
</template>
<script>
export default {
name: "MyInput",
props: ["mValue"],
model: {
prop: "mValue",
event: "input",
},
data() {
console.log("MyInput", this);
return {};
},
methods: {
handleInput(event) {
this.$emit("input", event.target.value);
},
},
};
</script>
<style>
</style>
2.1 第一种
2.2 第二种
2.3 第三种(标准的使用方式)
三、MyRadio组件
<!-- -->
<template>
<div>
<input
type="radio"
:checked="checked"
@change="handleChange"
:value="label"
:name="name"
/>
<slot />
</div>
</template>
<script>
export default {
name: "MyRadio",
props: ["sex", "label", "name"],
model: {
prop: "sex",
event: "change",
},
computed: {
checked() {
return this.sex === this.label;
},
},
data(){
console.log('MyRadio',this);
return{}
},
methods: {
handleChange(event) {
if (!this.sex||this.sex!==this.label) {
console.log("event", event, event.target.checked, this.label);
this.$emit("change", event.target.checked ? this.label : "");
}
},
},
};
</script>
<style>
</style>
四、MyCheckbox组件
<!-- MyCheckbox需要借助外层再次包裹,否则无法获取数组。参考element-ui实现 -->
<template>
<div>
<input
type="checkbox"
:checked="checked"
@change="handleChange"
:value="label"
:name="name"
/>
<slot />
</div>
</template>
<script>
export default {
name: "MyCheckbox",
props: ["hobbies", "label", "name"],
model: {
prop: "hobbies",
event: "change",
},
data() {
console.log("MyCheckbox", this);
return {};
},
computed: {
checked() {
return this.hobbies.includes(this.label);
},
},
methods: {
handleChange(event) {
console.log("event", event);
const checked = event.target.checked;
let tempHobbies = [...this.hobbies];
let currentIndex = tempHobbies.indexOf(this.label);
if (checked && currentIndex == -1) {
tempHobbies.push(this.label);
} else if (!checked && currentIndex != -1) {
tempHobbies.splice(currentIndex, 1);
}
this.$emit("change", tempHobbies);
},
},
};
</script>
<style>
</style>
五、效果图