Vue基础

1. Vue简介

1.1 什么是 Vue

官方概念:Vue 是一套用于构建用户界面的前端框架

1.2 Vue 的特性(两个核心)

  • 数据驱动视图

在使用了vue 的页面中,vue 会监听数据的变化,从而自动重新渲染页面结构。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-praodxFJ-1652883437021)(C:\Users\肖锦顺\AppData\Roaming\Typora\typora-user-images\1649771840707.png)]

好处:当页面数据发生变化是,页面会自动重新渲染

注意:数据驱动视图是单向绑定数据

  • 双向数据绑定

在填写表单时,双向数据绑定可以辅助开发者在不操作 DOM 的前提下,自动把用户填写的内容同步到数据源中。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JWDZJH9v-1652883494710)(C:%5CUsers%5C%E8%82%96%E9%94%A6%E9%A1%BA%5CAppData%5CRoaming%5CTypora%5Ctypora-user-images%5C1649771840707.png#pic_center)]

好处:开发者不再需要手动操作 DOM 元素,来获取表单元素的最新值

1.3 MVVM

MVVM 是 Vue 实现数据驱动视图双向数据绑定的核心原理。MVVM 指的是 Model、View、ViewModel。它把每个 HTML 页面都拆分成了这三部分

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9X58q5iF-1652883437023)(C:\Users\肖锦顺\AppData\Roaming\Typora\typora-user-images\1649772195609.png)]

1.4 MVVM 的工作原理

ViewModel 作为 MVVM 的核心,是它把当前页面数据源(Model)和页面结构 (View)连接在一起。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gypxIBRb-1652883437023)(C:\Users\肖锦顺\AppData\Roaming\Typora\typora-user-images\1649772286174.png)]

数据源发生变化是,会被 ViewModel 监听到,VM 会根据最新的数据源自动更新页面结构

表单元素的值发生变化是,也会被 VM 监听到,VM 会把变化过后的最新的值自动同步到 Model 数据源中。

2. Vue 的基本使用

  • 导入 vue.js 的 script 脚本文件
  • 在页面中声明一个将要被 vue 控制的 DOM 区域
  • 创建一个 VM 实例对象(vue 实例对象)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sbCvpJp4-1652883437023)(C:\Users\肖锦顺\AppData\Roaming\Typora\typora-user-images\1649772513596.png)]

3. Vue 指令

3.1 指令的概念

指令是 vue 为开发者提供的模板语法,用于辅助开发者渲染页面的基本结构

Vue 指令的 6 大类:

  • 内容渲染指令
  • 属性绑定指令
  • 事件绑定指令
  • 双向绑定指令
  • 条件渲染指令
  • 列表渲染指令

3.2 内容渲染指令

内容渲染指令用来辅助开发者渲染 DOM 元素的文本内容。常用的内容渲染指令有如下 3 个

  • v-text
  • {{}}
  • v-html

v-text

用法


<p v-text="gender">性别p>

{{}}

vue 提供的 {{}} 语法,专门用来解决 v-text 会覆盖默认文本内容的问题。这种语法 {{}} 的专业名称是插值表达式(英文:Mustache)

<p>
    姓名:{{username}}
p>

v-html

v-text 指令和插值表达式只能渲染存文本内容。如果要把包含 HTML 标签的字符串渲染为页面的 HTML 元素,则需要用到 v-html 指令


<p v-html="discription"> p>

3.3 属性绑定

为元素绑动态绑定属性值,可以使用 v-bind 属性绑定指令

 
    <div id="app">
        
        <input type="text" v-bind:placeholder="tips"><br>
        
        <input type="text" :placeholder="tips">

        <hr>
        
        <div>{{ 1 + 2}}div>
        <div>{{ tips}} 翻转的结果是: {{ tips.split('').reverse().join('')}}div>
    div>


    
    <script src="./lib/vue-2.6.12.js">script>
    
    <script>
        // 创建 Vue 实例对象
        const vm = new Vue({
            // el 是固定的写法,表示 vm 要控制页面上的哪一个区域,接受的值是一个选择器
            el:'#app',
            // data 对象就是要渲染到页面上的数据
            data:{
                tips:'请输入用户名',
                index:3,
            }

        })
    script>

vue 提供的模板语法渲染语法中,除了支持绑定简单的数据值之外,还支持 JavaScript 表达式的运算

{{ ok ? 'yes' : 'no' }}
<div v-bind="'list'+id">
    
div>

3.4 事件绑定

vue 提供了 v-on 事件绑定指令,用来辅助程序员为 DOM 元素绑定事件监听

 <div id="app">
        <p>count 的值是:{{ count}}p>
        
        
        
        <button @click='add(2)'>+1button>
        <button v-on:click='sub'>-1button>
    div>

    
    <script src="./lib/vue-2.6.12.js">script>
    
    <script>
        // 创建 Vue 实例对象
        const vm = new Vue({
            // el 是固定的写法,表示 vm 要控制页面上的哪一个区域,接受的值是一个选择器
            el:'#app',
            // data 对象就是要渲染到页面上的数据
            data:{
                count:0,
            },
            // methods 的作用就是定义事件处理函数
            methods:{
                // add:function(){

                // }
                //  处理函数简写形式
                add(n){
                    // console.log(vm === this) // this 就是 vm这个 Vue 实例对象
                    // 调用 count 属性
                    this.count +=n
                },
                sub(){
                    this.count -=1
                }
            }
        });

注意:原生 DOM 对象有 onclick、oninput、onkeyup 等原生事件

事件绑定之后为:v-on:click v-on:input v-on:keyup

事件参数对象

在原生的 DOM 对象绑定中,可以在事件处理函数的形参处,接受事件对象 event。同理,在 v-on 指令所绑定的事件处理函数中,同样可以接收到事件对象 event


    <div id="app">
        <p>count的值是 {{count}}p>
        
        
        <button @click="add">+1button>
    div>


    
    <script src="./lib/vue-2.6.12.js">script>
    
    <script>
        // 创建 Vue 实例对象
        const vm = new Vue({
            // el 是固定的写法,表示 vm 要控制页面上的哪一个区域,接受的值是一个选择器
            el:'#app',
            // data 对象就是要渲染到页面上的数据
            data:{
                count:0,
            },
            methods:{
                add(e){ // 接受事件对象 event ,简写为 e
                    // 调用是不传参数,会有一个参数e
                   e.target.style.backgroundColor = 'red'
                },
            }

        });

在使用 v-on 指令绑定事件时,可以使用 ()进行传参

count的值为:{{count}}

// ------------------------------------- methods:{ add(n) { // 用 n 接受参数 this.count += n } }

$event 是 vue 提供的特殊变量,用来表示原生的事件参数对象 event。

$event 可以解决事件参数对象 event 被覆盖的问题

 <!-- Vue 提供了内置变量,名为 $event,它就是 DOM 的原生对象 e -->
<button @click="add(1,$event)">+N</button>


// -------------------------------------
methods: {
    add(n,e) {
        // 使用 e 来接受传递过来的原生事件对象 $event
        this.count += n
        e.target.style.backgroundColor = 'red'
    }
}


事件修饰符

  • .prevent

    <a @click.prevent="xxx">链接a>
    
    
  • .stop

    <button @click.stop="xxx">按钮button>
    
    

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZCQvkY4p-1652883437024)(C:\Users\肖锦顺\AppData\Roaming\Typora\typora-user-images\1649826528524.png)]

按键修饰符

在监听键盘事件时,我们经常需要判断详细的按键。此时,可以为键盘相关事件添加按键修饰符

<!-- 绑定一个按键修饰符 -->
<input type="text" @keyup.esc="clearInfo">
    
methods:{
    clearInfo(e){
         console.log('触发了按键修饰符')
         e.target.value = ''
       }
}

3.5 数据双向绑定

vue 提供了 v-model 双向绑定数据指令

<div id="app">
        <p>用户的姓名是:{{ username}}</p>
        <!-- 使用 v-model 双向绑定 -->
        <input type="text" v-model="username">
        <hr>
        请选择:<select name="" id="" v-model="city">
            <option value="1">北京</option>
            <option value="2">上海</option>
            <option value="3">武汉</option>
            <option value="4">长沙</option>
        </select>
    </div>


    <!-- 导入 Vue 库文件,在 windows 全局就有了一个 Vue 的构造函数 -->
    <script src="./lib/vue-2.6.12.js"></script>
    <!-- 创建 Vue 实例对象 -->
    <script>
        // 创建 Vue 实例对象
        const vm = new Vue({
            // el 是固定的写法,表示 vm 要控制页面上的哪一个区域,接受的值是一个选择器
            el:'#app',
            // data 对象就是要渲染到页面上的数据
            data:{
                username:'zhangsan',
                city:''
            }

        })
    </script>

v-model 指令的修饰符

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-J4erLghq-1652883437025)(C:\Users\肖锦顺\AppData\Roaming\Typora\typora-user-images\1649826943490.png)]

3.6 条件渲染指令

  1. v-show 的原理是:动态为元素添加或移除 display: none 样式,来实现元素的显示和隐藏
    • 如果要频繁的切换元素的显示状态,用 v-show 性能会更好
  2. v-if 的原理是:每次动态创建移除元素,实现元素的显示和隐藏
    • 如果刚进入页面的时候,某些元素默认不需要被展示,而且后期这个元素很可能也不需要被展示出来,此时 v-if 性能更好

在实际开发中,绝大多数情况,不用考虑性能问题,直接使用 v-if 就好了!!!

v-if 指令在使用的时候,有两种方式:

  1. 直接给定一个布尔值 true 或 false

    <p v-if="true">被 v-if 控制的元素p>
    
    
  2. 给 v-if 提供一个判断条件,根据判断的结果是 true 或 false,来控制元素的显示和隐藏

    <p v-if="type === 'A'">良好p>
    
    

v-if 可以单独使用,也可以配合 v-else / v-else-if一起使用

<div v-if="type === A">
    优秀
div>
<div v-else-if="type === B">
    良好
div>
<div v-else-if="type === C">
    一般
div>
<div v-else>div>

3.7 列表渲染指令

vue 提供了 v-for 列表渲染指令

语法:v-for="(item,index) in list"

data: {
    list: [ // 列表数据
        {id: 1,name: 'zs'},
        {id: 2,name: 'ls'}
    ]
}

// ------------------------------------
<ul>
	<li v-for="item in list">姓名是:{{ item.name }}</li>    
</ul>

注意:v-for 指令中的 item 和 index 都是形参,可以根据需要进行重命名。列如:(user,i) in userList

使用 key 维护列表状态

当列表数据发生变化时,默认情况下,vue 会尽可能的复用已经存在的 DOM 元素,从而提升渲染的性能。但这种默认的性能优化策略,会导有状态的列表无法被正确更新。

为了给 vue 一个提示,以便它能跟踪每个节点的身份,从而在保证有状态的列表被正确更新的前提下,提升渲染的性能。此时,需要为每项提供一个唯一的 key 属性

data: {
    list: [ // 列表数据
        {id: 1,name: 'zs'},
        {id: 2,name: 'ls'}
    ]
}

// ------------------------------------
<ul>
    // 为每项提供一个唯一的 key 属性
	<li v-for="item in list" :key="item.id">姓名是:{{ item.name }}</li>    
</ul>

key 的注意事项

  • key 的值只能是字符串或数字类型
  • key 的值必须具有唯一性
  • 建议把数据项的 id 属性的值作为 key 的值
  • 使用 index 的值当做 key 的值没有任何意义(因为 index 的值不具有唯一性)
  • 建议使用 v-for 指令时一定要指定 key 的值(既能提升性能、又能防止列表状态紊乱)

4. Vue过滤器

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

过滤器应该被添加在 JavaScript 表达式的尾部,由“管道符”进行调用

    <div id="app">
        
        <p>message的值是:{{ message | cpi}}p>
    div>
    <script src="./lib/vue-2.6.12.js">script>
    <script>
        const vm = new Vue({
            el:'#app',
            data:{
                message:'hello Vue.js',
            },
            // 过滤器函数必须定义到 filters 节点之下
            // 过滤器实质上也是一个函数
            filters:{
                // 注意,过滤器函数形参 val 是管道符 "|"前面的那个数据
                cpi(val){
                   // 字符串有 charAt 方法,这个方法接受所索引值,表示在字符串中把索引对应的字符取出来
                   // 第一个字符 val.charAt(0)
                   const first = val.charAt(0).toUpperCase()
                   // 字符串的 slice 方法,可以截取字符串,从指定索引往后截取
                   const other = val.slice(1)
                   // 强调,过滤器必须要有返回值
                   return first + other
                }
            }
        })

私有过滤器和全局过滤器

在 filters 节点下定义的过滤器。称为“私有过滤器”。Vue.filter() 定义全局过滤器

<div id="app">
        <!-- 代用过滤器  " | "叫做管道符 -->
        <p>message的值是:{{ message | cpi}}</p>
    </div>
    <div id="app1">
        <!-- 代用过滤器  " | "叫做管道符 -->
        <p>message的值是:{{ message | cpi}}</p>
    </div>
    <script src="./lib/vue-2.6.12.js"></script>
    <script>
        // 使用 Vue.filter() 定义全局过滤器
        // 两个参数:一个过滤器函数名称,一个函数

        // 如果 全局过滤器 和 私有过滤器 名字冲突,就近原则会先调用 私有过滤器
        Vue.filter('cpi',function(val){
            const first = val.charAt(0).toUpperCase()
            const other = val.slice(1)
            return first + other
        })
        const vm = new Vue({
            el:'#app',
            data:{
                message:'hello Vue.js',
            },
            // 过滤器函数必须定义到 filters 节点之下
            // 过滤器实质上也是一个函数
            filters:{
                // 这里定义的是私有过滤器
                // 注意,过滤器函数形参 val 是管道符 "|"前面的那个知
                cpi(val){
                   // 字符串有 charAt 方法,这个方法接受所索引值,表示在字符串中把索引对应的字符取出来
                   // 第一个字符 val.charAt(0)
                    const first = val.charAt(0).toUpperCase()
                    // 字符串的 slice 方法,可以截取字符串,从指定索引往后截取
                    const other = val.slice(1)
                    // 强调,过滤器必须要有返回值
                    return first + other
                }
            }
        })
        const vm1 = new Vue({
            el:'#app1',
            data:{
                message:'xjs',
            }
        })

连续调用多个过滤器

/*
	把 message 的值,交给 filterA 进行处理
	把 filterA 处理的结果交给 filterB 进行处理
	最后把 filterB 处理的结果,作为最终值渲染都页面上
*/
{{ message | fliterA | filterB}}

过滤器传参

过滤器的本质是 JavaScript 函数,因此可以接受参数

// 传递参数
<p>{{ messgae | filterA(arg1,arg2)}}</p>

// 第一个参数,永远都是 “管道符” 前面待处理的值
// 从第二个参数开始,才是接受传递过来的参数
Vue.filter('filterA',(message,arg1.arg2) => {
    // 逻辑代码
})

5. 侦听器

watch 侦听器允许开发者监听数据的变化,从而针对数据的变化做特定的操作

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

5.1 immediate 选项

默认情况下,组件初次加载完毕后不会调用 watch 侦听器。如果想让 watch 侦听器立即被调用,则需要使用 immediate 选项

const vm = new Vue({
    el: '#app',
    data: {
        username: 'xjs'
    },
    watch: {
        // 监听 username 值的变化
        // newVal 是变化之后的值 oldVal 是变化之前的值
        username(newVal,oldVal) {
            console.log(newVal,odlVal)
        },
        // 表示页面初次渲染之后,就立即触发当前的侦听器
        immediate: true 
    }
})

5.2 deep 选项

如果 watch 侦听的是一个对象,如果对象中的属性值发生了变化,则无法被监听到。此时需要使用 deep 选线

const vm = new Vue({
    el: '#app',
    data: {
        info: {
            username: 'xjs',
            age: 18
        }
    },
    watch: {
        // 监听 username 值的变化
        // newVal 是变化之后的值 oldVal 是变化之前的值
        info(newVal,oldVal) {
            console.log(newVal.username,odlVal.username)
        },
        // 深度监听
        deep: true
        // 或者之间监听子属性
        // 监听对象子属性的变化,需要在外面包裹一层单引号
        'info.username'(newVal){
             console.log(newVal)
         }  
    }
})

6. 计算属性

计算属性指定是通过一系列运算之后,最终得到的一个属性值

这个动态计算出来的属性值可以被模板结构methods 方法使用

  <div id="app">
    <div>
      <span>R</span>
      <input type="text" v-model.number="r">
    </div>
    <div>
      <span>G</span>
      <input type="text" v-model.number="g">
    </div>
    <div>
      <span>B</span>
      <input type="text" v-model.number="b">
    </div>
    <hr>

    <!-- 专门用户呈现颜色的 div 盒子 -->
    <!-- 在属性身上,: 代表  v-bind: 属性绑定 -->
    <!-- :style 代表动态绑定一个样式对象,它的值是一个 {  } 样式对象 -->
    <!-- 当前的样式对象中,只包含 backgroundColor 背景颜色 -->
    <div class="box" :style="{ backgroundColor: rgb }">
      {{ rgb }}
    </div>
    <button @click="show">按钮</button>
  </div>

  <script>
    // 创建 Vue 实例,得到 ViewModel
    var vm = new Vue({
      el: '#app',
      data: {
        // 红色
        r: 0,
        // 绿色
        g: 0,
        // 蓝色
        b: 0
      },
      methods: {
        // 点击按钮,在终端显示最新的颜色
        show() {
          console.log(this.rgb)
        }
      },
      // 所有的计算属性都要放在 computed 节点下
      // 计算属性在定义的时候,要定义成 “方法格式”
      computed:{
          // rgb 作为计算属性,被定义成了一个方法格式
          // 最终在这个方法中要返回一个拼接号的 rgb(x,x,x) 字符串
          // 计算属性在定义的时候被定义成 “方法格式”,
          // 使用的时候作为 属性使用
        rgb() {
            return (`rgb(${this.r},${this.g},${this.b})`)
        }
      }
    });
  </script>

你可能感兴趣的:(Vue,vue.js,前端,javascript,Vue3)