Vue.js 2.0 学习笔记(二)初识Vue

Vue.js 2.0 学习笔记(二)初识Vue

文章目录

一、初认识Vue

  • Vue 是一个渐进式框架,何为渐进式
    • 渐进式意味着可以将Vue作为应用中的一部分嵌入其中,交互体验更丰富
    • 若希望将更多业务逻辑使用Vue实现,那Vue的核心库以及其生态环境如:Core+Vue-router+Vuex也可满足各种各样的需求
  • Vue的特点和Web开发中常见的高级功能
    • 解耦视图和数据

    • 可复用的组件

    • 前端路由技术

    • 状态管理

    • 虚拟DOM

  • Vue是声明式编程
  • Vue特性:
    • 数据驱动视图(单向数据绑定):当页面数据变化时,页面会重新加载
    • 双向数据绑定:在填写表单时,该特性可以辅助开发者在不操作DOM的前提下,自动把用户填写的内容同步到数据源中(form负责收集数据,Ajax负责提交数据)

1.1 MVX 模式

1.1.1 MVC

1. MVC 定义

       MVC 模式代表 Model-View-Controller(模型-视图-控制器) 模式。这种模式用于应用程序的分层开发。

  • Model(模型):表示应用程序核心(如数据库)

  • View(视图):视图代表模型包含的数据的可视化

    扫描二维码关注公众号,回复: 14744568 查看本文章
  • Controller(控制器):控制器作用于模型和视图上。它控制数据流向模型对象,并在数据变化时更新视图。它使视图与模型分离开

image-20211019223248669
image-20211019223315678

2. MVC设计模式

       MVC是多种设计模式的组合,组成MVC的三个模式分别是组合模式、观察者模式、策咯模式,MVC在软件开发中发挥的威力,最终离不开这三个模式的默契配合。

  • 组合模式:组合模式只在视图层活动,组合模式的类层次结构是树状的,例子:而我们做Web时视图层是html页面,html的结构就是树状的。

  • 观察者模式:观察者模式有两部分组成,被观察的对象和观察者,观察者也被称为监听者。对应到MVC中,Model是被观察的对象,View是观察者,Model层一旦发生变化,View层即被通知更新。

  • 策略模式:策略模式是View和Controller之间的关系,Controller是View的一个策略,Controller对于View是可替换的。

MVC各层之间关系所对应的设计模式:

  • View层:单独实现了组合模式

  • Model层和View层:实现了观察者模式

  • View层和Controller层:实现了策咯模式

       

1.1.2 MVP

       Model-View-Presenter ;MVP 是从经典的模式MVC演变而来

       MVP与MVC有着一个重大的区别:在MVP中View并不直接访问Model,它们之间的通信是通过Presenter 来进行的,所有的交互都发生在Presenter内部,Presenter 完全把 view 和 model 进行了分离Presenter 与具体的 view 是没有直接关联的,而是通过定义好的接口进行交互,从而在变更view时可以保证Presenter 不变
image-20211019224114722

1.1.3 MVVM

Vue.js 就是MVVM的代表框架。

image-20211026101810076

       View 的变化会自动更新到 viewModel,viewModel 的变化也会自动同步到view上显示。

       (ViewModel)视图模型是暴露公共属性和命令的视图的抽象。MVVM没有MVC模式的控制器,也没有MVP模式的presenter,有的是一个绑定器。在视图模型中,绑定器在视图和数据绑定器之间进行通信。其作用:一是将【模型】转化成【视图】,即将后端传递的数据转化成所看到的页面。实现的方式是:数据绑定。二是将【视图】转化成【模型】,即将所看到的页面转化成后端的数据。实现的方式是:DOM 事件监听。这两个方向都实现,我们称之为数据的双向绑定。

       

1. Vue中的MVVM

ViewModel 是 vue 的实例

image-20211026101824215

image-20211029123213007
       

2. Vue中代码与MVVM的对应关系

image-20211029123224842

       

二、基础语法及指令

2.1 插值操作

只能用在内容节点,不能用在属性节点

2.1.1 Mustache 语法

Mustache 语法中可以直接写变量,也可以写简单的表达式

<div id="app">
    <h2>Message:{
   
   {message}}</h2>
    <h2>{
   
   {firstName + '' + lastName}}</h2>
    <h2>{
   
   {firstName}} {
   
   {lastName}}</h2>
</div>

vue 允许在表达式后面添加过滤器,多个过滤器可以串联

{
   
   {example | filterA | filterB}}

注意:

  • Mustache 语法不能作用在 HTML attribute 上,遇到这种情况应该使用 v-bind

有时只需渲染一次数据,可以通过“*”实现

<span>text: {
   
   {*msg}}</span>

若为HTML片段:

<div>logo: {
   
   {
   
   {logo}}}</div>
logo:'<<span>hhh</span>>'

       

2.1.2 v-once 指令

<span v-once>这个将不会改变: {
   
   { msg }}</span>

注意:

  • 该指令后不需要任何表达式
  • 通过 v-once 指令,也能执行一次性插值。但该指令表示元素和组件只渲染一次,不会随着数据的改变而改变

       

2.1.3 v-html 指令

背景:某些情况下,从服务器请求的数据本身就是HTML,如果通过{ {}} 输出,输出的是HTML源代码,不会对其进行解析

  • v-html 指令后跟上一个 string
  • 指令会将 string 的 html页面解析并进行渲染
<h2 v-html='link'></h2>
// link :'<a> href = 'http://www.baidu.com'</a>'

       

2.1.4 v-text 指令

  • 跟mustache 相似:都是用于将数据显示在界面中
  • v-text接收一个string类型
<h2 v-text='message'></h2>

       

2.1.5 v-pre 指令

  • v-pre:用于跳过这个元素和其子元素的编译过程,用于显示原本的mustache语法,即其内容不会被解析
<p>{
   
   {message}}</p>   //hello world!   
<p v-pre>{
   
   {message}}</p>  //{
   
   {message}}

       

2.1.6 v-cloak 指令

       当网络较慢,网页还在加载 Vue.js ,而导致 Vue 来不及渲染,这时页面就会直接显示出未编译得Vue 源代码

<div id="app" v-cloak>
    {
   
   {context}}
</div>

<script>
    var app = new Vue({
      
      
        el: '#app',
        data: {
      
      
            context:'互联网头部玩家钟爱的健身项目'
        }
    });
</script>
[v-cloak]{
    
    
    display: none;
}

       

2.2 v-bind动态绑定属性

  • 作用:动态绑定一个或多个属性,或向另一个组件传递props值
  • 语法糖——
  • 案例:如绑定图片的src、网站链接的href,动态绑定一些类、样式
<div id="app">
    <a v-bind:href="">hhh</a>
    <img v-bind:src="" alt="">
</div>

<script>
    let app = new Vue({
      
      
        el:"#app",
        data: {
      
      
            logoURL:'https://vuejs.org/images/logo.png',
            link:'https://vuejs.org'
        }
    })
</script>

       

2.2.1 v-bind 绑定class

1. 绑定方法

  • 对象语法
用法一:直接通过{}绑定一个类
<h2 :class="{
     
     'active': isActive}">Hello World</h2>

用法二:通过判断,传入多个值
<h2 :class="{
     
     'active': isActive, 'line': isLine}">Hello World</h2>

用法三:和普通的类同时存在,并不冲突
<h2 class="title" :class="{
     
     'active': isActive, 'line': isLine}">Hello World</h2>

用法四:若过于复杂,可以放在一个methods或computed中
注意:classes是计算属性
<h2 class="title" :class="classes"></h2>
  • 数组语法(用的少)

    :class后跟的是一个数组

用法一:直接通过{}绑定一个类
<h2 :class="['active']}">Hello World</h2>

用法二:通过判断,传入多个值
<h2 :class="['active','line']">Hello World</h2>

用法三:和普通的类同时存在,并不冲突
<h2 class="title" :class="['active','line']">Hello World</h2>

用法四:若过于复杂,可以放在一个methods或computed中
注意:classes是计算属性
<h2 class="title" :class="classes"></h2>

       

2.2.2 v-bind 绑定style

  • 用 v-bind:style 来绑定一些内联样式

  • 写属性名时注意,如font-size:

    • 可以使用驼峰式: fontSize
    • 短横线分隔,记得用单引号括起来'font-size’
  • 绑定的方法:

    • 对象语法
    语法:
    :style ="{color:currentColor, fontSize:fontSize + "px"}"
    

    style后跟的是一个对象类型:

    1. 对象的key是CSS属性名称
    2. 对象的value是具体赋的值,值可以来自于data中的属性
    <h2 :style="{fontSize:'50px'}">Hello World</h2>
    

    注意:上面的50px一定要加单引号,不加单引号会被认为是变量,而变量名不能以数字开头就会报错,加了单引号是字符串,vue解析时会去掉单引号

    • 数组语法(用的少)
    :style="[baseStyles,overrideingStyles]"
    

    style后面跟的是一个数组类型

       

2.3 条件判断

2.3.1 v-if v-else-if v-else

  • 根据表达式的值在DOM中渲染或销毁元素或组件,若条件为false,则其对应的元素及其子元素不会渲染,对应的标签不会出现在DOM中
  • 逻辑叫复杂的最好用计算属性

案例:登录切换

需求:用户再次登录时,可以切换使用用户账号登录或邮箱地址登录

<div id="app">
    <span v-if="type === 'username'">
        <label for="">用户账号:</label>
        <input placeholder="用户账号">
    </span>
    <span v-else>
        <label for="">邮箱地址:</label>
        <input placeholder="邮箱地址">
    </span>
    <button @click="handleToggle">切换类型</button>
</div>

<script>
    let app = new Vue({
      
      
        el:"#app",
        data: {
      
      
            type:'username'
        },
        methods: {
      
      
            handleToggle() {
      
      
                this.type = this.type === 'email' ? 'email' : 'username';
            }
        }
    })
</script>
image-20211020185455203
<span v-if="isUser">
    <label for="username">用户账号:</label>
    <input type='text' id='username' placeholder="用户账号" key='username'>
</span>
<span v-else>
    <label for="">邮箱地址:</label>
    <input type='text' id='email' placeholder="邮箱地址" key='email'>
</span>
<button @click="isUser = !isUser">切换类型</button>

要点:添加了不同 key 的 input 就不会出现重复利用的情况

       

2.3.2 v-show

也用于决定一个元素是否渲染

v-if 和 v-show 对比

  • v-if 当条件为false时,压根不会有对应的元素在DOM中
  • v-show当条件为false时,仅仅是将元素的display属性设置为none而已。即DOM元素是创建了的,只是被隐藏了

开发中如何选择 v-if 和 v-show

  • 当需要在显示和隐藏之间切换很频繁时,用 v-show
  • 当只有少数次切换时,用 v-if

       

2.4 循环遍历

2.4.1 v-for遍历数组或对象

遍历数组:

<ul>
    <li v-for="item in names">{
   
   {item}}</li>
</ul>

// 遍历过程中获取索引值
<ul>
    <li v-for="(item, index) in names">
        {
   
   {index+1}}.{
   
   {item}}
    </li>
</ul>

<ul>
    <li v-for="item in names">
        {
   
   {$index}}-{
   
   {item}}
    </li>
</ul>

遍历对象:

<ul>
    <li v-for="(value,key) in info">{
   
   {value}}-{
   
   {key}}</li>
</ul>

<ul>
    <li v-for="(value,key,index) in info">{
   
   {value}}-{
   
   {key}}-{
   
   {index}}</li>
</ul>

要点:

  • 获取key 和 value 时,value在前,格式:(value,key)
  • 获取key 和 value 和 index时,格式:(value,key,index)
  • 不管是遍历对象还是数组,要获取index时,index总是放在最后,在for中未描述index 是,可以在内容中直接**使用 { {$index}} **获取index

       

2.4.2 v-for 绑定和非绑定key属性

<ul>
    <li v-for="item in letters" :key="item">{
   
   {value}}-{
   
   {key}}	 </li>
</ul>

​ 官方推荐在使用 v-for 时,给对应的元素或组件添加上一个key属性,给每个节点做唯一的标识,作用:

  • Diff算法就可以正确识别此节点
  • 可高效的更新虚拟DOM

       

2.4.3 数组中响应式的方法

  • 因为Vue是响应式的,所以当数据发生变化时,Vue会自动监测数据变化,视图会发生相应的更新
  • Vue中包含了一组观察数组编译的方法,使用它们改变数组也会触发视图的更新(响应式):
    • push()
    • pop()
    • shift()
    • unshift()
    • splice()
    • sort()
    • reverse()
//注意:通过索引值修改数组中的元素
this.letters[0] = 'hhhh'; // 非响应式
this.letters.splice(0, 1, 'hhhh'); //响应式
Vue.set(this.letters,0,'hhhh'); //响应式

       

2.4.4 函数式编程(高阶函数)

高阶函数:filter/reduce/map

(一)filter(过滤器)

要点:

1、filter中的回调函数必须返回布尔值,当返回true时,函数内部会自动将这次回调的值n加入到新的数组中;当但会false时,函数内部会过滤此次的值n

2、回调函数执行的次数为数组元素的个数

3、新数组自动生成,只需要一个变量去接收

const nums = [10,20,304,304,1204,221,45];

let newNums = nums.filter(function(n) {
    
    
    return n < 100;
})
console.log(newNums);

(二) map

let newNums2 = nums.map(function(n) {
    
    
    return n * 2;
})

(三)reduce

对数组中所有内容进行汇总:全部相加或者全部相乘

let total = nums.filter(n => n < 100).map(n => n*2).reduce((pre,n) => pre + n);

       

2.5 事件监听 v-on

  • 作用:用于绑定事件监听器
  • 语法糖:@
  • 参数:event
<div id="app">
    <h2>点击次数:{
   
   {counter}}</h2>
    <button v-on:click="counter++">按钮1</button>
    <button @click="btnClick">按钮2</button>
</div>

<script>
    let app = new Vue({
      
      
        el:"#app",
        data: {
      
      
            counter:0
        },
        methods: {
      
      
            btnClick() {
      
      
                this.counter++
            }
        }
    })
</script>

       

2.5.1 v-on 参数

​ 当通过methods中定义方法,以供@click调用,需要注意参数问题:

  • 情况一:若该方法不需要额外参数,那方法后的()可以不添加,若方法中本身由一个参数,那么会默认将原生事件event参数传递进去

  • 情况二:若需要同时传入某个参数,同时需要event时,可以通过$event传入事件

<div id="app">
    <h2>点击次数:{
   
   {counter}}</h2>
    <button @click="handleAdd"></button>
    <button @click="handleAddTen(10,$event)"></button>
</div>

<script>
    let app = new Vue({
      
      
        el:"#app",
        data: {
      
      
            counter:0
        },
        methods: {
      
      
            handleAdd(event) {
      
      
                this.counter++;
            },
            handleAddTen(count,event) {
      
      
                this.counter += count;
                if(count % 2 == 0) {
      
      
                    event.targer.style.background-color = 'red'
                }
            }
        }
    })
</script>

       

2.5.2 v-on 的修饰符

Vue提供修饰符来帮助我们处理一些事件:

  • .stop:调用event.stopPropagation()
  • .prevent:调用event.preventDefault()
  • .{keyCode | keyAlias}:只当事件是从特定键触发时才会触发回调
  • .native:监听组件根元素的原生事件
  • .once:只触发一次回调
<!-- 停止冒泡 -->
<button @click.stop="btnClick"></button>

<!-- 阻止默认行为 -->
<button @click.prevent="doThis"></button>

<!-- 阻止默认行为,无表达式 -->
<form @click.prevent></form>

<!-- 串联修饰符 -->
<button @click.stop.prevent="doThis"></button>

<!-- 键修饰符,键别名 -->
<input @keyup.enter="onEnter">

<!-- 键修饰符,键代码 -->
<input @keyup.13="onEnter">

<!-- 点击回调只会触发一次 -->
<button @click.once="doThis"></button>

       

2.6 表单绑定 v-model

2.6.1 v-model 基本用法

  • 作用:实现表单元素和数据的双向绑定

  • v-model实际是语法糖,其背后是包含两个操作:

    1. v-bind:绑定value值
    2. v-on:给当前元素绑定事件
<div id="app">
    <input type="text" v-model="message">
    <h2>{
   
   {message}}</h2>
</div>

<script>
    let app = new Vue({
      
      
        el:"#app",
        data: {
      
      
            message:''
        }
    })
</script>

​ 当我们在输入框中输入内容时,因为input中v-model绑定了message,所以会实时将输入的内容传递给message,message发生变化。而又使用了Mustache语法将message的值绑定到DOM中,所以DOM会发生相应的变化

       

2.6.2 v-model + radio

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ANB7UAkR-1635481971630)(C:\Users\小萌\Desktop\image-20211021143537209.png)]

要点:如果v-model 都绑定的是同一个变量,那么删除name后也可以互斥

       

2.6.3 v-model+checkbox

1. checkbox 单选框

<div id="app">
    <label for="agree">
        <input type="checkbox" id="agree" v-model="isAgree">同意协议
    </label>
    <h2>您的选择是:{
   
   {isAgree}}</h2>
    <button :disaled="!isAgree">下一步</button>
</div>

2. checkbox 多选框

<input type="checkbox" value="篮球" v-model="hobbies">篮球
<input type="checkbox" value="足球" v-model="hobbies">足球
<input type="checkbox" value="乒乓球" v-model="hobbies">乒乓球
<input type="checkbox" value="羽毛球" v-model="hobbies">羽毛球
<h2>您的爱好是:{
   
   {hobbies}}</h2>
<script>
    let app = new Vue({
      
      
        el:"#app",
        data: {
      
      
            message: '你好啊',
            isAgree: false, //单选框
            hobbies: [] //多选框
        }
    })
</script>

要点:value是点击后会返回的值

       

2.6.4 v-model + select

单选

  • v-model 绑定的是一个值
  • 当我们选中一个option时,会将它对应的 value 赋值到select(fruit)中

多选

  • v-model 绑定的是一个数组
  • 当选中多个值时,会将选中的 option 对应的value添加到数组 selects (fruits)中
<div id="app">
    <!-- 选择一个 -->
    <select name="abc" v-model="fruit">
        <option value="苹果">苹果</option>
        <option value="香蕉">香蕉</option>
        <option value="西瓜">西瓜</option>
        <option value="梨子">梨子</option>
    </select>
    <h2>您选择的水果是:{
   
   {fruit}}</h2>

    <!-- 选择多个 -->
    <select name="abc" v-model="fruits" multiple>
        <option value="苹果">苹果</option>
        <option value="香蕉">香蕉</option>
        <option value="西瓜">西瓜</option>
        <option value="梨子">梨子</option>
    </select>
    <h2>您选择的水果是:{
   
   {fruits}}</h2>
</div>

<script>
    let app = new Vue({
      
      
        el:"#app",
        data: {
      
      
            message: '你好啊',
            fruit:'香蕉',
            fruits:[]
        }
    })
</script>

       

2.6.5 input绑定

<div id="app">
    <label v-for="item in originHobbies" :for="item">
        <input type="checkbox" :value="item" :id="item" v-model="hobbies">{
   
   {item}}
    </label>
</div>

<script>
    let app = new Vue({
      
      
        el:"#app",
        data: {
      
      
            message: '你好啊',
            hobbies:[],
            originHobbies:['篮球','足球','乒乓球','羽毛球','台球']
        }
    })
</script>

       

2.6.6 v-model的修饰符

  • lazy 修饰符

    • 作用:为避免数据的频繁更新,lazy修饰符可以让数据在失去焦点或回车时才会更新,而不是在输入过程中频繁更新
    • 默认情况下,v-model是在input事件中同步输入框中的数据,即一旦有数据发生该百年对应的data中的数据就会自动发生改变
  • number 修饰符

    • 作用:可以让输入框中输入的内容自动转换为数字类型

    • 默认情况下,在输入框中无论我们输入的事数字还是字母,都会被当作字符串类型进行处理。当若我们希望处理的事数字类型,最好直接将内容当作数字处理

  • trim 修饰符

    • 作用:过滤内容左右两边的空格
    • 输入的内容首尾可能有很多空格,通常希望将其去除
<input type="text" v-model.lazy="message">
<h2>{
   
   {message}}</h2>

<input type="number" v-model.number="age">
<h2>{
   
   {age}}</h2>

       

2.7 总结

  • 内容渲染指令: 渲染DOM元素的文本内容
    • v-text
    • { { }}
    • v-html
  • 属性绑定指令: 为元素的属性动态绑定属性值
    • v-bind
  • 事件绑定指令
    • v-on
  • 双向绑定指令: 在不操作DOM 的前提下,快速获取表单的数据
    • v-model
  • 条件渲染指令
    • v-if
    • v-show
  • 列表渲染指令
    • v-for

       

三、ES6对象增强写法

ES6中,对对象字面量进行了很多增强。

3.1 属性初始化简写

// ES6之前
let name = 'why';
let age = 18;
let obj1 = {
    
    
    name: name,
    age: age
}
console.log(obj1);

// ES6之后
let obj2 = {
    
    
    name, age
}
console.log(obj2);

       

3.2 方法的简写

// ES6之前
let obj1 = {
    
    
    test: funtion() {
    
    
    console.log("obj1");
	}
};
obj1.test();

// ES6之后
let obj1 = {
    
    
    test() {
    
    
    console.log("obj2");
	}
};
obj2.test();

       

四、Vue的生命周期

4.1 生命周期的概念

       vue 每个组件都是独立的,每个组件都有一个属于它的生命周期,从一个组件创建(new)、数据初始化、挂载、更新、销毁,这就是一个组件所谓的生命周期。同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会。

       

4.2 生命周期钩子(函数)

  • beforeCreate()

    ​ 此时组件的选项对象还未创建,el 和 data 并未初始化,因此无法访问methods, data, computed等上的方法和数据。

  • create()

    ​ 实例已经创建完成之后被调用。在这一步,实例已完成以下的配置:数据观测(data observer),属性和方法的运算, watch/event 事件回调。然而,挂载阶段还没开始,$el 属性目前不可见。可以调用methods中的方法,改变data中的数据;获取computed中的计算属性,且常在该钩子里进行网络请求

  • beforeMount()

    ​ 在挂载开始之前被调用:相关的 render 函数首次被调用(虚拟DOM)。实例已完成以下的配置: 编译模板,把data里面的数据和模板生成html,完成了el和data 初始化,注意此时还没有挂载html到页面上

  • mounted()

    ​ **挂载完成,也就是模板中的HTML渲染到HTML页面中,**此时一般可以做一些ajax操作,mounted只会执行一次

  • beforeUpdate()

    ​ 在数据更新之前被调用,发生在虚拟DOM重新渲染和打补丁之前,可以在该钩子中进一步地更改状态,不会触发附加地重渲染过程

  • update()

    ​ 在由于数据更改导致的虚拟DOM重新渲染和打补丁之后调用,调用时**,组件DOM已经更新,所以可以执行依赖于DOM的操作**,在大多数情况下,应该避免在此期间更改状态,因为这可能会导致更新无限循环,该钩子在服务器端渲染期间不被调用

  • beforeDestroy()

    ​ 在实例销毁之前调用,实例仍然完全可用

    1. 这一步还可以用this来获取实例
    2. 一般在这一步做一些重置的操作,比如清除掉组件中的定时器和监听的dom事件
  • destroyed()

    ​ 在实例销毁之后调用,调用后,所有的事件监听器会被移出,所有的子实例也会被销毁,该钩子在服务器端渲染期间不被调用

注意:不要在选项 property 或回调上使用箭头函数,比如 created: () => console.log(this.a)vm.$watch('a', newValue => this.myMethod())。因为箭头函数并没有 this

img

       

五、过滤器(Vue 3.x已经不使用)

5.1 过滤器基本使用

过滤器常用于文本的格式化。过滤器可以用在两个地方:插值表达式v-bind 属性绑定

过滤器是个函数,应该添加在 JS 表达式的尾部,有**“管道符”**进行调用,示例:

<!-- 在双括号中通过管道符调用 captalize 过滤器,对 message 的值进行格式化 -->
<!-- message作为参数传给capitalize函数,最后在message位置看到的是capitalize函数的返回值-->
<p>{
   
   {message | capitalize}}</p>  

<!-- 在v-bind 中通过“管道符”调用 formatID 过滤器,对 rawID 的值进行格式化 -->
<div v-bind:id='rawID | foematID'></div>
<div id="app">
    <p>message的值: {
   
   {message | capitalize}}</p>
</div>
<script src="./vue.js"></script>
<script>
    const vm = new Vue({
      
      
        el:'#app',
        data: {
      
      
            message: 'hello vue'
        },
        // 过滤器函数
        filters: {
      
      
            //注意:过滤器函数中的形参val永远都是管道符前面的那个值
            capitalize(val) {
      
      
                //强调:过滤器中一定要有返回值
                const first = val.charAt(0).toUpperCase();
                const other = val.slice(1);
                return first + other;
            }
        }
    })
</script>

注意:

  1. 过滤器函数中的形参val永远都是管道符前面的那个值
  2. 过滤器中一定要有返回值
  3. 过滤器本身是一个函数

       

5.2 私有过滤器和全局过滤器

  • 私有过滤器:在 filters 节点下定义的过滤器,只能在当前的 vm 实例所控制的 el 区域内使用

  • 全局过滤器:可在多个vue实例之间共享过滤器

定义全局过滤器的格式:

// 第一个参数:全局过滤器的名字, 第二个参数:全局过滤器的处理器
Vue.filter('capitalize',(str) => {
    
    
	return str.charAt(0).toUpperCase() + str.slice(1);
})

注意:若私有过滤器和全局过滤器名字相同,按照“就近原则”,调用的是私有过滤器

案例:可以用全局过滤器去格式化时间,利用 dayjs() 快速格式化

       

5.3 连续调用多个过滤器

{
   
   { message | filterA | filterB}}

解析:

  1. 把 message 的值发给 filterA 处理
  2. 把 filterA 处理的值交给 filterB 处理
  3. 最终把 filterB 处理的结果作为最终值返回

       

5.4 过滤器传参

<p>{
   
   {message | filterA(arg1,arg2)}}</p>
<script>
    //第二个参数中的第一个参数永远是管道符前面待处理的值
    Vue.filter('filterA',(message,arg1,arg2) => {
      
      
      ...
    })
</script>

       

六、侦听器

6.1 watch监听器的概念

       watch 监听器允许开发者监听数据的变化,从而针对数据的变化做特定的操作,语法格式如下:

const vm = new Vue({
    
    
    el:'#app',
    data: {
    
    
        username: ''
    },
    watch: {
    
    
        // 监听username值的变化
        // newVal是变化后的新值,oldVal是变化前的旧值
        username(newVal, oldVal) {
    
    
            console.log(newVal,oldVal);
        }
    }
})

注意:

  1. 监听函数里面的形参 “新前旧后”
  2. 要监听谁就在 watch 节点中把谁当作函数名

       

6.2 业务场景——判断用户名是否被占用

<div id="app">
    <input type="text" v-model='username'>
        </div>
<script>
    const vm = new Vue({
      
      
        el:'#app',
        data: {
      
      
            usename: 'hello vue'
        },
        watch: {
      
      
            username(newVal, oldVal){
      
      
                if(newVal === '') return;
                //1. 调用jQuery中的Ajax发起请求,判断 newVal是否被占用
                $.get('http://www/escook.cn/api/finduser/' + newVal, function(result) {
      
      
                    console.log(result);
                });
            }
        }
    })
</script>

       

6.3 侦听器的选项

6.3.1 侦听器的格式

  • 方法格式的侦听器

    缺点:

    1. 无法在刚进入页面时自动触发
    2. 如果侦听的是一个对象,如果对象中的属性发送了变化,不会触发侦听器
  • 对象格式的侦听器

    优点:

    1. 可以通过 immediate 选项,让侦听器自动触发
    2. 可以通过 deep 选项,让侦听器深度监听对象中每个属性的变化

       

6.3.2 immediate属性

<script>
    const vm = new Vue({
      
      
        el:'#app',
        data: {
      
      
            usename: 'hello vue'
        },
        watch: {
      
      
            username:{
      
      
                handler(newVal, oldVal) {
      
      
                    console.log(newVal,oldVal);
                },
                //immediate默认选项是false,作用是:控制侦听器是否自动触发一次
                immediate: true
            }
        }
    })
</script>

       

6.3.3 deep属性(深度侦听)

<script>
    const vm = new Vue({
      
      
        el: '#app',
        data: {
      
      
            info: {
      
      
                usename: 'admin'
            }
        },
        watch: {
      
      
            info: {
      
      
                handler(newVal) {
      
      
                    console.log(newVal);
                },
                deep: true
            }
        }
    })
</script>

       

七、计算属性

7.1 计算属性

计算属性是通过一系列计算后,最终得到一个属性值

<div id="app">
    <h2>总价格:{
   
   {totalPrice}}</h2>
</div>
<script src="./vue.js"></script>
<script>
    let app = new Vue({
      
      
        el:"#app",
        data: {
      
      
            books:[
                {
      
      id: 110, name: 'hhh', price: 119},
                {
      
      id: 111, name: 'xxx', price: 105},
                {
      
      id: 112, name: 'sss', price: 98},
                {
      
      id: 113, name: 'jjj', price: 87}
            ]
        },
        computed: {
      
      
            totalPrice: function() {
      
      
                let res = 0;
                for(let i=0; i < this.books.length; i++) {
      
      
                    res += this.books[i].price;
                }
                return res;

                //其他的for写法
                for(let i in this.books){
      
      
                    this.books[i];
                }

                for(let book of this.books){
      
      

                }
            }
        }
    })
</script>

注意:

  1. totalPrice 不加括号,把它当成属性来看待

  2. 计算属性在声明时要定义成方法格式,使用的时候当成属性去用

好处:

  1. 实现了代码的复用
  2. 只要计算属性中依赖的数据源变了,则计算属性会自动重新求值

       

7.2 计算属性的setter和getter

计算属性一般是没有set方法的,为只读属性

image-20211028171416827

7.3 计算属性与methods对比

<div id="app">
    <!-- 1.直接拼接 -->
    <h2>{
   
   {firstName}} {
   
   {lastName}}</h2>
    <!-- 2.通过定义methods -->
    <h2>{
   
   {getFullName()}}</h2>
    <!-- 3.通过computed -->
    <h2>{
   
   {fullName}}</h2>
</div>

要点:computed 属性有缓存的 ,不管需要调用多少个{ {fullName}},都只计算一次

八、axios

axios 是一个专注于网络请求、数据请求的库

8.1 axios的基础用法

基本语法如下:

axios({
    
    
    //请求方式
    method: '请求的类型',
    //请求地址
    url: '请求的url',
    //url中的查询参数(按需可选,一般GET用)
    params:{
    
    },
    //请求体参数(按需可选,一般post用)
    data:{
    
    }
}).then((result) => {
    
    
    //.then用来指定请求成功后的回调函数
    //形参中的 result 是请求成功之后的结果
})

方法解析:

  1. 调用 axios 方法后得到的返回值是一个 Promise 对象
  2. Promise 对象就可以用 .then 方法

image-20211028194253942

8.1.1 发起 GET 请求

/*
 get请求传递两个参数
 参数一表示请求地址,参数二表示配置信息
 配置信息中:
 params:表示传递到服务器端的数据以url参数的形式拼接到请求地址后面
 headers:表示请求头

 例如:请求地址为:https://www.github.com/martians
 params中 {page:1,per:3}
 最终生成的url为:https://www.github.com/martians?page=1&per=3
*/
axios({
    
    
    //请求方式
    method: 'GET',
    //请求地址
    url: 'http://www.hhh.com/api/books',
    //url中的查询参数(按需可选)
    params:{
    
    
        id:1
    },
}).then((result) => {
    
    
	console.log(result);
})

8.1.2 发起 POST 请求

axios({
    
    
    method: 'POST',
    url: 'http://www.hhh.com/api/books',
    data:{
    
    
        name:'zs',
        age:20
    },
}).then((result) => {
    
    
	console.log(result);
})

8.1.3 结合 async 和 await调用 axios

要点:

  1. 如果调用某个方法的返回值是 Promise 实例,则前面可以添加 await
  2. await 只能放在被 async 修饰的方法中
document.querySelector('#btnPost').addEventListener('click', async function() {
    
    
    const result = await axios({
    
    
        method: 'POST',
        url: 'http://www.hhh.com/api/books',
        data: {
    
    
            name: 'zs',
            age: 20
        }
    })
})

8.1.4 使用解构赋值

只获取自己关心的数据

document.querySelector('#btnPost').addEventListener('click', async function() {
    
    
    //解构复制的时候,使用:进行重命名
    const {
    
     data : res } = await axios({
    
    
        method: 'POST',
        url: 'http://www.hhh.com/api/books',
        data: {
    
    
            name: 'zs',
            age: 20
        }
    })
    console.log(res.data);
})

总结使用axios的步骤:

  1. 调用 axios 之后,使用async+await 进行简化
  2. 使用解构赋值,从 axios 封装的大对象中,把 data 属性解构出来
  3. 把解构出来的 data 属性,使用冒号进行重命名,一般都重命名为{ data:res }

8.2 基于axios.get 和 axios.post 发起请求

8.2.1 axios.get

语法格式:

axios.get('url地址', {
    
    
	//GET参数
    params: {
    
    }
})
document.querySelector('#btnPost').addEventListener('click', async function() {
    
    
    //解构复制的时候,使用:进行重命名
    const {
    
    data : res } = await axios.get('http://www.hhh.com/api/books',{
    
    
        params:{
    
     id: 1 }
    })
    console.log(res);
})

8.2.2 axios.post

语法格式:

axios.post('url',{
    
     /*post 请求体数据*/})
document.querySelector('#btnPost').addEventListener('click', async function() {
    
    
    //解构复制的时候,使用:进行重命名
    const {
    
     data : res } = await axios.post('http://www.hhh.com/api/books',{
    
    
        name: 'zs',
        age: 20
    })
    console.log(res);
})

九、Vue-cli

9.1 单页面应用程序

指一个web网站中只有唯一一个HTML页面,所有的功能和交互都在这唯一的一个页面内完成

9.2 vue-cli(脚手架)

vue-cli 是 Vue.js 开发的标准工具,简化了程序员基于 webpack 创建工程化的Vue项目,已经帮我们配置好了 webpack ,直接用就行

9.3 安装和使用

安装的命令

npm install -g @vue/cli

创建指定名称的项目:

vue create 项目的名字

9.4 vue项目中src目录的构成

  • assets:存放项目用到的静态资源文件,如:css样式表、图片资源
  • components:程序员封装的可复用的组件
  • main.js:是项目的入口文件。对应webpack中的entry,整个项目的运行,要先执行main.js
  • App.vue:项目的根组件

9.5 vue项目的运行流程

       在工厂化项目中,vue的任务:通过 main.jsApp.vue 渲染到 index.html 的指定区域

其中:

  1. App.vue:用来编写待渲染的模板结构
  2. index.html:需要预留一个el区域
  3. main.js:把App.vue 渲染到 index.html 所预留的区域
image-20211029100128404

猜你喜欢

转载自blog.csdn.net/weixin_45950819/article/details/120897115