在学习vue的学习之路(Vue中组件(component )之前,建议先学习
Vue学习之路(基础篇)
vue实现购物车功能
vue的学习之路(Axios 基本使用)
vue的学习之路(Vue 生命周期)
SpringBoot+mybatis+Vue实现前后端分离小项目
一、vue官方支持的开发模式——SPA
1、什么是SPA 单页面Web应用
vue官方支持的开发模式-SPA(Single Page Application)单页面WEB应用
一个应用只有一张页面==》index.html SPA
2、为什么支持单页面开发?
维护vue效率使用效用问题
3、按照SPA开发模式进行 存在问题
1、主页面代码过多 不利于管理 后续维护
2、vue实例需要一起初始化页面内容,可能会降低vue效率
3、功能展示过多 用户体验差
4、vue官方提供 组件技术
(1)一个组件负责一组功能 实现组件之间的隔离
(2) 组件还可以实现复用
(3)减少vue实例对象中代码量
二、vue中的组件
1、组件作用
Vue中组件 (component[kəmˈpoʊnənt])
组件作用: 用来减少Vue实例对象中代码量,日后在使用Vue开发过程中,可以根据 不同业务功能将页面中划分不同的多个组件,然后由多个组件去完成整个页面的布局,便于日后使用Vue进行开发时页面管理,方便开发人员维护。
2、组件分类
全局组件 直接注册给vue实例
局部组件 注册给vue实例中的compents属性 只能在vue中使用
3、全局组件注册
说明:全局组件注册给Vue实例,日后可以在任意Vue实例的范围内使用该组件
(1)全局组件使用案例
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>全局组件的定义</title> </head> <body> <div id="app"> {{msg}} <hr/> <!--使用全局组件 在vue实例中配置对象--> <login></login> </div> </body> </html> <script src="../js/vue-min.js"></script> <script src="../js/axios.min.js"></script> <script> <!-- 1.开发全局组件--> /* 新建登录全局组件: * 参数一:当前全局组件的名字 参数二:当前全局组件的配置对象 * */ Vue.component("login",{ // 组件对应标签内容 template:`<form> 姓名:<input type="text" value=""> 密码:<input type="text" value=""> <input type="submit" value="登录"> </form>` }) //vue代码 new Vue({ el: "#app", //vue的实例作用范围 data: { //vue中定义的一系列数据 msg:"全局组件的定义" }, methods:{ } }); </script>
(2)全局组件具体使用
1.开发全局组件
/* 新建登录全局组件: * 参数一:当前全局组件的名字 参数二:当前全局组件的配置对象 * */ Vue.component("login",{ // 组件对应标签内容 template:`<form> 姓名:<input type="text" value=""> 密码:<input type="text" value=""> <input type="submit" value="登录"> </form>` })
2.使用全局组件 在Vue实例范围内
<login></login>
(3)注意事项:
1.Vue.component用来开发全局组件
参数1: 组件的名称
参数2: 组件配置{} template:’'用来书写组件的html代码 template中必须有且只有一个root元素
2.使用时需要在Vue的作用范围内根据组件名使用全局组件
3.如果在注册组件过程中使用 驼峰命名组件的方式 在使用组件时 必须将驼峰的所有单词小写加入-线进行使用
4、局部组件注册
说明:通过将组件注册给对应Vue实例中一个components属性来完成组件注册,这种方式不会对Vue实例造成累加
语法
new Vue({ el:"#app", data:{}, methods:{}, computed:{}, components:{ "组件名":{ //组件的配置对象 } } })
(1)局部组件注册案例
<body> <div id="app"> {{msg}} <hr> <!--使用局部组件--> <login></login> <!--注册--> <hr/> <register></register> </div> </body> </html> <script src="../js/vue-min.js"></script> <script> //vue代码 new Vue({ el: "#app", //vue的实例作用范围 data: { //vue中定义的一系列数据 msg:"局部组件" }, components:{ login:{ //其中添加div的意义就是让remplate标签有一个根标签,否则只展示“欢迎进入登录程序” template:` <div> <center>欢迎进入登录程序</center> <form> 姓名:<input type="text" value=""> 密码:<input type="text" value=""> <input type="submit" value="登录"> </form> </div>` }, register:{ template: ` <form> 姓名:<input type="text" value=""> 密码:<input type="text" value=""> <input type="submit" value="注册"> </form> ` } } }) </script>
注意:其中添加div的意义就是让template标签有一个根标签 ,否则只展示“欢迎进入登录程序”
不加div效果图
(2)两种开发方式
第一种开发方式
//局部组件登录模板声明 let login ={ //具体局部组件名称 template:'<div><h2>用户登录</h2></div>' }; const app = new Vue({ el: "#app", data: {}, methods: {}, components:{ //用来注册局部组件 login:login //注册局部组件 es6的新特性可以直接写login,也可以的 } }); //局部组件使用 在Vue实例范围内 <login></login>
第二种开发方式
//1.声明局部组件模板 template 标签 注意:在Vue实例作用范围外声明 <template id="loginTemplate"> <h1>用户登录</h1> </template> //2.定义变量用来保存模板配置对象 let login ={ //具体局部组件名称 template:'#loginTemplate' //使用自定义template标签选择器即可 }; //3.注册组件 const app = new Vue({ el: "#app", data: {}, methods: {}, components:{ //用来注册局部组件 login:login //注册局部组件 } }); //4.局部组件使用 在Vue实例范围内 <login></login>
5、Prop的使用
作用:props用来给组件传递相应静态数据或者是动态数据的
(1)通过在组件上声明静态数据传递给组件内部
//1.声明组件模板配置对象 let login = { template:"<div><h1>欢迎:{{ userName }} 年龄:{{ age }}</h1></div>", props:['userName','age'] //props作用 用来接收使用组件时通过组件标签传递的数据 } //2.注册组件 const app = new Vue({ el: "#app", data: {}, methods: {}, components:{ login //组件注册 } }); //3.通过组件完成数据传递 <login user-name="王恒杰" age="23"></login>
总结:
1.使用组件时可以在组件上定义多个属性以及对应数据
2.在组件内部可以使用props数组生命多个定义在组件上的属性名
3.日后可以在组件中通过{{ 属性名 }} 方式获取组件中属性值
(2)通过在组件上声明动态数据传递给组件内部
//1.声明组件模板对象 const login = { template:'<div><h2>欢迎: {{ name }} 年龄:{{ age }}</h2></div>', props:['name','age'] } //2.注册局部组件 const app = new Vue({ el: "#app", data: { username:"小陈陈", age:23 }, methods: {}, components:{ login //注册组件 } }); //3.使用组件 <login :name="username" :age="age"></login> //使用v-bind形式将数据绑定Vue实例中data属性,日后data属性发生变化,组件内部数据跟着变化
(3) prop的单向数据流
单向数据流:所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定 :父级 prop 的更新会向下流动到子组件中,但是反过来则不行。
所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定 :父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外改变父级组件的状态,从而导致你的应用的数据流向难以理解。
额外的,每次父级组件发生更新时,子组件中所有的 prop 都将会刷新为最新的值。这意味着你不 应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在浏览器的控制台中发出警告。—摘自官网
(4)父组件向局部组件传递静态数据
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>v-model指令</title> </head> <body> <div id="app"> {{msg}} <login></login> </div> </body> </html> <script src="../js/vue-min.js"></script> <script> const login={ template:` <div> <h1>登录组件</h1> {{name}}----{{count}}---{{ countSqrt}} <button @click="incrCount()">点我count+1</button> </div> `, // 在组件中定义数据 data(){ return{ name:"王恒杰", count:10 } }, // 定义组件自己的函数 methods: { incrCount(){ this.count++; } }, computed:{ countSqrt(){ //计算属性当方法用 return this.count*this.count; } }, // 声明周期函数 created(){ console.log("当前组件数据初始化完成!"); } } //vue代码 new Vue({ el: "#app", //vue的实例作用范围 data: { //vue中定义的一系列数据 msg:"组件其他属性的定义" }, methods:{ }, components: { login:login } }) </script>
(5)父组件向局部组件传递动态数据
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>v-model指令</title> </head> <body> <div id="app"> <!-- 传递:父组件 在子组件调用处 以键值对的形式传递数据 数据要绑定交给vue实例进管理 接收:子组件 在props属性值以指定的键接收即可 注意:官方规定数据流是单选下行绑定,建议从父组件向子组件传递数据,但是不支持子组件修改父组件的数据状态 --> {{msg}} <login name="王恒杰" :msg="msg" :count="count"></login> </div> </body> </html> <script src="../js/vue-min.js"></script> <script> const login={ template:`<div><h3>登录组件</h3>{{name}}--{{msg}}--{{subCount}} <button @click="countAdd">点击count+10</button></div>` ,data(){ return{ subCount:this.count } }, props:["name","msg","count"], methods: { countAdd(){ //props里面的值相当于data里面的值 this.subCount+=10; } } } //vue代码 new Vue({ el: "#app", //vue的实例作用范围 data: { //vue中定义的一系列数据 msg:"父组件向局部组件传递动态数据", count:0 }, methods:{ }, components:{ login } }) </script>
6、组件中定义数据和事件使用
1. 组件中定义属于组件的数据
<body> <div id="app"> <!-- 1、传递 以键值对的形式 定义在局部组件的调用处 2、局部组件 核心:接收 props属性 props:[传递数据时的键] 注意:使用props属性接收的值 就相当于在data中定义对应的内容{key:value} --> {{msg}} <login name="王恒杰" msg="{{msg}}"></login> </div> </body> </html> <script src="../js/vue-min.js"></script> <script> const login={ template:`<div><h3>登录组件</h3>{{name}}</div>`, props:["name"], data(){ return{ name:this.name } } } //vue代码 new Vue({ el: "#app", //vue的实例作用范围 data: { //vue中定义的一系列数据 msg:"父组件向局部组件传递静态数据" }, methods:{ }, components:{ login } }) </script>
2.组件中事件定义
const login={ template:'<div><input type="button" value="点我触发组件中事件" @click="change"></div>', data(){ return { name:'王恒杰' }; }, methods:{ change(){ alert(this.name) alert('触发事件'); } } }
# 总结 1.组件中定义事件和直接在Vue中定义事件基本一致 直接在组件内部对应的html代码上加入@事件名=函数名方式即可 2.在组件内部使用methods属性用来定义对应的事件函数即可, 事件函数中this 指向的是当前组件的实例
7、向子组件中传递事件并在子组件中调用该事件(子组件向父组件传递数据)
在子组件中调用传递过来的相关事件必须使用 this.$emit('函数名') 方式调用
(1)子组件调用父组件,并向父组件传递数据
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>v-model指令</title> </head> <body> <div id="app"> <button @click="sup()">点我触发父组件事件</button> {{msg}} <!-- 父组件向子组件传递事件 传递:在子组件调用处使用 @事件在子组件的名字=“要传递的事件的名字” --> <login @sup="sup"></login> </div> </body> </html> <script src="../js/vue-min.js"></script> <script> <!--定义组件对象--> const login={ template:`<div><h3>登录组件</h3><button @click="sub()">点我触发子组件事件</button> </button></div>` ,methods: { sub(){ console.log("这是子组件的单机事件") // 调用父组件的功能 sup 参数一:要触发的事件名 this.$emit("sup") } } } //vue代码 new Vue({ el: "#app", //vue的实例作用范围 data: { //vue中定义的一系列数据 msg:"父组件向子组件传递事件" }, methods:{ sup(){ console.log("这是父组件的单机事件") } }, components:{ login } }) </script>
(2)子组件向父组件传递对象
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>v-model指令</title> </head> <body> <div id="app"> <button @click="sup()">点我触发父组件事件</button> {{user}} <hr/> {{msg}} <hr/> <!-- 父组件向子组件传递事件 传递:在子组件调用处使用 @事件在子组件的名字=“要传递的事件的名字” --> <login @sup="sup"></login> </div> </body> </html> <script src="../js/vue-min.js"></script> <script> <!--定义组件对象--> const login={ template:`<div><h3>登录组件</h3><button @click="sub()">点我触发子组件事件</button> </div>` ,methods: { sub(){ console.log("这是子组件的单机事件") // 调用父组件的功能 sup 参数一:要触发的事件名 //调用组件传递过来的其他函数时需要使用 this.$emit('函数名调用') this.$emit("sup",{name:"王恒杰",age:"21",content:"秋招完成!"}) } } } //vue代码 new Vue({ el: "#app", //vue的实例作用范围 data: { //vue中定义的一系列数据 msg:"父组件向子组件传递事件", user:{} }, methods:{ sup(user){ //一个事件函数 将这个函数传递给子组件 console.log("这是父组件的单机事件"); console.log(user) this.user=user; } }, components:{ login //组件的注册 } }) </script>
后续发布vue博客相关内容
🍅 Vue学习之路(基础篇)
🍅 vue的学习之路(Axios 基本使用)
🍅 vue的学习之路(Vue 生命周期)
🍅 vue的学习之路(Vue中组件(component)
🍅 vue的学习之路(Vue中路由 (Vue Router))
🍅 vue的学习之路(Vue CLI 脚手架)
🍅 vue的学习之路(VueX 状态管理)