_
2023/8/31 08:27:411119

这节课给大家在组件传值上补充一些数据双向绑定的知识点,就是我们之前学习过的

v-model数据双向绑定指令。

学习这节课之前我们需要先来回顾一下组件的事件通讯知识点。我们先来撸一个计数器实现组件的事件通讯演示。

<script>
  const app = Vue.createApp({
    data() {
      return {
        count: 1
      }
    },
    methods:{
      handelAdd(val){
        this.count = val
      }
    },
    template: `<counter :count="count" @add="handelAdd" />`
  })

  app.component("counter",{
    props:['count'],
    emits:['add'],
    methods: {
      add(){
        this.$emit('add', this.count+1)
      }
    },
    template:`<button @click="add">点击加1 {{count}}</button>`
  })


  const vm = app.mount("#app")
</script>

上面的代码我们实现一个计数器组件,主要给大家演示了组件事件通讯,那么有段代码,我们可以通过数据双向绑定来调整优化这个计数器。

组件的数据双向绑定

v-model数据双向绑定其实是事件通讯来实现的,在我们上面的案例中,我们传入了count属性然后通过向外触发一个add事件来把最新的count值传递出去,然后在父组件中又来监听add事件获取到最新的数据赋值给count变量,这样形成了一个闭环实现了这个计数器。

那么v-model其实在这个闭环中它帮我们实现了最后一步,我们了解这些以后就可以开始来改造计数器组件了。

首先我们是用 v-model 绑定count 并且删除掉其余代码

const app = Vue.createApp({
    data() {
      return {
        count: 1
      }
    },
    template: `<counter v-model="count"  />`
  })

然后Counter组件里面我们需要修改props定义的属性countmodelValue 这是个固定写法。

props:['modelValue']

还有修改事件名为update:modelValue 这也是固定写法。

别忘了声明emits:['update:modelValue']

这里的update表示更新数据冒号后面跟着的是需要更新的属性名称。

 app.component("counter",{
    props:['modelValue'],
    emits:['update:modelValue'],
    methods: {
      add(){
        this.$emit('update:modelValue', this.modelValue+1)
      }
    },
    template:`<button @click="add">点击加1 {{modelValue}}</button>`
  })

最后得到代码

<script>
  const app = Vue.createApp({
    data() {
      return {
        count: 1
      }
    },
    template: `<counter v-model="count"  />`
  })

  app.component("counter",{
    props:['modelValue'],
    emits:['update:modelValue'],
    methods: {
      add(){
        this.$emit('update:modelValue', this.modelValue+1)
      }
    },
    template:`<button @click="add">点击加1 {{modelValue}}</button>`
  })

  const vm = app.mount("#app")
</script>

运行上面的代码,看一下结果,你会发现计数器功能仍然正常。

自定义属性

上面我们尝试实现了一个组件的数据双向绑定,我们组件需要固定写一个modelValue属性。如果我们改成其它的,它是会出现问题的。

比如我们改成modelValue1,

 app.component("counter",{
    props:['modelValue1'],
    emits:['update:modelValue1'],
    methods: {
      add(){
        this.$emit('update:modelValue1', this.modelValue+1)
      }
    },
    template:`<button @click="add">点击加1 {{modelValue}}</button>`
  })

这样改了之后,它运行起来是会的报错的,但是这不代表它不能修改,只是咱们得按规则来。

modelValue它是v-model默认指定传递属性,那么我们需要自定义的话,我们就需要给设置一个自定义传值属性。比如我们以count为例。

<script>
  const app = Vue.createApp({
    data() {
      return {
        count: 1
      }
    },
    template: `<counter v-model:count="count"  />`
  })

  app.component("counter",{
    props:['count'],
    emits:['update:count'],
    methods: {
      add(){
        this.$emit('update:count', this.count+1)
      }
    },
    template:`<button @click="add">点击加1 {{count}}</button>`
  })

  const vm = app.mount("#app")
</script>

只需要在v-model后面加个冒号和自定义的属性名就行了,那么当我们不传递的时候它是默认modelValue属性 并且可以简写v-model,其实等价于v-model:modelValue

v-mode数据双向绑定在我们开发组件时,用得好的话是可以减少不少代码的。

实现多个v-mode

v-mode它是可以实现多个值绑定的,我们只需给它多设置一个传值属性,多触发一个事件就行,给大家演示一下。

<script>
  const app = Vue.createApp({
    data() {
      return {
        count: 1,
        count1:2
      }
    },
    template: `<counter v-model:count="count" v-model:count1="count1"  />`
  })

  app.component("counter",{
    props:['count','count1'],
    emits:['update:count', 'update:count1'],
    methods: {
      add(){
        this.$emit('update:count', this.count+1)
        this.$emit('update:count1', this.count1 + 3)
      }
    },
    template:`<button @click="add">点击加1 {{count}} - {{count1}}</button>`
  })

  const vm = app.mount("#app")
</script>

我们多添加了一个count1属性,其它的照葫芦画瓢就行了。

这节课学习的内容对于新手朋友来说还挺难理解的,希望大家还是多多消化一下。

好了,这节课就到这个结束了,

视频讲解