当前位置: 首页 > news >正文

Vue组件相关记录

Vue组件开发

非单文件组件

创建组件api Vue.extend({})

    const student = Vue.extend({template: `<div>{{studentName}} - {{age}}</div>`,data() {return {studentName: 'jjking',age: 12}}})new Vue({el: '#app',//局部注册components: {student: student}})

不能使用el,因为按理来说,组件不应该固定挂载谁,
并且data返回的是函数,不能写成对象

局部注册
在components里边

使用就是用<student></student>

全局注册
Vue.component('student',student);
前面是组件名,后面是组件

注意事项
组件名相关问题

组件名在开发者工具中,都是首字母大写的

一个单词组成: 大小写都可以
school
School

但是组件注册的时候写什么名字,你的标签就得写什么名字,避免出错

局部注册
多个单词组成:
第一种写法(kebab-case命名):my-school
第二种写法(CamelCase命名):MySchool (需要Vue脚手架支持)

其他,我们可以使用name来指定开发者工具里边的呈现的名字,所以只是为了好看,我么实际用还是用注册用的名字

关于组件的本质

  1. school组件的本质是VueComponent的构造函数,每次vm会帮助我们创建一个全新的VueComponent,但是这样的工作不用我们程序员干
  2. 关于this的指向
    (1) 在组件中,this指向组件实例对象
    (2) 在vm中,指向的是Vue实例对象

一个重要的内置关系

在这里插入图片描述

vc的prototype.__proto__ 指向的是Vue的原型对象

也就是vc可以访问到Vue原型对象上的属性和方法

换个意思讲,如果我们在Vue的原型对象上写了一个属性,我们在vc中可以拿得到

单文件组件

默认来看,生成一个vue组件是
const a = Vue.extend({options})

但是我们写单文件组件的时候

<template><div><h2>学校名称: {{name}}</h2><h2>学校地址: {{address}}</h2></div>
</template><script>
export default {name: 'School',data() {return {name: '光景',address: '白云区'}}
} 
</script><style></style>

export的时候,是直接抛出一个{}也就是一个对象,这里是简写的形式
const a = options
在app页面中,我们导入一个组件的时候,他会自动识别

组件通信

父子组件通信

父传子 -> props

子传父(初级用法)
例如父亲是app.vue
儿子是MyHeader.vue

父组件发一个函数给儿子
儿子在这个函数中把要传的数据传给父亲

准确的说,儿子把要传的数据传到这个函数的参数上

App.vue

<!-- 头部 -->
<MyHeader :addTodo="addTodo"></MyHeader>...
methods: {addTodo(todoObj) {// console.log('我是App组件,我收到了数据x',todoObj);this.todoList.unshift(todoObj)}
}

子组件是MyHeader

export default {name: 'MyHeader',props: ['addTodo'],methods: {add(e) {const todoObj = ...;this.addTodo(todoObj);}}
}

这个方法十分的诡异,但是确实是可以用的

组件自定义事件 子 -> 父

子传父,我们可以通过props 父亲给儿子传递一个函数,儿子在合适的时候触发这个事件,父亲就可以收到儿子传递过来的数据

这里的小项目就是为了说明组件自定义事件的,非常小的项目
父亲是app.vue
儿子分别是student.vue 和 school.vue

App.vue

<template><div class="app"><h1>{{msg}}</h1><School/><Student/></div>
</template><script>import Student from './components/Student'import School from './components/School'export default {name:'App',components:{School,Student},data() {return {msg:'你好啊!',}}}
</script><style scoped>.app{background-color: gray;padding: 5px;}
</style>

Student.vue

<template><div class="student"><h2>学生姓名:{{name}}</h2><h2>学生性别:{{sex}}</h2></div>
</template><script>export default {name:'Student',data() {return {name:'张三',sex:'男',}},}
</script><style scoped>.student{background-color: pink;padding: 5px;margin-top: 30px;}
</style>

School.vue

<template><div class="school"><h2>学校名称:{{name}}</h2><h2>学校地址:{{address}}</h2></div>
</template><script>export default {name:'School',props:['getSchoolName'],data() {return {name:'Tom学校',address:'北京',}}}
</script><style scoped>.school{background-color: skyblue;padding: 5px;}
</style>

页面显示

在这里插入图片描述

props传

props传当然是最为简陋的方式,并且传的是,函数
在App.vue上,我们绑定一个函数来接收来自儿子的数据

<School :getSchoolName="getStudentData"/>
...
methods: {getStudentData(data) {console.log('App组件收到了来自儿子的事件',data);}}

在子组件上,我们在合适的时机来触发这个事件,把数据传回App.vue
School.vue

        <!-- 通过props,子传父数据 --><button @click="sendSchoolName">点我发送给父亲app.vue数据</button>...```bashprops:['getSchoolName'],data() {return {name:'Tom学校',address:'北京',}},methods: {sendSchoolName() {this.getSchoolName(this.name)}}

这样的写法,实在称不上好,但是能用

绑定自定义事件

通过v-on绑定自定义事件

我们给组件绑定绑定自定义事件
在App.vue上

<School v-on:jjking="getStudentData"/>
...
methods: {getStudentData(data) {console.log('App组件收到了来自儿子的事件',data);}
}

这个自定义事件是在vc上的,触发条件就是我们在子组件调用
this.$emit('自定义事件名换',data)

这个emit,意思就是发射,就像子组件发射数据到父组件一样,实际上,也是触发父组件的方法

在这里就是在子组件中,我们绑定了一个事件叫做jjking
我们子组件只要触发这个jjking事件就行

事件的回调方法叫做getStudentData

在子组件

<!-- 通过自定义事件$emit触发父亲给儿子绑定的事件 -->
<button @click="sendSchoolName">点我发送给父亲app.vue数据</button>
...
methods: {sendSchoolName() {this.$emit('jjking',this.name)}
}

通过ref绑定自定义事件

<!-- 通过ref绑定自定义事件 -->
<School ref="student"/>methods: {getStudentData(data) {console.log('App组件收到了来自儿子的事件',data);}
},
mounted() {this.$refs.student.$on('jjking',this.getStudentData)
}

this.$refs.student 其实就是组件vc我们在这上面绑定jjking自定义事件,回调函数时this.getStudentData

相比看下来,其实第一种绑定的方式更为简单,但为什么我们要用ref来绑定呢,原因是这样子会更加的灵活

例如我们如果想要触发3秒之后,再启用getStudentData的回调函数,此时第一种方式就直接写死了,模版解析到<School/>组件的时候,啪一下,就执行了回调函数了,然而我们通过ref来绑定,我们可以直接直接写

mounted() {setTimeout(() => {this.$refs.student.$on('jjking',this.getStudentData)},3000)
}

如果我们想要触发一次,我们就可以换成$once

mounted() {this.$refs.student.$once('jjking', this.getStudentData)
}

注意:

这里的this.getStudentData不能写成普通的函数类似于下面这样

    this.$refs.student.$on('jjking', function getStudentData(data) {console.log('App组件收到了来自儿子的事件', data);})

眼下看的时候没有问题,但是如果涉及到this的操作的话,就会出问题,这里的this不再是App这个组件了,而是他的儿子组件School.vue,原因是在Vue中,谁触发了事件,this就指向谁,此时this就是School的vc

这里的解决办法就是我们可以写箭头函数,因为箭头函数没有this,他的this会去外边一层去找this的指向,所以这里的this会找到mounted的this

而vue中,已经把mounted的this指向指向了App,所以箭头函数是不会出bug的

触发事件时传递多个参数

// 方式一school.vue
<script>methods: {sendStudentlName(){this.$emit('atguigu',this.name,666,888,900)},},
</script>app.vue
<script>methods: {getStudentName(name,x,y,z){console.log('App收到了学生名:',name,x,y,z)},},}
</script>
开发中的方式
// 方式一 :把数据包装成一个对象传递过去
school.vue
<script>methods: {sendStudentlName(){this.$emit('atguigu',{})},},
</script>// 方式二:es6 写法  正常传递,接收
school.vue
<script>methods: {sendStudentlName(){this.$emit('atguigu',this.name,666,888,900)},},
</script>app.vue
<script>methods: {// name 正常结构,其他的参数不管传递多少,整理到params数组上getStudentName(name,...params){console.log('App收到了学生名:',name,params)},},}
</script>

要么参数一个一个写,要么用...params这是es6的语法

解绑自定义事件

<!-- 解绑自定义事件 -->
<button @click="unbind">点我解绑自定义事件</button>unbind() {this.$off('jjking')// this.$off(['jjking','demo']) //解绑多个自定义事件// this.$off() //解绑所有的自定义事件
}

组件绑定事件默认不使用内置事件

// 这么写会被默认当做自定义事件
<Student ref="student" @click="show"/> //加上native 原生的,本来的,才会使用到内置事件
<Student ref="student" @click.native="show"/> 

必须写native才行

总结

在这里插入图片描述


http://www.mrgr.cn/news/80347.html

相关文章:

  • 【CSS in Depth 2 精译_079】第 13 章:渐变、阴影与混合模式概述 + 13.1:CSS 渐变效果(一)——使用多个颜色节点
  • python请求SSL问题
  • 深入分析 Java 中的 NoSuchMethodException 异常及解决方法
  • Gitlab ci/cd 从0-1持续集成持续发布前端
  • Android显示系统(11)- 向SurfaceFlinger申请Surface
  • Transformer记录Attention is all you need
  • 怎么写英语作文(个人笔记)
  • Unity中Mesh重叠顶点合并参考及其应用
  • chromedriver可运行的docker环境
  • etcd常见运维事件
  • 【electron】electron forge + vite + vue + electron-release-server 自动更新客户端
  • tryhackme-Pre Security-Defensive Security Intro(防御安全简介)
  • ragflow连不上ollama的解决方案
  • 【Golang】如何读取并解析SQL文件
  • ensp 单臂路由配置
  • CAD c# 生成略缩图预览
  • 计算机网络-传输层 TCP协议(下)
  • YOLOv9改进,YOLOv9引入DLKA-Attention可变形大核注意力,WACV2024,二次创新RepNCSPELAN4结构
  • 拿到小米 Offer,却迷茫了。。
  • 《数据结构》(408代码题)