vue的学习之路(Vue中组件(component )

简介: vue的学习之路(Vue中组件(component )

在学习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效率使用效用问题

image.png



3、按照SPA开发模式进行 存在问题

1、主页面代码过多 不利于管理 后续维护


2、vue实例需要一起初始化页面内容,可能会降低vue效率


3、功能展示过多 用户体验差


4、vue官方提供 组件技术

(1)一个组件负责一组功能 实现组件之间的隔离


(2) 组件还可以实现复用


(3)减少vue实例对象中代码量


image.png


二、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>


image.png

(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>

image.png

注意:其中添加div的意义就是让template标签有一个根标签 ,否则只展示“欢迎进入登录程序”


image.png

不加div效果图

image.png


(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 的更新会向下流动到子组件中,但是反过来则不行。


image.png


所有的 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>

image.png


(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>

image.png

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>

image.png

(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>

image.png

后续发布vue博客相关内容

🍅 Vue学习之路(基础篇)

🍅 vue的学习之路(Axios 基本使用)

🍅 vue的学习之路(Vue 生命周期)

🍅 vue的学习之路(Vue中组件(component)

🍅 vue的学习之路(Vue中路由 (Vue Router))

🍅 vue的学习之路(Vue CLI 脚手架)

🍅 vue的学习之路(VueX 状态管理)


相关文章
|
11天前
|
缓存 JavaScript 前端开发
vue学习第四章
欢迎来到我的博客!我是瑞雨溪,一名热爱JavaScript与Vue的大一学生。本文介绍了Vue中计算属性的基本与复杂使用、setter/getter、与methods的对比及与侦听器的总结。如果你觉得有用,请关注我,将持续更新更多优质内容!🎉🎉🎉
27 1
vue学习第四章
|
11天前
|
JavaScript 前端开发
vue学习第九章(v-model)
欢迎来到我的博客,我是瑞雨溪,一名热爱JavaScript与Vue的大一学生,自学前端2年半,正向全栈进发。此篇介绍v-model在不同表单元素中的应用及修饰符的使用,希望能对你有所帮助。关注我,持续更新中!🎉🎉🎉
23 1
vue学习第九章(v-model)
|
11天前
|
JavaScript 前端开发 开发者
vue学习第十章(组件开发)
欢迎来到瑞雨溪的博客,一名热爱JavaScript与Vue的大一学生。本文深入讲解Vue组件的基本使用、全局与局部组件、父子组件通信及数据传递等内容,适合前端开发者学习参考。持续更新中,期待您的关注!🎉🎉🎉
24 1
vue学习第十章(组件开发)
|
17天前
|
JavaScript 前端开发
如何在 Vue 项目中配置 Tree Shaking?
通过以上针对 Webpack 或 Rollup 的配置方法,就可以在 Vue 项目中有效地启用 Tree Shaking,从而优化项目的打包体积,提高项目的性能和加载速度。在实际配置过程中,需要根据项目的具体情况和需求,对配置进行适当的调整和优化。
|
17天前
|
存储 缓存 JavaScript
在 Vue 中使用 computed 和 watch 时,性能问题探讨
本文探讨了在 Vue.js 中使用 computed 计算属性和 watch 监听器时可能遇到的性能问题,并提供了优化建议,帮助开发者提高应用性能。
|
17天前
|
存储 缓存 JavaScript
如何在大型 Vue 应用中有效地管理计算属性和侦听器
在大型 Vue 应用中,合理管理计算属性和侦听器是优化性能和维护性的关键。本文介绍了如何通过模块化、状态管理和避免冗余计算等方法,有效提升应用的响应性和可维护性。
|
17天前
|
存储 缓存 JavaScript
Vue 中 computed 和 watch 的差异
Vue 中的 `computed` 和 `watch` 都用于处理数据变化,但使用场景不同。`computed` 用于计算属性,依赖于其他数据自动更新;`watch` 用于监听数据变化,执行异步或复杂操作。
|
16天前
|
JavaScript 前端开发 UED
vue学习第二章
欢迎来到我的博客!我是一名自学了2年半前端的大一学生,熟悉JavaScript与Vue,目前正在向全栈方向发展。如果你从我的博客中有所收获,欢迎关注我,我将持续更新更多优质文章。你的支持是我最大的动力!🎉🎉🎉
26 3
|
18天前
|
存储 JavaScript 开发者
Vue 组件间通信的最佳实践
本文总结了 Vue.js 中组件间通信的多种方法,包括 props、事件、Vuex 状态管理等,帮助开发者选择最适合项目需求的通信方式,提高开发效率和代码可维护性。
|
16天前
|
JavaScript 前端开发 开发者
vue学习第一章
欢迎来到我的博客!我是瑞雨溪,一名热爱JavaScript和Vue的大一学生。自学前端2年半,熟悉JavaScript与Vue,正向全栈方向发展。博客内容涵盖Vue基础、列表展示及计数器案例等,希望能对你有所帮助。关注我,持续更新中!🎉🎉🎉
36 2