Vue3组件(一)做个组件尝尝鲜

简介: 在工程化项目里面,默认会设置views和components这两个文件夹,而两个文件夹里面放的又都是.vue文件,既然是同类型的文件,为啥要设置两个文件夹呢?因为用途有点区别。

.vue文件的分类



在工程化项目里面,默认会设置views和components这两个文件夹,而两个文件夹里面放的又都是.vue文件,既然是同类型的文件,为啥要设置两个文件夹呢?因为用途有点区别。

按照使用方式,.vue文件可以分为页面、组件和控件三类。


页面


一般存放在views目录里面,一开始我还以为这里的.vue文件不需要属性(props)呢,因为没有谁能给他传递属性值。 后来学习路由知识后发现我错了,路由不仅可以加载组件,而且还能给组件传递属性。


这样.vue文件不管在哪,都可以有属性(props),那么从代码角度,就没有明确的区分了。


所以只能从使用方式来区分一下。


页面可以看做是路由直接加载的组件,作为一个“容器”,存放多个组件,确定其位置,负责各个组件之间的连系。


组件


导航、header、footer这类多个页面共用的部分,或者功能比较独立的部分。 从页面里面分离出来,可以让代码更清晰易读,扩展性和维护性也会更好。 比如我要改个导航,直接去找导航组件就好,不用怕误改了其他代码。


其他组件里面也不会看到共用组件里的代码,指定位置就好。可以把重点放在自己的逻辑上面来。


控件


简单的说,就是UI库提供的各种控件,比如表单里的文本框、选择列表框、日期选择控件等,还有表单控件、列表控件、分页控件等。


虽然在vue里面,这些都是组件的形式出现,但是还是可以细分、明确一下,这样不容易产生误解。


本系列主要说的是控件这一类的组件。


我们先用一个简单的文本框来举个例子。


定义组件



<template>
  <input
    :value="modelValue"
    @input="myInput"
  ><br>
  组件内部值:{{modelValue}}
</template>
<script>
import { toRef, toRefs, watch } from 'vue'
export default {
  name: 'mytext',
  props: {
    modelValue: String,
    meta: Object
  },
  emits: ['input'],
  setup (props, context) {
    // 向父组件提交修改属性
    const myInput = (e) => {
      console.log(e)
      context.emit('update:modelValue', e.target.value)
    }
    return {
      myInput
    }
  }
}
</script>
复制代码


  • template:模板部分,写html代码和vue的绑定语句。


  • script:js脚本部分。


  • style:可以写css。


  • export default:返回一个对象,用于创建组件。


  • name :组件名称,可以不写这个属性,但是如果要写的话,就不要重名。


  • props:定义组件的属性。


  • emits:定义组件的事件。


  • setup:vue3的新写法。虽然vue3也兼容vue2的方式,但是我们都用上vue3了,那么尽量用新的方式。


父组件里面使用组件


<template>
  <div class="home">
    父组件的值:{{value}}<br>
    自己的组件:<mytext v-model="value"/><br>
    原生文本框:<input type="text" v-model="value"/>
  </div>
</template>
<script>
import { ref } from 'vue'
import mytext from '@/components/nf-html/input-text2.vue'
export default {
  name: 'eleBase',
  components: {
    mytext
  },
  setup () {
    const value = ref('1')
    return {
      value
    }
  }
}
</script>
复制代码


  • import


可以用 import  的方式引入组件。


  • components


如果组件没有做全局注册的话,那么需要使用 components 在父组件里面注册。


setup 的参数



setup提供两个参数,一个是props,传递组件的属性;一个是context(上下文),提供emit这类的方法。


props


在 setup 里面可以通过 props 访问组件的属性,但是请注意:原则上是不允许在组件内部直接修改属性值的。所以一般可以使用 watch 的方式来监控属性的变化。 但是如果我就是想访问属性呢,结果会如何? 我们可以设计几个方式来看看效果:


const myProps1 = props // 获取属性
    const myProps = toRefs(props) // toRefs的方式获取属性
    const myValue = toRef(props, 'modelValue') // toRef获取指定的属性
    console.log('原生属性:', props)
    console.log('toRefs的属性:', myProps)
    console.log('toRef 的属性:', myValue)
    console.log('myProps.modelValue:', myProps.modelValue)
    // 直接修改,会报错(ESLint)
    // props.modelValue = '直接改属性'
    // 尝试修改,虽然只有警告不会报错,但是修改不会成功。
    myProps1.modelValue = '内部直接修改'
    // 尝试修改,虽然只有警告不会报错,但是修改不会成功。
    myValue.value = '内部修改属性'
    // 监控属性变化
    watch(() => props.modelValue, (v1, v2) => {
      console.log('原值:', v1)
      console.log('新值:', v2)
    })
复制代码


  • 属性的打印结果


image.png


从打印结果可以看出来,组件的属性被封装成了reactive的形式,然后又在外面套上了readonly,所以实现了无法直接赋值的效果。


注意:不能修改只是对简单类型有效,如果属性是对象类型的话,还是可以直接修改属性值的。


  • 尝试直接赋值。


以前尝试直接赋值的时候会报错,现在虽然不报错了,但是无法修改,而且会给出警告,如

图:


image.png


  • toRefs 和 toRef


image.png


toRefs可以把属性拆分成多个ref的形式,尝试了一下,如果属性是简单类型,还是不可以直接修改值的。但是如果属性类型是对象的话,又可以直接修改值了。


toRef也是一样的效果。


context


我们来看一看context的打印结果:


image.png


比较常用的就是emit,相当于vue2的this.emit。


我们可以写一个向父组件提交属性的函数


// 向父组件提交修改属性
    const myInput = (e) => {
      console.log(e)
      context.emit('update:modelValue', e.target.value)
    }
复制代码


  • update:modelValue


这是修改父组件的属性的一种方法,后面是要修改的值。


v-model


vue3支持多个v-model了。父组件可以这样写:


v-model:foo="foo" v-model:fo="fo" 
复制代码


如果只需要一个属性的话,也可以简写


v-model="fooo"
复制代码


只是组件内部的属性名称要写成固定的“modelValue”,如果是其他属性名称的话,必须用带冒号的方式。


小结



这个只是一个开篇,介绍基础知识,后面还有更精彩的内容。


源码:



github.com/naturefwvue…


相关文章
|
2月前
|
缓存 JavaScript UED
Vue3中v-model在处理自定义组件双向数据绑定时有哪些注意事项?
在使用`v-model`处理自定义组件双向数据绑定时,要仔细考虑各种因素,确保数据的准确传递和更新,同时提供良好的用户体验和代码可维护性。通过合理的设计和注意事项的遵循,能够更好地发挥`v-model`的优势,实现高效的双向数据绑定效果。
165 64
|
3天前
|
资源调度 JavaScript 前端开发
创建vue3项目步骤以及安装第三方插件步骤【保姆级教程】
这是一篇关于创建Vue项目的详细指南,涵盖从环境搭建到项目部署的全过程。
38 1
|
2月前
|
JavaScript 前端开发 API
Vue 3 中 v-model 与 Vue 2 中 v-model 的区别是什么?
总的来说,Vue 3 中的 `v-model` 在灵活性、与组合式 API 的结合、对自定义组件的支持等方面都有了明显的提升和改进,使其更适应现代前端开发的需求和趋势。但需要注意的是,在迁移过程中可能需要对一些代码进行调整和适配。
146 60
|
30天前
|
JavaScript API 数据处理
vue3使用pinia中的actions,需要调用接口的话
通过上述步骤,您可以在Vue 3中使用Pinia和actions来管理状态并调用API接口。Pinia的简洁设计使得状态管理和异步操作更加直观和易于维护。无论是安装配置、创建Store还是在组件中使用Store,都能轻松实现高效的状态管理和数据处理。
120 3
|
2月前
|
JavaScript 前端开发 API
从Vue 2到Vue 3的演进
从Vue 2到Vue 3的演进
86 17
|
2月前
|
JavaScript 前端开发 API
Vue.js响应式原理深度解析:从Vue 2到Vue 3的演进
Vue.js响应式原理深度解析:从Vue 2到Vue 3的演进
103 17
|
2月前
|
前端开发 JavaScript 测试技术
Vue3中v-model在处理自定义组件双向数据绑定时,如何避免循环引用?
Web 组件化是一种有效的开发方法,可以提高项目的质量、效率和可维护性。在实际项目中,要结合项目的具体情况,合理应用 Web 组件化的理念和技术,实现项目的成功实施和交付。通过不断地探索和实践,将 Web 组件化的优势充分发挥出来,为前端开发领域的发展做出贡献。
62 8
|
2月前
|
存储 JavaScript 数据管理
除了provide/inject,Vue3中还有哪些方式可以避免v-model的循环引用?
需要注意的是,在实际开发中,应根据具体的项目需求和组件结构来选择合适的方式来避免`v-model`的循环引用。同时,要综合考虑代码的可读性、可维护性和性能等因素,以确保系统的稳定和高效运行。
54 1
|
2月前
|
JavaScript
Vue3中使用provide/inject来避免v-model的循环引用
`provide`和`inject`是 Vue 3 中非常有用的特性,在处理一些复杂的组件间通信问题时,可以提供一种灵活的解决方案。通过合理使用它们,可以帮助我们更好地避免`v-model`的循环引用问题,提高代码的质量和可维护性。
60 1
|
2月前
|
JavaScript
在 Vue 3 中,如何使用 v-model 来处理自定义组件的双向数据绑定?
需要注意的是,在实际开发中,根据具体的业务需求和组件设计,可能需要对上述步骤进行适当的调整和优化,以确保双向数据绑定的正确性和稳定性。同时,深入理解 Vue 3 的响应式机制和组件通信原理,将有助于更好地运用 `v-model` 实现自定义组件的双向数据绑定。