lengyingmofeng

1. 邂逅Vuejs

1.1 简单认识一下Vuejs

Vue是一个渐进式的框架,什么是渐进式呢?

  • 渐进式意味着你可以将Vue作为应用的一部分嵌入其中,带来更丰富的交互体验
  • 或者你希望将更多的业务逻辑使用Vue实现,那么Vue核心库以及其生态系统。
  • 比如Core+Vue-router-Vuex,也可以满足你各种各样的需求。

Vue有很多特点和Web开发中常见的高级功能

  • 解耦试图的数据
  • 可复用的组件
  • 前端路由技术
  • 状态管理
  • 虚拟Dom

这些特点,你不需要一个个去记住,我们在后面的学习和开发中都会慢慢体会到的

学习Vuejs的前提?

  • 从零学习Vue,并不需要你具备其他类似与Angular、React,甚至JQuery的经验
  • 但是你需要具备一定的HTML、CSS、JavaScript基础

1.2 安装Vuejs

安装Vue的方式有很多:

  1. 直接CDN引入

    • CDN

      对于制作原型或学习,你可以这样使用最新版本:
      <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
      对于生产环境,我们推荐链接到一个明确的版本号和构建文件,以避免新版本造成的不可预期的破坏:
      <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
      
    • 你可以选择引入开发环境版还是生成环境版本

      <!-- 开发环境版本,包含了有帮助的命令行警告 -->
      <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
      <!-- 生产环境版本,优化了尺寸和速度 -->
      <script src="https://cdn.jsdelivr.net/npm/vue"></script>
      
    • NPM安装

      后续通过webpack和CLI的使用,我们使用改方式

1.3. Hello Vuejs

我们来做一个Vue程序,体验一下Vue的响应式

我们来阅读JavaScript代码,会发现创建了一个Vue对象

创建Vue对象的时候,传入了一些options:{}

  • {}中包含了el属性:该属性决定了这个Vue对象挂载到了哪一个元素上,很明显,我们这里挂载了id为app的元素上
  • {}中包含了data属性:该属性中通常会存储一些数据
    • 这些数据可以是我们直接定义出来的,比如想上面这样。
    • 也可能来自网络,服务器加载的

代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">{{messages}}</div>
<script src="../js/vue.js"></script>
<script>
    <!--  编程方式:声明式编程  -->
    let app = new Vue({
        el: '#app', // 用于挂载管理的元素
        data: {
            message: 'Hello Vue js!'
        }
    });
//    元素js的做法(编程方式:命令式编程)
//    1.创建div元素,设置id属性
//    2.定一个变量叫message
//    3.将message变量放在前面的div元素中显示
</script>
</body>
</html>

浏览器显示

image-20210512220500740

什么是命令式编程和声明式编程:

命令式编程:命令“机器”如何去做事情(how),这样不管你想要的是什么(what),它都会按照你的命令实现。

声明式编程:告诉“机器”你想要的是什么(what),让机器想出如何去做(how)。

详细:https://www.cnblogs.com/sirkevin/p/8283110.html

1.4. 创建Vue实例传入的Options

你会发现,我们在创建Vue实例的时候,传入了一个对象options

详细请访问:https://cn.vuejs.org/v2/api/#选项-DOM

目前掌握这些选项:

  • el:
    • 类型string | Element
    • 限制:只在用 new 创建实例时生效。
    • 作用:决定之后Vue实例会管理哪一个DOM
    • 详细https://cn.vuejs.org/v2/api/#el
  • data:
    • 类型Object | Function
    • 限制:组件的定义只接受 function
  • methods:
    • 类型{ [key: string]: Function }
    • 作用:定义属于Vue的一些方法,可以在其他地方调用,也可以在指令中使用
    • 详细https://cn.vuejs.org/v2/api/#methods

1.5. Vue的生命周期

生命周期:事物从诞生到消亡的整个过程

vue每个组件都是独立的,每个组件都有一个属于它的生命周期,从一个组件创建、数据初始化、挂载、更新、销毁,这就是一个组件所谓的生命周期。在组件中具体的方法有:

beforeCreate

created

beforeMount

mounted

(

​ beforeUpdate

​ updated

)

beforeDestroy

destroyed

生命周期流程图:

img

详细:https://www.jianshu.com/p/410b6099be69

1.6 设置Vue的template(模板)

  1. 打开Webstorm

    image-20210513133634369

  2. 找到Editor-> Live Template - >Vue

    image-20210513133746863

  3. 进行设置 (Abbreviation: 缩写词, Description: 说明)

    image-20210513133835115

    <div id="app">{{message}}</div>
    <script src="../js/vue.js"></script>
    <script>
      let app = new Vue({
        el: '#app', 
        data: {
          message: 'Hello Vue js!'
        }
      });
    </script>
    
  4. 点击Change

    image-20210513134030331

  5. OK

2. 基本语法

2.1 插值操作

如何将data中的文件数据,插入到HTML中呢?

  • 可以通过Mustache语法(也就是双大括号)
  • Mustache:胡子/胡须
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="app">
  <p>{{message}}</p>
  <p>{{firstName}} {{lastName}}</p>
  <p>{{firstName + lastName}}</p>

</div>
<script src="../js/vue.js"></script>
<script>
  let app = new Vue({
    el: '#app',
    data: {
      message: 'Hello Vue js!',
      firstName: '不能说的秘密',
      lastName: '周杰伦'
    }
  });
</script>
</body>
</html>

image-20210513192402503

image-20210513192018658

2.2 指令

v-once

在某些情况下,我们可能不希望界面随意的随意改变

  • 这个时候,我们就可以使用Vue的指令

v-once:

  • 改指令后面不需要跟如何表达式
  • 该指令表达元素和其他组件只渲染一次,不会随着数据改变而改变

代码:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="app">
  <p v-once>{{message}}</p>
</div>
<script src="../js/vue.js"></script>
<script>
  let app = new Vue({
    el: '#app',
    data: {
      message: 'Hello Vue js!',
    }
  });
</script>
</body>
</html>

v-html

某些情况下,我们从服务器请求到的数据本身就是一个HTML代码

  • 如果我们直接通过{{}}来输出,会将HTML代码也一起输出
  • 但是我们可能希望的是按照HTML进行解析,并且显示对应的数据内容

如果我们希望解析出HTML展示可以使用v-html指令

  • 该指令后面往往会将跟上一个string类型
  • 会将string的html解析出来并且进行渲染

代码:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="app">
  <p v-once>{{message}}</p>
  <p>{{url}}</p>
    // 使用v-html进行渲染
  <p v-html="url"></p>
</div>
<script src="../js/vue.js"></script>
<script>
  let app = new Vue({
    el: '#app',
    data: {
      message: 'Hello Vue js!',
      url: '<a href="https://cn.vuejs.org/v2/guide/">官网</a>'
    }
  });
</script>
</body>
</html>

image-20210513193725507

v-text

v-pre

v-cloak(cloak:斗篷)

3. 绑定属性

3.1 v-bind

某些属性我们也希望动态来绑定。

  • 比如动态绑定a元素的href属性
  • 比如动态绑定img元素的src属性

这个时候,我们可以使用v-bind指令:

  • 作用:动态绑定属性
  • 缩写::
  • 预期: any fwith argument)I Object(without argument)
  • 参数:attrOrProp(optional)

我们如果直接使用musttache语法进行绑定的话,会出现下面的情况

image-20210513195244662

image-20210513195412087

正确的使用方式是通过v-bind,让标签进行进行动态绑定达到我们想要的效果

image-20210513200212672

代码:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="app">
  <!-- 错误的做法:这里不能使用mustache语法 -->
<!--  <img src="{{img}}" alt="">-->
  <!-- 正确的使用方式 -->
  <img v-bind:src="img" alt=""><br>
  <a v-bind:href="href">哔哩哔哩</a>
<!-- 语法糖使用方式 -->
  <a :href="href"></a>
  <img :src="img" alt="">
</div>
<script src="../js/vue.js"></script>
<script>
  let app = new Vue({
    el: '#app',
    data: {
      message: 'Hello Vue js!',
      img: "https://cn.vuejs.org/images/logo.png",
      href: "https://www.bilibili.com/"
    }
  });
</script>
</body>
</html>

动态绑定class

当然我们也可以使用v-bind进行动态绑定class

image-20210513201902662

效果:

image-20210513201951496

通过console来更改Boolean值

image-20210513202005639

上面那种写法会让人感觉到不是很友好,我们可以使用函数来封装

image-20210513203120591

代码:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <style>
    .active{
        color: skyblue;
    }
  </style>
</head>
<body>
<div id="app">
  <!--
      {}表示是一个对象
      {key1: value1, key2: value2}
      {类名1:boolean, 类型2: boolean}
   -->
  <!-- 两个标量都为true时,样式才会生效 -->
  <h2 v-bind:class="{active: isActive, line: isLine}">{{message}}</h2>
  <!-- 上面那种写法会让人感觉到不是很友好,我们可以使用函数来封装 -->
  <h2 v-bind:class="">{{message}}</h2>
  <!-- 使用v-on指令进行动态绑定事件,后面我们会学习到 -->
  <button v-on:click="btnClick">按钮</button>
</div>
<script src="../js/vue.js"></script>
<script>
  let app = new Vue({
    el: '#app',
    data: {
      message: 'Hello Vue js!',
      isActive: true,
      isLine: true
    },

    methods: {
      btnClick: function(){
        this.isActive = !this.isActive
      },
      getClass: function() {
        return {active: this.isActive, line: this.isLine}
      }

    }
  });
</script>
</body>
</html>

image-20210513204809830

动态绑定style

在写CSS属性的时候,比如font-size

  • 我们可以使用驼峰式
  • 或者短横线分隔font-size(但是记得加单引号括起来)

实例图:

image-20210513204918506

效果图:

image-20210513204937059

也可以使用变量名来进行

image-20210513205336218

效果图:

image-20210513205358168

代码:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="app">
<!--  <h2 :style="{key(属性名): value(属性值)}"></h2>-->
  <!-- 50px必须加单引号, 否则当做一个变量去解析 -->
  <h2 :style="{fontSize: '50px'}">{{message}}</h2>
  <!-- 使用font-size必须加单引号 -->
  <h2 :style="{'fontSize': '50px'}">{{message}}</h2>
  <!-- finalSize当成一个变量使用 -->
  <h2 :style="{fontSize: finalSize + 'px'}">{{message}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
  let app = new Vue({
    el: '#app',
    data: {
      message: 'Hello Vue js!',
      finalSize: 100
    }
  });
</script>
</body>
</html>

3.2 计算属性

基本使用

我们知道,在模板中可以直接通过插值语法显示一些data中的数据。

但是在某些情况,我们可能需要对数据进行一些转化后再显示,或者需要将多个数据结合起来进行显示

  • 比如我们有firstName和lastName两个变量,我们需要显示完整的名称。

  • 但是如果多个地方都需要显示完整的名称,我们就需要写多个

基本使用:

image-20210513211216765

效果图:

image-20210513211228456

复杂操作:

image-20210513212220412

结果:

image-20210513212247646

代码:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="app">
  {{totalPrice}}
</div>
<script src="../js/vue.js"></script>
<script>
  let app = new Vue({
    el: '#app',
    data: {
      books:[
        {id:110, name: 'Java', price: 100},
        {id:111, name: 'Python', price: 100},
        {id:112, name: 'Vue', price: 100},
        {id:113, name: 'C', price: 100},
      ]
    },
    // computed: 计算机属性()
    computed:{
      totalPrice: function (){
        let result = 0
        for (let i = 0; i < this.books.length; i++) {
           result += this.books[i].price;
        }
        return resultA
        // 这两种是es6语法当中的
      //   for (let i in this.books) {
      //     result += this.books[i].price
      //   }
      //   for (let book of this.books) {
      //     result += book.price
      //   }
      }
    }
  });
</script>
</body>
</html>

3.3 computed和methods的对比

你可能已经注意到我们可以通过在表达式中调用方法来达到同样的效果:

<p>Reversed message: "{{ reversedMessage() }}"</p>
// 在组件中
methods: {
  reversedMessage: function () {
    return this.message.split('').reverse().join('')
  }
}

我们可以将同一函数定义为一个方法而不是一个计算属性。两种方式的最终结果确实是完全相同的。然而,不同的是计算属性是基于它们的响应式依赖进行缓存的。只在相关响应式依赖发生改变时它们才会重新求值。这就意味着只要 message 还没有发生改变,多次访问 reversedMessage 计算属性会立即返回之前的计算结果,而不必再次执行函数。

这也同样意味着下面的计算属性将不再更新,因为 Date.now() 不是响应式依赖:

computed: {
  now: function () {
    return Date.now()
  }
}

相比之下,每当触发重新渲染时,调用方法将总会再次执行函数。

我们为什么需要缓存?假设我们有一个性能开销比较大的计算属性 A,它需要遍历一个巨大的数组并做大量的计算。然后我们可能有其他的计算属性依赖于 A。如果没有缓存,我们将不可避免的多次执行 A 的 getter!如果你不希望有缓存,请用方法来替代。

总结:

computed:会进行缓存,如果多次使用时,计算属性只会调用一次。

methods: 调用一次执行一次

3.4 v-on

概述:
在前端开发中,我们需要经常和用于交互。

  • 这个时候,我们就必须监听用户发生的时间,比如击、拖拽、键盘事件等等
  • 在Vue中如何监听事件呢?使用v-on指令v-on介绍

v-on介绍:

  • 作用:绑定事件监听器
  • 缩写:@
  • 预期:Function |Inline Statement|Object
  • 参数:event

基本使用

image-20210514152517666

上面这种方法,适合简单的事件绑定,如果我们有其他的功能实现这种写法就不太好,所以我推荐下面这种写法

image-20210514152900191

当然,也可以用语法糖的方式进行编写

image-20210514152957124

代码:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="app">
  <h2>{{number}}</h2>
  <!-- 简单的使用 click:鼠标点击事件 -->
<!--  <button v-on:click="number++">+</button>-->
<!--  <button v-on:click="number&#45;&#45;">-</button>-->
<!--  <button v-on:click="increment">+</button>-->
<!--  <button v-on:click="decrement">-</button>-->
  <button @:click="increment">+</button>
  <button @:click="decrement">-</button>
</div>
<script src="../js/vue.js"></script>
<script>
  let app = new Vue({
    el: '#app',
    data: {
      message: 'Hello Vue js!',
      number: 10 // 定义一个参数
    },
    methods:{
      increment() {
        this.number++
      },
      decrement() {
        this.number--
      }
    }
  });
</script>
</body>
</html>

v-on还可以进行传参数

image-20210514154932579

如果你需要传递参数就记得添加(),如果你不需要传递参数就不用添加()

image-20210514155154847

如果不知道什么是MouseEvent对象的话:

https://blog.csdn.net/claroja/article/details/103990202

代码:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="app">
  <!-- 传递参数 -->
  <button @click="btnClick(123)">按钮1</button>
<!-- 如果方法定义了一个参数,我们这里不传递参数的话,它会传递一个MouseEvent对象 -->
  <button @click="btnClick">按钮2</button>
  <!-- 我们这里加了括号没有传递参数的话,形参就是undefined-->
  <button @click="btnClick()">按钮3</button>

</div>
<script src="../js/vue.js"></script>
<script>
  let app = new Vue({
    el: '#app',
    data: {
      message: 'Hello Vue js!'
    },
    methods: {
      btnClick(name) {
        console.log(name)
      }
    }
  });
</script>
</body>
</html>

v-on的修饰符:

  • .stop - 调用event.stopPropagation()
  • .prevent - 调用event.preventDefault()
  • .{keyCode | keyAlias} 只当时间是从特定键触发时才触发回调
  • .native - 监听组件根元素的原生事件
  • .once - 只触发一次回调

基本使用:

image-20210514161424397

效果图:

image-20210514161509466

如果我们想组织这种冒泡事件可以使用.stop

image-20210514161611243

效果图:

image-20210514161621844

代码:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="app">
  <div @click="divClick">
    aaa
    <!--  当我们点击这个按钮时,它会出现冒泡事件  -->
    <button @click.stop="btnClick">按钮</button>
  </div>
</div>
<script src="../js/vue.js"></script>
<script>
  let app = new Vue({
    el: '#app',
    data: {
      message: 'Hello Vue js!'
    },
    methods: {
      btnClick() {
        console.log("btnClick")
      },
      divClick() {
        console.log("divClick")
      }
    }
  });
</script>
</body>
</html>

4. 条件判断

4.1 v-if v-else-if v-else

v-if 指令用于条件性地渲染一块内容。这块内容只会在指令的表达式返回true 值的时候被渲染。

基本使用:

image-20210514162527417

效果图:

image-20210514162855046

image-20210514162913593

v-else的使用

image-20210514163151073

效果图:

image-20210514163202247

代码:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="app">
  <h1 v-if="isShow">{{message}}</h1>
  <h1 v-else>isShow为false的时候你才能看到我</h1>
  <button @click="isShow_function">按钮</button>
</div>
<script src="../js/vue.js"></script>
<script>
  let app = new Vue({
    el: '#app',
    data: {
      message: 'Hello Vue js!',
      isShow: true
    },
    methods: {
      isShow_function() {
        this.isShow = !this.isShow
        console.log(this.isShow)
      }
    }
  });
</script>
</body>
</html>

4.2 v-show

v-show和v-if非常相似,也用于决定一个元素是否渲染

v-if和v-show对比

  • v-if和v-show都可以决定一个元素是否渲染,那么开发中我们如何选择?

    • v-if当条件为false时,压根不会有对应的元素在DOM中
    • v-show当条件为false时,仅仅是将元素的display属性设置为none而已
  • 开发中如何选择?

    • 当需要在显示与隐藏之间切片很频繁时,使用v-show
    • 但只有一次切换时,使用v-if

    基本使用:

    image-20210514164411046

效果图:

image-20210514164425942

代码:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="app">
  <!-- v-if当条件为false时,压根不会有对应的元素在DOM中 -->
  <p v-if="isShow">{{message}} v-if</p>
  <!-- v-show为false时,仅仅是将元素的display属性设置为none而已 -->
  <p v-show="isShow">{{message}} v-show</p>
</div>
<script src="../js/vue.js"></script>
<script>
  let app = new Vue({
    el: '#app',
    data: {
      message: 'Hello Vue js!',
      isShow: true
    }
  });
</script>
</body>
</html>

5. 循环遍历

5.1 v-for

当我们有一组数据需要渲染时,我们就可以使用v-for

  • v-for的语法类似于JavaScript中的for循环
  • 格式:item in itmes的形式

如果在遍历的过程中,我们需要拿到元素在数组的中的索引值

  • 语法格式: v-for = (item, index) in items
  • 其中的index就代表了取出的item在原数组中的索引值

基本使用:

image-20210514165328625

效果图:

image-20210514165339356

当然也可以遍历对象

image-20210514165820453

效果图:

image-20210514165832190

如果想拿到key的话,可以这样:

image-20210514170030270

效果图:

image-20210514170038110

注意:遍历数组拿下标,item在前,index在后, 遍历对象拿key的话, values在前, key在后

6.表单绑定

6.1 v-model

Vue中使用v-model指令来实现表单元素和数据的双向绑定

image-20210514205554777

效果图:

image-20210514205604277

代码:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="app">
  <input type="text" v-model="message">
  {{message}}
</div>
<script src="../js/vue.js"></script>
<script>
  let app = new Vue({
    el: '#app',
    data: {
      message: 'Hello Vue js!'
    }
  });
</script>
</body>
</html>

v-model其实是一个语法糖,他的背后本质上是包含两个操作:

  • v-bind绑定一个value属性
  • v-on指令给当前元素绑定input事件

image-20210514205927500

代码:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="app">
  <input type="text" v-bind:value="message" v-on:input="message=$event.target.value">
</div>
<script src="../js/vue.js"></script>
<script>
  let app = new Vue({
    el: '#app',
    data: {
      message: 'Hello Vue js!'
    }
  });
</script>
</body>
</html>

我们可以使用v-model结合radio使用:

image-20210514210438944

效果图:

image-20210514210450467

也可以配合checkbox:

image-20210514210933800

效果图:

image-20210514210949517

代码:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="app">
  <input type="checkbox" value="LXL" v-model="hobbies">LXL
  <input type="checkbox" value="LOL" v-model="hobbies">LOL
  <input type="checkbox" value="LkL" v-model="hobbies">LKL
  <input type="checkbox" value="LPL" v-model="hobbies">LPL
  <br>
  <h2>你的爱好:{{hobbies}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
  let app = new Vue({
    el: '#app',
    data: {
      message: 'Hello Vue js!',
      hobbies: []
    }
  });
</script>
</body>
</html>

6.2 值绑定

值绑定的意思就是给value赋值

  • 我们前面的value中的值,可以回头看一下,都是在定义input的时候直接给定的
  • 但是真实开发中,这些input的值可能是从网络获取或定义data中的
  • 所以我们可以通过v-bind:value动态给value绑定值

image-20210514212235158

代码:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="app">
  <input type="checkbox" value="LXL" v-model="hobbies">LXL
  <input type="checkbox" value="LOL" v-model="hobbies">LOL
  <input type="checkbox" value="LkL" v-model="hobbies">LKL
  <input type="checkbox" value="LPL" v-model="hobbies">LPL
  <br>
  <h2>你的爱好:{{hobbies}}</h2>
<!-- 我们通过v-for循环遍历my_hobbies并且生成input标签 在通过v-bind绑定值 -->
  <label v-for="item in my_hobbies" :for="item">
    <!--  我们在通过v-bind绑定item所遍历的值, 在通过v-model进行双向绑定  -->
    <input type="checkbox" :value="item" v-model="hobbies">{{item}}
  </label>
</div>
<script src="../js/vue.js"></script>
<script>
  let app = new Vue({
    el: '#app',
    data: {
      message: 'Hello Vue js!',
      hobbies: [],
      my_hobbies: ['LXL', 'LOL', 'LKL', 'LPL']
    }
  });
</script>
</body>
</html>

6.3 修饰符

lazy修饰符:

  • lazy修饰符可以让数据在失去焦点或者回车时才会更新

number修饰符:

  • number修饰符可以让在输入框中输入的内容自动转成数字类型

trim修饰符:

  • trim修饰符可以过滤内容左右两边的空格

7. 组件化开发

7.1 什么是组件化?

人面对复杂问题的处理方式:

  • 任何一个人处理信息的逻辑能力都是有限的
  • 所以,当面对一个非常复杂的问题时,我们不太可能一次性搞定一大堆的内容。
  • 但是,我们人有一种天生的能力,就是将问题进行拆解。
  • 如果将一个复杂的问题,拆分成很多个可以处理的小问题,再将其放在整体当中,你会发现大的问题也会迎刃而解。

组件化也是类似的思想:

  • 如果我们将一个页面中所有的处理逻辑全部放在一起,处理起来就会变得非常复杂,而且不利于后续的管理以及扩展。
  • 但如果,我们讲一个页面拆分成一个个小的功能块,每个功能块完成属于自己这部分独立的功能,那么之后整个页面的管理和维护就变得非常容易了。

image-20210514213558620

7.2 Vue组件化思想

组件化是Vue.js中的重要思想

  • 他提供了一中抽象,让我们可以开发出一个个独立可复用的小组件来构造我们的应用

  • 任何的应用都会被抽象成一颗组件树

    Component Tree

组件化思想的应用:

  • 有了组件化的思想,我们在之后的开发中就要充分的利用它
  • 尽可能的将页面拆分成一个个小的、可复用的组件
  • 这样让我们的代码更加方便组织和管理,并且扩展性也更强

7.3 组件化的基本步骤

  1. 创建组件构造器

    Vue.extend0:

    • 调用Vue.extend0创建的是一个组件构造器。
    • 通常在创建组件构造器时,传入template代表我们自定义组件的模板。
    • 该模板就是在使用到组件的地方,要显示的HTML代码。
    • 事实上,这种写法在Vue2.x的文档中几乎已经看不到了,它会直接使用下面我们会讲到的语法糖,但是在很多资料还是会提到这种方式,而且这种方式是学习后面方式的基础。
  2. 注册组件

    Vue.component():

    • 调用Vue.component0是将刚才的组件构造器注册为一个组件,并且给它起一个组件的标签名称。

    • 所以需要传递两个参数:1、注册组件的标签名 2、组件构造器

  3. 使用组件

    • 组件必须挂载在某个Vue实例下,否则它不会生效。

image-20210514214218082

image-20210514221232821

效果图:

image-20210514221245174

代码:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="app">
<!-- 使用组件 -->
  <my-cpn></my-cpn>
</div>
<script src="../js/vue.js"></script>
<script>
<!-- 1.创建组件构造器对象 -->
  const cpnC = Vue.extend({
    template: `
    <div>
      <h2>我是标题</h2>
      <p>我是内容1</p>
      <p>我是内容2</p>
    </div>
    `
  })
  // 2. 注册组件
  Vue.component('my-cpn', cpnC)
  let app = new Vue({
    el: '#app',
    data: {
      message: 'Hello Vue js!'
    }
  });
</script>
</body>
</html>

7.4 全局组件和局部组件

我们上面创建的就是全局组件,全局组件就是可以在多个Vue实例里面使用

image-20210515104805783

效果图:

image-20210515104918977

那么我们如何创建局部组件? 其实创建局部组件也很简单,把要注册的组件放到某个Vue实例里面注册就好了

image-20210515105554781

效果图:

image-20210515105614009

我们会发现标签只在

里面有效,这就是局部组件

代码:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="app">
  <cpn></cpn>
  <cpn></cpn>
</div>

<div id="app1">
  <cpn></cpn>
</div>
<script src="../js/vue.js"></script>
<script>
  <!-- 1.创建组件构造器对象 -->
  const cpnC = Vue.extend({
    template: `
    <div>
      <h2>我是标题</h2>
      <p>我是内容1</p>
      <p>我是内容2</p>
    </div>
    `
  })
  // 注册组件(意味着可以在多个Vue实例中使用)
  // Vue.component("my-cpn", cpnC)

  // 如何注册局部组件?
  // 我们只需要在某个Vue实例里面注册即可
  let app = new Vue({
    el: '#app',
    data: {
      message: 'Hello Vue js!'
    },
    // components:组件,component的复数,表示可以使用多次
    components: {
      // cpn:使用组件的标签名
      cpn: cpnC
    }
  });
  // 创建一个vue实例
  let app1 = new Vue({
    el: '#app1'
  })
</script>
</body>
</html>

7.5 父组件和子组件

什么是父组件,什么又是子组件。简单来说:我们把某段代码封装成了一个组件,而这个段组件里面又引入另一个组件,我们把引入封装的组件叫做父组件,把被引入的组件叫做子组件

image-20210515112959373

效果图:

image-20210515113026145

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="app">
  <cpn></cpn>
</div>
<script src="../js/vue.js"></script>
<script>
<!-- 注册子组件 -->
  const cpnC2 = Vue.extend({
    template: `
     <div>
      <h2>我是子组件</h2>
      <p>我是子组件的内容</p>
    </div>
    `
  })
  // 注册父组件
  const cpnC1 = Vue.extend({
    template: `
    <div>
      <h2>我是父组件</h2>
      <p>我是父组件的内容</p>
<!--  // 但解析到这一步的时候,它会先去你Vue实例components里面找你是否注册了cpn2-->
<!--  // 如果没有找到他才会在cpnC1components去找-->
      <cpn2></cpn2>
    </div>
    `,
    // 把子组件注册到父组件
    components: {
      cpn2: cpnC2
    },
  })
  let app = new Vue({
    el: '#app',
    data: {
      message: 'Hello Vue js!'
    },
    components: {
      cpn: cpnC1
    }
  });
</script>
</body>
</html>

7.6 注册组件的语法糖方式

我们之前注册组件的方式,会觉得有些繁琐

  • Vue为了简化这个过程,提供了注册的语法糖
  • 主要是省去了调佣Vue.extend()的步骤,而是可以直接使用一个对象来替换

image-20210515114939573

效果图:

image-20210515114949705

代码:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="app">
  <!-- 使用组件 -->
  <cpn></cpn>
</div>
<script src="../js/vue.js"></script>
<script>
  // component会跳用Vue.extend来创建组件
  // 所以我们以后可以使用这种语法糖模式来创建全局组件
  Vue.component('my-cpn', {
    template: `
    <div>
      <h2>组件</h2>
      <p>组件的内容</p>
    </div>
    `
  })
  let app = new Vue({
    el: '#app',
    data: {
      message: 'Hello Vue js!'
    },
    //  局部组件
    components: {
      cpn:{
        template: `
        <div>
          <h2>组件</h2>
          <p>组件的内容</p>
        </div>
    `
      }
    }
  });
</script>
</body>
</html>

7.7 组件模板抽离

我们之前虽然简化了Vue组件的注册过程,另外还有一个地方的写法比较麻烦,就是template模板的写法

如果我们能将其中的html分离出来写,然后挂载到对应的组件上,必然结构会变得非常清晰

Vue提供了两种方案来定义HTML模块内容:

  • 使用标签
  • 使用

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2021-11-30
  • 2021-06-20
  • 2021-08-24
  • 2021-04-17
  • 2022-01-06
相关资源
相似解决方案