-
v-model 的實(shí)質(zhì)其實(shí)就是語(yǔ)法糖
從上圖中我們可以看到v-model=”something”則表示將value值綁定在something上唉侄,當(dāng)值發(fā)生改變時(shí)觸發(fā)綁定的oninput事件。oninput事件綁定的函數(shù)是將觸發(fā)oninput事件的目標(biāo)(該input)的value值賦值給something這個(gè)變量野建。所以:
在vue3中要注意將 prop和event命名更改為modelValue和update:modelValue
主要的兩個(gè)步驟:
1.自定義組件創(chuàng)建 props屬性 modelValue
2.自定義組件觸發(fā)update:modelValue事件属划,并把值傳出去
- 下面我們先來(lái)封裝一個(gè)最基礎(chǔ)的 TestModel組件
// 自定義一個(gè)TestModel組件
<template>
<div>
<input type="text" :value="modelValue" @input="$emit('update:modelValue', $event.target.value)" />
</div>
</template>
<script>
export default {
props: {
modelValue: {
type: String
}
}
}
</script>
- 使用組件
<testModel v-model="msg"></testModel>
等同于下面語(yǔ)法 默認(rèn)傳入一個(gè)modelValue 然后子組件接收這個(gè)modelValue
<testModel :modelValue="msg" @update:modelValue="msg = $event"></testModel>
// 引用TestModel組件
<template>
<h1>vue3中使用v-model {{msg}}</h1>
<testModel v-model="msg"></testModel>
<!-- 等同于下面語(yǔ)法 默認(rèn)傳入一個(gè)modelValue 然后子組件接收這個(gè)modelValue -->
<testModel :modelValue="msg" @update:modelValue="msg = $event"></testModel>
</template>
<script>
import { ref } from 'vue';
import testModel from './TestModel.vue';
export default {
components: {
testModel
},
setup(){
const msg = ref('')
return { msg }
},
}
</script>
- 有時(shí)候可能不想叫modelValue,也可以改成其他的名字候生,需要這樣改寫一下
// 父組件
<template>
<h1>vue3中使用v-model {{msg}}</h1>
<testModel v-model:msg="msg"></testModel>
</template>
子組件接收的props就要改成msg了
// 子組件
<template>
<div>
<input type="text" :value="msg" @input="$emit('update:msg', $event.target.value)" />
</div>
</template>
<script>
export default {
props: {
msg: {
type: String
}
}
}
</script>
- 雙向綁定不一定必須是輸入框組件同眯,可以自定義各種各樣的組件,比如通過(guò)click事件改變父組件的值,或者進(jìn)一步封裝 已有v-model功能的組件,比如進(jìn)一步封裝prism-editor
<template>
<div class="c-prism-editor">
<prism-editor
v-model="code"
class="my-editor"
:style="{height: _height}"
:highlight="highlighter"
:line-numbers="lineNumbers"
></prism-editor>
</div>
</template>
<script>
import { PrismEditor } from 'vue-prism-editor'
import 'vue-prism-editor/dist/prismeditor.min.css' // import the styles somewhere
// import highlighting library (you can use any library you want just return html string)
import { highlight, languages } from 'prismjs/components/prism-core'
import 'prismjs/components/prism-clike'
import 'prismjs/components/prism-javascript'
import 'prismjs/themes/prism-tomorrow.css' // import syntax highlighting styles
import { defineComponent, ref, reactive, onMounted, watch } from 'vue'
export default defineComponent({
name: 'c-prism-editor',
components: {
PrismEditor
},
props: {
height: String,
modelValue: String
},
emits: ['update:modelValue'],
setup(props, context) {
console.log(props)
let code = ref('')
let _height = props.height ? ref(props.height) : ref('300px') //默認(rèn)300px
let lineNumbers = ref(true)
function highlighter(code) {
console.log(languages)
return highlight(code, languages.js) //returns html
}
watch(code, (newCode, prevCode) => {
context.emit('update:modelValue', newCode)
})
watch(props, (newCode, prevCode) => {
let {modelValue} = props
code.value = modelValue
})
return {
code,
lineNumbers,
highlighter,
_height
}
}
})
</script>
<style lang="less">
.c-prism-editor {
width: 100%;
.my-editor {
background: #2d2d2d;
color: #ccc;
font-family: Fira code, Fira Mono, Consolas, Menlo, Courier, monospace;
font-size: 14px;
line-height: 1.5;
padding: 5px;
}
}
// optional
.prism-editor__textarea:focus {
outline: none;
}
</style>
使用
<div class="auto-center">
<c-prism-editor v-model="form.script" height="500px"></c-prism-editor>
</div>
以上就是封裝vue3 實(shí)現(xiàn)v-model的知識(shí)點(diǎn)了唯鸭,fzs原創(chuàng)嗽测,轉(zhuǎn)載請(qǐng)注明出處