Vue实战之Vue中组件(component)

文章目录

  • Vue 实战
    • 十二、Vue 中组件(component)
      • 1、组件作用
      • 2、组件使用
        • (1)全局组件祖册
        • (2)局部组件注册(用的最多)
        • (3)Vue组件中定义data、methods、computed、生命周期函数以及子组件
      • 3、Prop的使用
        • (1)Vue组件的数据传递之props(通过在组件上声明静态数据传递给组件内部)
        • (2)Vue组件的数据传递之props(通过在组件上声明动态数据传递给组件内部)
        • (3)Vue组件的数据传递之props(父组件向子组件传递动态数据之单向数据流)
      • 4、组件中定义数据和事件使用
        • (1)组件中定义属于组件的数据
        • (2)组件中事件定义
      • 5、Vue中父组件向子组件中传递事件并在子组件中调用该事件
      • 6、Vue组件中的插槽 slot
      • 7、es6基本语法及使用
      • 8、Vue标准开发方式
        • Vue推荐开发方式
        • 什么是 SPA 单页面应用
        • 为什么 Vue 推荐开发方式为 SPA 的开发方式
        • 使用现有手段严格遵循SPA存在的问题
        • 为了严格遵循 SPA 开发方式在Vue中提供了 Vue 组件 -- `Component`
      • 代码仓库


Vue 实战

十二、Vue 中组件(component)

1、组件作用

组件作用:用来减少Vue实例对象中代码量,日后在使用Vue开发过程中,可以根据不同业务功能将页面中划分为不同的多个组件,然后由多个组件去完成整个页面的布局,便于日后使用Vue进行开发时页面管理,方便开发人员维护。

Vue实战之Vue中组件(component)_第1张图片

2、组件使用

(1)全局组件祖册

说明:全局组件直接注册给Vue实例,日后可以在任意Vue实例的范围内使用该组件

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8"/>
    <title>Vue系列课程title>
head>
<body>
<div id="app">
    <h1>{{msg}}h1>
    
    
    <login>login>
    
    <register>register>
div>
body>
html>
<script src="js/vue.js">script>
<script>
    // 1.定义一个全局组件,参数1:组件名称 参数2:组件的配置对象
    Vue.component(`login`, {
        template: `

用户登录

`
}); Vue.component(`register`, { template: `

用户注册

`
}) var app = new Vue({ el: "#app", data: { msg: "Vue中组件之全局组件的使用" } })
script>

注意

  • Vue.component() :用来开发全局组件
    • 参数1:组件的名称
    • 参数2:组件配置{}对象
    • template·· 用来书写组件的 html 代码 template 中必须有且只有一个root元素
  • 使用时需要在Vue的作用范围内根据组件名称使用全局组件
  • 如果在注册组件过程中使用 驼峰命名组件的方式 在使用组件时 必须将驼峰的所有单词小写加入 - 线进行使用
  • 注意:无论使用全局组件还是局部组件都必须在组件template中加入唯一根元素

Vue实战之Vue中组件(component)_第2张图片

(2)局部组件注册(用的最多)

说明:通过将组件注册给对应Vue实例中一个 components 属性来完成组件注册,这种方式不会对Vue实例造成叠加

  • 第一种开发方式
DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8"/>
    <title>Vue系列课程title>
head>
<body>
<div id="app">
    <h1>{{msg}}h1>
    
    
    <login>login>
    
    <add>add>
div>
body>
html>
<script src="js/vue.js">script>
<script>
    // 局部组件登录模板声明
    let login = { // 具体局部组件名称
        template: `

用户登录

`
} const app = new Vue({ el: "#app", data: { msg: "Vue中组件之局部组件的使用" }, methods: {}, computed: {}, components: { // 用来注册局部组件 // login: login, // 简写 login, // 登录局部组件 add: { // 添加局部组件 template: `

用户添加

`
} } })
script>
  • 第二种开发方式
DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8"/>
    <title>Vue系列课程title>
head>
<body>
<div id="app">
    <h1>{{msg}}h1>
    
    
    <login>login>
div>

<template id="loginTemplate">
    <h1>用户登录h1>
template>
body>
html>
<script src="js/vue.js">script>
<script>
    //2.定义变量用来保存模板配置对象
    let login = {//具体局部组件名称
        template: `#loginTemplate` //使用自定义template标签选择器即可
    }
    const app = new Vue({
        el: "#app",
        data: {
            msg: "Vue中组件之局部组件的使用"
        },
        methods: {},
        computed: {},
        components: { //用来注册局部组件
            //login:login,
            //简写
            login, //3.注册组件
        }
    })
script>
(3)Vue组件中定义data、methods、computed、生命周期函数以及子组件

Vue实战之Vue中组件(component)_第3张图片

  • 代码如下
DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8"/>
    <title>Vue系列课程title>
head>
<body>
<div id="app">
    <h1>{{msg}}h1>
    
    <login>login>
    <register>register>
div>
body>
html>
<script src="js/vue.js">script>
<script>
    Vue.component('register', {
        template: `

我是注册

{{msg}}
`
, data() { return { msg: "我是注册全局组件中数据" } } }); //登录组件配置对象 const login = { template: `

用户登录

{{counter}}---{{msg}}---{{counterSqrt}}---{{counterSqrt}}----{{counterSqrt}}

`
, //用来书写组件html代码 data() { //用来给当前组件定义属于组件自己数据 组件中定义数据 data必须是一个函数 return { counter: 1, msg: "我是组件msg" } }, methods: { //用来给组件自己定义一系列方法 test(count) { this.counter += count; } }, computed: { //用来给组件自己定义一些列计算方法 counterSqrt() { return this.counter * this.counter; } }, //初始化阶段 beforeCreate() { console.log("beforeCreate:", this.msg); }, created() {//在这个函数执行时Vue实例对象已经存在自身内部事件和生命周期函数以及自定义data methods computed console.log("created:", this.msg); }, beforeMount() { //此时组件中template还是模板还没有渲染 console.log(this); //console.log("beforeMount:",this.$el.innerHTML); }, mounted() { // 此时组件中页面的数据已经和data中数据一致 console.log("mounted:", document.getElementById("aa").innerHTML); }, //运行阶段 beforeUpdate() {// 此时data中数据变化了 页面数据还是原始数据 console.log("beforeUpdate:", this.counter); console.log("beforeUpdate:", document.getElementById("aa").innerHTML); }, updated() { //此时data 页面数据一致 console.log("updated:", this.counter); console.log("updated:", document.getElementById("aa").innerHTML); }, //销毁阶段 beforeDestroy() { }, destroyed() { }, components: { aa: { //定义组件 template: '
我是aa子组件
'
}, } }; const app = new Vue({ el: "#app", data: { msg: "Vue的组件中定义组件data、methods、computed、生命周期函数以及子组件" }, methods: {}, computed: {}, components: { //用来定义局部组件 login, } })
script>

3、Prop的使用

定义:Vue中提供的一个特有的数据传递机制,props用来给组件传递相应静态数据或动态数据的

作用:在使用Vue组件时如果需要通过父组件给子组件传递数据可以通过 props 进行实现

(1)Vue组件的数据传递之props(通过在组件上声明静态数据传递给组件内部)
  • 代码示例一
DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vue之系列课程title>
head>
<body>
<div id="app">
    <h1>{{msg}}h1>
    
    
    <login username="小朱" age="21">login>
div>
body>
html>
<script src="js/vue.js">script>
<script>
    //1.声明组件模板配置对象
    const login = {
        template: `

欢迎:{{username}} 年龄:{{age}}

`
, props: ["username", "age"], //props作用 用来接收使用组件时通过组件标签传递的数据 } const app = new Vue({ el: "#app", data: { msg: "组件之间数据传递:通过在组件上声明静态数据传递给组件内部" }, methods: {}, computed: {}, components: {//注册组件 login,//2.注册局部组件 } })
script>
  • 代码示例二
DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vue之系列课程title>
head>
<body>
<div id="app">
    <h1>{{msg}}h1>

    

    
    <login title="我是标题" count="0">login>

div>
body>
html>
<script src="js/vue.js">script>
<script>

    //定义组件对象
    const login = {
        template: `

用户登录----{{title}}---{{loginTitle}}---{{count}}

`
, data() { return { // title:"我是子组件内部标题", //报错 因为已经props机制内已经有title了 相当于data中已经有了 // count:0, loginTitle: this.title, } }, props: ['title', 'count'],//用来接收父组件给当前组件传递数据 注意:props机制接收数据就相当于自己组件data中声明一个这样数据 }; const app = new Vue({ el: "#app", data: { msg: "组件之间数据传递:父组件向子组件传递静态数据" }, components: { //注册局部组件 login, //注册局部组件login } });
script>

总结

  • 在使用组件时可以在组件上定义多个属性以及对应数据
  • 在组件内部可以使用props数组声明多个定义在组件上的属性名 日后可以在组件中通过{{属性名}} 方式获取数组中属性值
(2)Vue组件的数据传递之props(通过在组件上声明动态数据传递给组件内部)
  • 代码示例一
DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vue之系列课程title>
head>
<body>
<div id="app">
    <h1>{{msg}}h1>
    
    
    <login :name="username" :age="age">login>
div>
body>
html>
<script src="js/vue.js">script>
<script>

    //1.声明组件模板对象
    const login = {
        template: `

欢迎:{{name}} 年龄:{{age}}

`
, props: ["name", "age"],//用来接收父组件给当前组件传递数据 注意:props机制接收数据就相当于自己组件data中声明一个这样数据 } const app = new Vue({ el: "#app", data: { msg: "组件之间数据传递:通过在组件上声明动态数据传递给组件内部", username: "小朱11", age: 21, }, methods: {}, computed: {}, components: {//注册组件 login,//2.注册局部组件 } })
script>
  • 代码示例二
DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vue之系列课程title>
head>
<body>
<div id="app">
    <h1>{{msg}}h1>
    

    
    <input type="text" v-model="name">
    <input type="text" v-model="msg">
    
    <login :name="name" :msg="msg">login>
div>
body>
html>
<script src="js/vue.js">script>
<script>

    //定义组件配置对象
    const login = {
        template: `

用户登录--{{name}}--{{msg}}

`
, props: ['name', 'msg'], } const app = new Vue({ el: "#app", data: { msg: "组件间数据传递:父组件向子组件传递动态数据", name: "我是vue实例管理数据", }, methods: {}, computed: {}, components: {//注册局部组件 login, } })
script>
(3)Vue组件的数据传递之props(父组件向子组件传递动态数据之单向数据流)
  • 单向数据流:所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。

  • 所有的 prop 都使得其父子prop之间形成了一个单向下行绑定:父级prop 更新会向下流动到子组件中,但是反过来则不行 这样会防止从子组件意外改变父级组件的状态 从而导致你的应用的数据流难以理解

  • 额外的,每次父级组件发生更新时,子组件中所有的prop都将会刷新为最新的值,这意味着你不应该在一个子组件内部改变prop。如果你这样做了,Vue会在浏览器的控制台中发出警告。

  • 代码示例如下
DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vue之系列课程title>
head>
<body>
<div id="app">
    <h1>{{msg}}h1>

    

    <input type="text" v-model="counter">
    
    <login :count="counter">login>
div>
body>
html>
<script src="js/vue.js">script>
<script>

    //声明组件配置对象
    const login = {
        template: `

用户登录--{{aaaCount}}

`
, data() { return { aaaCount: this.count } }, props: ['count'], methods: { incrmentCount() { console.log(this.count); this.aaaCount++; } } }; const app = new Vue({ el: "#app", data: { msg: "组件间数据传递", counter: 1, }, methods: {}, computed: {}, components: {//注册局部组件 login, }, })
script>

4、组件中定义数据和事件使用

(1)组件中定义属于组件的数据
DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vue之系列课程title>
head>
<body>
<div id="app">
    <h1>{{msg}}h1>
    
    <login>login>
div>
body>
html>
<script src="js/vue.js">script>
<script>

    //组件声明的配置对象
    const login = {
        template: `

{{msg}} 百度一下,你就知道

  • {{index+1}}. {{item}}
`
, data() {//使用data函数方式定义组件的数据 在templatehtml代码中通过插值表达式直接获取 return { msg: "hello", lists: ["java", "python", "c++", "ios"],//组件自己内部数据 } } } const app = new Vue({ el: "#app", data: { msg: "组件之间数据传递", }, methods: {}, computed: {}, components: {//注册组件 login,//注册局部组件 } })
script>
(2)组件中事件定义
DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vue之系列课程title>
head>
<body>
<div id="app">
    <h1>{{msg}}h1>

    
    <login>login>
div>
body>
html>
<script src="js/vue.js">script>
<script>

    //组件声明的配置对象
    const login = {
        template: `
`
, data() { return { name: "小朱", } }, methods: { change() { alert(this.name); alert("事件触发"); } } } const app = new Vue({ el: "#app", data: { msg: "组件之间数据传递", }, methods: {}, computed: {}, components: {//注册组件 login,//注册局部组件 } })
script>

总结

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

5、Vue中父组件向子组件中传递事件并在子组件中调用该事件

在子组件中调用传递过来的相关事件必须使用 this.$emit('函数名') 方式调用

  • 代码示例一
DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vue之系列课程title>
head>
<body>
<div id="app">
    
    
    <login @find="findAll" :name="name">login>
div>
body>
html>
<script src="js/vue.js">script>
<script>

    //1.声明组件
    const login = {
        template: "

百度一下 {{ uname }}

"
, data() { return { uname: this.name } }, props: ['name'], methods: { change() { //调用vue实例中函数 this.$emit('find'); //调用组件传递过来的其他函数时需要使用 this.$emit('函数名调用') } } } //2.注册组件 const app = new Vue({ el: "#app", data: { name: "小朱" }, methods: { findAll() { //一个事件函数 将这个函数传递给子组件 alert('Vue 实例中定义函数'); } }, components: { login,//组件的注册 } });
script>
  • 代码示例二
DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vue之系列课程title>
head>
<body>
<div id="app">
    <h1>{{msg}}  {{count}}h1>

    
    
    
    <login name="小朱" :msg="msg" @testParent="testParent" @bb="testHehe">login>
div>
body>
html>
<script src="js/vue.js">script>
<script>

    const login = {
        template: `

用户登录 --{{name}} --{{msg}}

`
, props: ['name', 'msg'], data() { return { count: 19, } }, methods:{ testChild(){ alert('我是子组件中定义事件'); //调用父组件中testParent事件 this.$emit('testparent');//这个方法用来调用父组件传递过来事件 参数1:调用事件名 注意大小写 testparent // this.$emit('bb',this.count,'xiaochen',true);//传递零散参数 this.$emit('bb',{count:this.count,name:"小李",sex:true});//传递对象 } } } const app = new Vue({ el: "#app", data: { msg: "组件间事件传递", count: 0, }, computed: {}, methods: { testParent() { alert("我是父组件上定义事件") }, testHehe(obj){ console.log("parent:","hehe"); console.log("parent:",obj); console.log("parent:",obj.count); console.log("parent:",obj.name); console.log("parent:",obj.sex); this.count = obj.count; } }, components: {//注册局部组件 login, }, })
script>

6、Vue组件中的插槽 slot

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vue之系列课程title>
head>
<body>
<div id="app">
    <h1>{{msg}} {{count}}h1>

    
    <login>login>
    <hr>

    <login><span slot="bb">欢迎进入我们网站span>login>


    <hr>
    <login><span slot="aa">welcome to website!!! {{msg}}span>login>
    <hr>

    <login>
        <button slot="aa" @click="incrmentCount()">点我button>
    login>
div>
body>
html>
<script src="js/vue.js">script>
<script>

    const login = {
        template: `
我是默认插槽

用户登录

`
}; const app = new Vue({ el: "#app", data: { msg: "组件的slot(插槽)", count: 0, }, methods: { incrmentCount() { this.count++; } }, components: { //注册局部组件 login, } });
script>

Vue实战之Vue中组件(component)_第4张图片

7、es6基本语法及使用

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vue之系列课程title>
head>
<body>
<div id="app">
    <h1>{{msg}}h1>
    
div>
body>
html>
<script src="js/axios.min.js">script>
<script src="js/vue.js">script>
<script>
    //es6 1.变量声明 var  原因:使用var声明变量存在作用范围混淆问题
    //              let     :用来声明局部变量  好处:作用范围严谨 从代码声明处开始 到代码块结束  一般在声明基本变量时使用 推荐使用let
    //              const   :用来声明js中常量 好处:一旦被赋值不能被修改  推荐使用这两个关键字声明变量  声明js中对象时推荐使用const

    //es6 2.在使用匿名函数时作为参数时候 function(){} 推荐使用es6中箭头函数 (参数,参数)=>{函数体}

    /*
    axios.get("url").then(function (res) {

    }).catch(function (err) {

    });
    */

    /*
    axios.get("url").then((res) => {

    }).catch((err) => {

    })
    */
    //注意:
    //1.当箭头函数没雨参数时或者参数大于1个,必须加入()
    //2.当箭头函数只有一个参数时 () 可以省略不写
    //3.当函数体中只有一行代码时 函数体 {} 可以省略不写
    //4.箭头函数和匿名函数的最大区别: 箭头函数没雨自己的this 匿名函数存在自己的this

    //es6 3.模板字符串  使用语法:
    let html = "" +
        "" +
        "" +
        "" +
        "" +
        "";

    let html1 = `

我是小黑

`
; console.log(html) console.log(html1) //es6 对象定义 便利:在定义对象时如果对象属性名和变量名一致,写一个即可。 let id = 21; let name = "小三"; let age = 23; // es5.x const emp = {id: id, name: name, age: age}; console.log(emp); // es6.x const emp1 = {id, name, age}; console.log("emp1", emp1); function test() { for (let i = 0; i < 10; i++) { console.log("for in", i); } //const name = "xiaosan"; //console.log(name); //name = "xiaoli"; //console.log("for out", i); //定义一个对象,const在定义对象时指的是对象的地址不变,对象中属性可以改变 const student = {id: 21, name: "xiaohong", age: 23}; console.log(student); student.name = "xiaoli"; console.log(student); student.age = 22; console.log(student); //定义一个数组,const在定义数组时指的是数组地址不能改变,但是数组中元素可以改变 const schools = ["北京", "天津"]; console.log(schools); schools.push("上海"); console.log(schools); } test();//调用函数 const app = new Vue({ el: "#app", data: { msg: "es6基本语法", }, methods: {} })
script>

8、Vue标准开发方式

Vue推荐开发方式

Vue推荐开发方式是 SPA :Single Page (Web)Application 单页面应用

Vue推荐开发方式是基于单页面应用 单页面web应用

什么是 SPA 单页面应用

单页面应用:就是日后项目中只有一张页面 ====> index.html

为什么 Vue 推荐开发方式为 SPA 的开发方式
  • 引入vue.js文件
  • 在现有页面中创建vue实例对象
  • 一个页面中只能存在一个Vue实例
  • Vue推荐开发方式要求:一个应用中只能存在一个Vue实例
使用现有手段严格遵循SPA存在的问题
  • 现有开发方式导致项目中唯一一个页面中代码越来越多不利于后续维护
  • 现有开发方式导致项目中唯一一个页面中完成全部业务功能,导致当前页面每次加载速度非常慢
为了严格遵循 SPA 开发方式在Vue中提供了 Vue 组件 – Component
  • Vue组件 component 减少Vue根实例代码量
  • 一个组件负责完成项目中一个功能或者一组功能实现业务功能隔离
  • 组件还可以在vue实例中实现复用

Vue实战之Vue中组件(component)_第5张图片

代码仓库

你可能感兴趣的:(vue)