Veam
文章20
标签4
分类10
vue的基础之路(组件(component)使用)

vue的基础之路(组件(component)使用)

vue的常规使用

一、vue官方支持的开发模式——SPA

1、什么是SPA 单页面Web应用

  • vue官方支持的开发模式-SPA(Single Page Application)单页面WEB应用
  • 一个应用只有一张页面==》index.html SPA

2、为什么支持单页面开发?

维护vue效率使用效用问题

img

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

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

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

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

4、vue官方提供 组件技术

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

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

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

img

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

img

(2)全局组件具体使用

  • 1.开发全局组件
/*
  新建登录全局组件:
  * 参数一:当前全局组件的名字
    参数二:当前全局组件的配置对象
  * */
  Vue.component("login",{
  // 组件对应标签内容
    template:`<form>
              姓名:<input type="text" value="">
              密码:<input type="text" value="">
              <input type="submit" value="登录">
              </form>`
  })

1234567891011121314
  • 2.使用全局组件 在Vue实例范围内
<login></login>  
1

(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:{
     "组件名":{
        //组件的配置对象
     }
    }
   })
1234567891011

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

img

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

img

  • 不加div效果图

img

(2)两种开发方式

  • 第一种开发方式
//局部组件登录模板声明
let login ={   //具体局部组件名称
  template:'<div><h2>用户登录</h2></div>'
};
const app = new Vue({
  el: "#app",
  data: {},
  methods: {},
  components:{  //用来注册局部组件
    login:login  //注册局部组件 es6的新特性可以直接写login,也可以的
  }
});

//局部组件使用 在Vue实例范围内
<login></login>
123456789101112131415
  • 第二种开发方式
//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>
12345678910111213141516171819202122

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

总结:
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属性发生变化,组件内部数据跟着变化
123456789101112131415161718192021

(3) prop的单向数据流

单向数据流:所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定 :父级 prop 的更新会向下流动到子组件中,但是反过来则不行。

img

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

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364

img

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

在这里插入图片描述

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

2.组件中事件定义

 const login={
        template:'<div><input type="button" value="点我触发组件中事件" @click="change"></div>',
        data(){
            return {
                name:'王恒杰'
            };
        },
        methods:{
            change(){
                alert(this.name)
                alert('触发事件');
            }
        }
    }
1234567891011121314
# 总结  

    1.组件中定义事件和直接在Vue中定义事件基本一致 
      直接在组件内部对应的html代码上加入@事件名=函数名方式即可
      
    2.在组件内部使用methods属性用来定义对应的事件函数即可,
      事件函数中this 指向的是当前组件的实例
1234567

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

img

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

img

  • 后续发布vue博客相关内容
    🍅 Vue学习之路(基础篇)
    🍅 vue的学习之路(Axios 基本使用)
    🍅 vue的学习之路(Vue 生命周期)
    🍅 vue的学习之路(Vue中组件(component)
    🍅 vue的学习之路(Vue中路由 (Vue Router))
    🍅 vue的学习之路(Vue CLI 脚手架)
    🍅 vue的学习之路(VueX 状态管理)
    🍅 vue的学习之路(Vue创建项目)

学习完这篇文章请移动到下一步

本文作者:Veam
本文链接:https://github.com/veam23/lonely0323.github.io/2022/09/04/vue.component/
版权声明:本文采用 CC BY-NC-SA 3.0 CN 协议进行许可
×