指尖上的记忆指尖上的记忆
首页
  • 基础
  • Laravel框架
  • Symfony框架
  • 基础
  • Gin框架
  • 基础
  • Spring框架
  • 命令
  • Nginx
  • Ai
  • Deploy
  • Docker
  • K8s
  • Micro
  • RabbitMQ
  • Mysql
  • PostgreSsql
  • Redis
  • MongoDb
  • Html
  • Js
  • 前端
  • 后端
  • Git
  • 知识扫盲
  • Golang
🌟 gitHub
首页
  • 基础
  • Laravel框架
  • Symfony框架
  • 基础
  • Gin框架
  • 基础
  • Spring框架
  • 命令
  • Nginx
  • Ai
  • Deploy
  • Docker
  • K8s
  • Micro
  • RabbitMQ
  • Mysql
  • PostgreSsql
  • Redis
  • MongoDb
  • Html
  • Js
  • 前端
  • 后端
  • Git
  • 知识扫盲
  • Golang
🌟 gitHub

vue3下的v-model和vue2的区别:

//子组件:TimeOutModel.vue
<script setup lang="ts">
import {computed} from "vue";

interface Props {
  modelValue: boolean;
}

const props = defineProps<Props>();

const emit = defineEmits<{
  (e: "update:model-value", show: boolean): void;//真正的 emit 方法在这里, show 只是参数名称,可以自定义为自己想要的
}>();

const isModalVisible = computed({
  get: () => props.modelValue,
  //当前组件的值发生变化的时候,通过emit通知父组件,实现双向绑定,这一步可以对value 做一定的处理,比如:set: (value) => emit("update:title-info", value.charAt(0).toUpperCase() + value.slice(1)),
  //注意,我开始以为需要可以在父组件里定义 @update:model-value="otherFun()",然后在otherFun()里获取这个 value,后来发现不行,感觉前面这个写法相当于是内置的,就只用于v-model的双向绑定,@update:model-value
  //不需要在父组件里写,可以参考最下面的链接
  set: (value) => emit("update:model-value", value),
});
</script>

<template>
  <QModal v-model="isModalVisible" :hideCloseIcon="true" :persistent="true">
    <template #header>
      <div class="infoHear">
        <img src="~/assets/img/notice.svg" class="notice-img"/>
        <h3>Time is up!</h3>
      </div>
    </template>
    <template #body>
      <p class="body-info">Do you want to submit  or discard changes</p>
    </template>
    <template #footer>
      <div class="flex gap-2">
        <QButton size="sm" class="flex-1" variant="secondary" @click="close">Discard</QButton>
        <QButton size="sm" class="flex-1" variant="primary" @click="submit">Submit</QButton>
      </div>
    </template>
  </QModal>
</template>

<script lang="ts">

export default {
  name: "DsModal",
  methods: {
    close(){
      this.$emit('close') //还是可以在这里定义对外的emit方法
    },
    submit(){
      this.$emit('submit')
    }
  }
}
</script>

<style scoped lang="postcss">
.infoHear{
  display: flex;
  flex-direction: column;
  align-items: center;
  .notice-img{
    display: block;
    width: 3.3125rem;
    height: 3.625rem;
  }
}

.body-info{
  display: flex;
  justify-content: center;
  padding: 1.25rem 0.625rem;
}
</style>


上面的vue组件,要求 script setup 中的 lang 和 script 中的 lang 要定义相同
参考:https://v3-migration.vuejs.org/breaking-changes/v-model.html
  
//经过改造以后,实现子组件修改数据,触发set方法 ,主要是通过 @click="tt" 修改字符串的内容,这样就验证了,这个set 方法中的emit的作用,实现双向绑定
<script setup lang="ts">
import {computed} from "vue";

interface Props {
  modelValue: boolean,
  titleInfo: string
}

const props = defineProps<Props>();

const emit = defineEmits<{
  (e: "update:model-value", show: boolean): void;
  (e: "update:title-info", str: string): void;
}>();

const isModalVisible = computed({
  get: () => props.modelValue,
  set: (value) => emit("update:model-value", value),
});

const titleStr = computed({
  get: () => props.titleInfo,
  set: (value) => emit("update:title-info", value.charAt(0).toUpperCase() + value.slice(1)),
})

const tt = () => {
  titleStr.value = "good bye" + (new Date())
}
</script>

<template>
  <QModal v-model="isModalVisible" :hideCloseIcon="true" :persistent="true">
    <template #header>
      <div class="infoHear">
        <img src="~/assets/img/notice.svg" class="notice-img"/>
        <h3 @click="tt">{{titleStr}}</h3>
      </div>
    </template>
    <template #body>
      <p class="body-info">Do you want to submit  or discard changes</p>
    </template>
    <template #footer>
      <div class="flex gap-2">
        <QButton size="sm" class="flex-1" variant="secondary" @click="close">Discard</QButton>
        <QButton size="sm" class="flex-1" variant="primary" @click="submit">Submit</QButton>
      </div>
    </template>
  </QModal>
</template>

<script lang="ts">

export default {
  name: "DsModal",
  methods: {
    close(){
      this.$emit('close')
    },
    submit(){
      this.$emit('submit')
    }
  }
}
</script>

<style scoped lang="postcss">
.infoHear{
  display: flex;
  flex-direction: column;
  align-items: center;
  .notice-img{
    display: block;
    width: 3.3125rem;
    height: 3.625rem;
  }
}

.body-info{
  display: flex;
  justify-content: center;
  padding: 1.25rem 0.625rem;
}
</style>


//vue3下v-model 自定义数据预处理,有时候我们需要在用户输入内容的的时候,对输入的数据做预处理,比如 去掉空格,转大写等
参考:https://vuejs.org/guide/components/v-model.html#handling-v-model-modifiers //我自己测试失败了