Vue2+vue3

vue核心

一、vue概念

V+ue.js是套构建用户界面的渐进式框架。与其他重量级框架不同的是,Vue采用自底向上增量开发的设计。Vue 的核心库只关注/图层,并且非常容易学习,非常容易与其它库或已有项目整合。另一方面,Vue 完全有能力驱动采用单文件组件和Vue生态系统支持的库开发的复杂单页应用单页面开发SPA

渐进式框架:可以理解为上手简单,入门简单,但是可以渐近提高框架等级
视图层:之前我们的express它是一个MVC的框架
SPA:称之为单页面开发,是目前开发的主流,当前阶段能够很好的实现SPA开发的框架主要有三个,分别是vue/react/angular

安装

1、安装dev tools

2、安装vue2,在node中安装

yarn add vue@2

使用

<script src="../js/vue.js"></script

二、初识Vue

想让Vue工作,就必须创建一个Vue实例,且要传入一个配置对象
demo容器里的代码依然符合html规范,只不过混入了一些特殊的Vue语法
demo容器里的代码被称为【Vue模板】
Vue实例和容器是一一对应的
真实开发中只有一个Vue实例,并且会配合着组件一起使用
{
   {xxx}}是Vue的语法:插值表达式,{
   {xxx}}可以读取到data中的所有属性
一旦data中的数据发生改变,那么页面中用到该数据的地方也会自动更新(Vue实现的响应式)

注意:vue实例接管的容器不能是body更不能接管html

当vue一旦接管某一个容器以后,这个容器里面所有的东西都可以通过vue来操作,如数据,事件,样式等

<!-- 引入vue -->
<script src="../js/vue.js"></script>
</head>
<body>
    <!-- 第一个容器 -->
    <div class="box1">
        <h1>你好{
  {name}}</h1>
    </div>
    <!-- 第二个容器 -->
    <div class="box2">
        <h1>你好{
  {name.toUpperCase()}},{
  { Date.now() }}</h1>
    </div>
</body>

</html>
<script type="text/javascript">
    Vue.config.productionTip = false;

    // 第一个vue实例
    new Vue({
     
        el: '.box1',
        data: {
     
            name: '初始vue1'
        }
    })

    // 第二个vue实例
    new Vue({
     
        el: '.box2',
        data: {
     
            name: '初始vue2'
        }
    })

</script>

三、模板语法

1、插值语法{ {}}

功能:用于解析标签体内容

语法:{ {xxx}},xxx是js表达式,且可以直接读取到data中的所有属性

<div class="box">
    <!-- 插值语法 -->
    <h1>模板语法之:{
  {value}}</h1>
    <!-- 对象语法.的方式 -->
    <a href="">{
  {prosion.name}}的年龄为{
  {prosion.age}}</a>
</div>

<script src="../js/vue.js"></script>
<script>
    new Vue({
     
        el: ".box",
        data: {
     
            value: '插值语法',
            // data的属性的key对应的values是一个对象时
            prosion: {
     
                name: '张三',
                age: 18
            }
        }
    })
</script>

2、指令语法v-xx

功能:用于解析标签(包括:标签属性、标签体内容、绑定事件…)

语法:

如v-bind指令用于数据绑定:v-bind:href=“xxx” 或 简写为 :href=“xxx”,xxx同样要写js表达式,且可以直接读取到data中的所有属性

注意:[v-bind:] 可以简写为[:]

3、模板中的js表达式

正确表达式:

1、{
   { number + 1 }}
2、{
   { ok ? 'YES' : 'NO' }}
3、{
   { message.split('').reverse().join('') }}
4、<div v-bind:id="'list-' + id"></div>

错误表达式:

<!-- 这是语句,不是表达式 -->
{
   { var a = 1 }}

<!-- 流控制也不会生效,请使用三元表达式 -->
{
   { if (ok) { return message } }}
<div class="box">
    <!-- 指令语法v-bind: -->
    <a v-bind:href='url'>百度一下小写</a>
    <a v-bind:href="url.toUpperCase()">百度一下大小</a>
    <!-- [v-bind:] 可以简写为[:] -->
    <a :href="url.toUpperCase()">百度一下大小</a>
</div>

<script src="../js/vue.js"></script>
<script>
  new Vue({
     
    el: ".box",
    data: {
     
      url: 'http://www.baidu.com',
    }
  })
</script>

四、数据绑定

1、单向数据绑定

单向绑定(v-bind):数据只能从data流向页面

当data的值改变时,v-bind绑定的值会跟着改变,但是当反过来时v-bind绑定的值改变时,data的值不会跟着改变

单向绑定<input type="text" v-bind:value="name">
单向绑定简写<input type="text" :value="name">

2、双向数据绑定

双向绑定(v-model):数据不仅能从data流向页面,还可以从页面流向data

当data的值改变时,v-model绑定的值会跟着改变,当反过来时v-bind绑定的值改变时,data的值也会跟着改变

注意:
1.双向绑定一般都应用在表单类元素上(如:input、select等)
2.v-model:value 可以简写为 v-model,因为v-model默认收集的就是value值

双向绑定<input type="text" v-model:value="name">
双向绑定简写<input type="text" v-model="name">

使用v-model收集表单数据

收集表单数据:

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

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

  3. 若:为checkbox

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

    2. 配置input的value属性:

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

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

v-model的三个修饰符:
  1. lazy:失去焦点再收集数据
  2. number:输入字符串转为有效的数字
  3. trim:输入首尾空格过滤
  <div class="box">
    <form @submit.prevent="submit">
      <!--.trim去除前后空格  -->
      用户名<input type="text" v-model.trim="userInfo.username"><br>
      密码:<input type="password" v-model="userInfo.password"><br>
      <!-- .number字符串装转为number-->
      年龄:<input type="number" v-model.number="userInfo.age"><br>
      性别:
      男<input type="radio" name="sex" v-model="userInfo.sex" value="boy"><input type="radio" name="sex" v-model="userInfo.sex" value="girl"><br>
      爱好:
      <input type="checkbox" name="hobby" v-model="userInfo.hobby" value="sing">
      <input type="checkbox" name="hobby" v-model="userInfo.hobby" value="jump">
      <input type="checkbox" name="hobby" v-model="userInfo.hobby" value="rap"><br>

      所在地:
      <select name="" id="" v-model="userInfo.address">
        <option value="">--请选择--</option>
        <option value="北京">北京</option>
        <option value="上海">上海</option>
        <option value="深圳">深圳</option>
      </select><br>
      <!--.lazy失去焦点再更新值-->
      个人简介:<textarea cols="30" rows="10" v-model.lazy="userInfo.introduce"></textarea>
      <br>
      阅读并接受用户协议:<input type="checkbox" v-model="userInfo.agree"><br>
      <input type="submit">
    </form>
  </div>
</body>
<script src="../js/vue.js"></script>
<script>
  let vm = new Vue({
      
    el: '.box',
    data: {
      
      userInfo: {
      
        username: "",
        password: "",
        age: '',
        sex: "boy",
        hobby: [],
        address: "北京",
        introduce: "",
        agree: ""
      },
    },
    methods: {
      
      submit () {
      

        console.log(this.userInfo);

      }
    }
  })


</script>

五、el与data的两种写法

1、el的两种写法

①创建vue构造函数的实例时指定

new Vue({
    
    // 创建vue实例对象时指定el容器
    el: '.ul',
    // data为对象类型
    data: {
    
        value1: "1",
    }
})

②创建vue实例后通过实例对象的原型方法**$mount()**指定

  // 在vue实例上挂载dom容器对象
  vm2.$mount(".ul")

2、data的两种写法

①data为对象类型

new Vue({
    
    // 创建vue实例对象时指定el容器
    el: '.ul',
    // data为对象类型
    data: {
    
      value1: "1",
    }
  })
  console.log(vm);

②data为函数类型,返回值为对象类型

注意:在组件中,data必须使用函数式

let vm2 = new Vue({
    
    // data是一个函数返回值为一个对象
    data: function () {
    
        return {
    
            value1: "你好"
        }
    }
})

六、MVVM模型:

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

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

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

    Model 层代表数据模型,也可以在Model中定义数据修改和操作的业务逻辑;View 代表UI 组件,它负责将数据模型转化成UI 展现出来,ViewModel 是一个同步View 和 Model的对象。

    在MVVM架构下,View 和 Model 之间并没有直接的联系,而是通过ViewModel进行交互,Model 和 ViewModel 之间的交互是双向的, 因此View 数据的变化会同步到Model中,而Model 数据的变化也会立即反应到View 上。

    ViewModel 通过双向数据绑定把 View 层和 Model 层连接了起来,而View 和 Model 之间的同步工作完全是自动的,无需人为干涉,因此开发者只需关注业务逻辑,不需要手动操作DOM, 不需要关注数据状态的同步问题,复杂的数据状态维护完全由 MVVM 来统一管理。

    详细参考:Vue.js 和 MVVM 的小细节 - 知乎 (zhihu.com)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-r4YAtIiu-1664507085274)(C:\Users\QuMing\Desktop\vue\资源\笔记图片\Snipaste_2022-08-22_19-20-38.png)]

对应代码的部分

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IXFVjiLt-1664507085275)(C:\Users\QuMing\Desktop\vue\资源\笔记图片\Vue数据代理.png)]

1、data中的属性都会出现在vue实例对象上,

2、vue实例对象上的所有属性及 原型上所有属性在vue模板中都可以使用

柒、数据代理

数据代理: 通过一个对象代理对另一个对象中属性的操作

1、Object.defineProperties的 get、set方法


let name = 'zs';//第三方数据
let age = 20;//第三方数据
let use = {
    }

Object.defineProperties(use, {
    
    name: {
    
           get: function () {
    
               return name//过去name属性时返回第三方name
           },
           set: function (value) {
    
               name = value//设置name属性时不是设置自身name而是设置第三方name的值,这样的话name的值就是动态变化的
           }
       },
       age: {
    
           get: function () {
    
               return age
           },
           set: function (value) {
    
               age = value
           }
       }
   })

2、数据代理,

//实际对象
let obj1 = {
    
    name: "张三"
}
//代理对象
let obj2 = {
    }

// 通过代理对象的get和set来操作实际的对象属性
Object.defineProperty(obj2, 'name', {
    
    get: function () {
    
        // 获取代理对象的属性时通过get拦截实际返回的是实际对象的属性
        return obj1.name;
    },

    set: function (value) {
    
        // 修改代理对象的属性时通过get拦截实际修改的是实际对象的属性
        obj1.name = value;
    }
})

console.log(obj2.name);//张三
obj2.name = "黎明"
console.log(obj2.name);//黎明
obj1.name = "zs"
console.log(obj2.name);//zs

vue中的数据代理

  • 在创建vue实例对象时,vue将data中的数据全部复制一份保存在.实例对象的_data对象中,_

  • 然后Vue给vue实例中添加_data中同名的属性并给属性设置【访问器属性】的getter和setter方法,_

  • 并且setter方法中会增加一个方法,这个方法会让vue重新解析模板

  • 当实例获取_data中同名属性时,会调用访问器属性的getter方法,但返回是_data中同名的值

  • 当实例修改_data中同名属性时,会调用访问器属性的setter方法,但修改的是_data中同名的值。

  • 调用setter方法的同时会重新解析模板(解析模板的后续:生成新的虚拟 DOM----->新旧DOM 对比 -----> 更新页面)

  • 这样的话当data中数据变化时,_ data中会变化,vm中也就跟着变化,

    提示:我们知道vue实例对象上的所有属性及 原型上所有属性在vue模板中都可以使用

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4c2sgG8h-1664507085276)(C:\Users\QuMing\Desktop\vue\资源\笔记图片\Snipaste_2022-08-22_19-32-06.png)]

注意事项💡不被响应的数据

在vue2中,数组中的单元进行整体替换是不会被响应的

<body>
  <div class="box">
    姓名:<span>{
   {arr[0].name}}</span>
    年龄:<span>{
   {arr[0].age}}</span>
  </div>
</body>
<script src="../js/vue.js"></script>
<script>
  let vm = new Vue({
      
    el: ".box",
    data: {
      
      // 当整体修改数组的单元时,数据不被被监事到变化,页面数据不会响应
      // 当把数组的下标为0 的元素整体替换时,数据不会被监视到,页面没有响应
      arr: [{
       name: "张三", age: 18 }, {
       name: "王五", age: 20 }]
    },
  })
</script>

先在控制台修将数组下标为0的元素整体修改、

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FGSOsTwD-1664507085277)(C:\Users\QuMing\Desktop\vue\资源\笔记图片\Snipaste_2022-08-25_17-17-27.png)]

❓ 修改后:vm中的data数据并没有变化。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ArN0TQkF-1664507085277)(C:\Users\QuMing\Desktop\vue\资源\笔记图片\Snipaste_2022-08-25_17-22-34.png)]

解决方法

1、使用vm.$set

vm.$set(vm.arr,0,{name:“zs”,age:19})

2使用入栈的方法,

m.arr.unshift({ name: ‘zs’, age: 19 })

Vue检测数据的原理

1、Vue监视数据的原理:

  • vue会监视data中所有层次的数据

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

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

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

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

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

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

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

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

  • 调用原生对应的方法对数组进行更新
  • 重新解析模板,进而更新页面

4、在Vue修改数组中的某个元素一定要用如下方法:
使用这些API:push()、pop()、shift()、unshift()、splice()、sort()、reverse()
Vue.set() 或 vm.$set()

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

八、事件处理

事件绑定语法:

​ 1、v-on:事件名=‘‘方法名’’

​ 2、简写: @事件名=‘‘方法名’’

注意:

1、调用函数时不传参数,默认会传一个event对象

2、调用函数传参数时,如果还要使用event对象,需要要添加** e v e n t ∗ ∗ 实参, event**实参, event实参,even就是event对象

3、事件回调函数中的this指向是vm 或 组件实例对象

4、事件回调函数需要配置在methods对象中最终会在vm上

5、如果想拿到data里面的数据,应该使用**this. d a t a ∗ ∗ ,但是可以简写,去掉 data**,但是可以简写,去掉 data,但是可以简写,去掉data也可以明出处

鼠标事件

<body>
    <div class="box">
        <button v-on:click="fun(1,$event)">按钮1</button>
        <button @click="fun(1,$event)">按钮2</button>
    </div>
</body>

<script src="../js/vue.js"></script>
<script>
    let vm = new Vue({
      
        el: ".box",
        data: {
      
            value: "小白"
        },
        // 事件的回调函数都写在methods中
        methods: {
      
            fun (a, e) {
      
                console.log(a, e);
                // alert(`初始vue的${this.$data.value}`)
                alert(`初始vue的${
        this.value}`)
            }
        }
    })
</script>

键盘事件

<body>
    <div class="box">
        <input type="text" @keyup.enter="fun">
    </div>
</body>
<script src="../js/vue.js"></script>
<script>
    new Vue({
      
        el: ".box",
        data: {
      },
        methods: {
      
            fun () {
      
                console.log(event.target.value);
            }
        }
    })
</script>

九、事件修饰符

小技巧:修饰符可以连续写

功能性修饰符

  1. stop:停止事件冒泡
  2. prevent:阻止标签的默认行为
  3. once:事件只触发一次
  4. self:当前事件只有自己触发时才执行回调
  5. capture:事件捕获阶段执行
  6. passive:事件默认行为立即执行,无需等待回调
  7. native修饰符,给组件绑定事件时需要加native修饰符

针对于鼠标的

.left
.right
.middle

针对于键盘的修饰符

.enter
.tab(必须配合keydown使用)
.delete (捕获“删除”和“退格”键)
.esc
.space
.up
.down
.left
.right

针对于系统的修饰符(用法特殊)

  1. 配合keyup使用:按下修饰符键的同时,再按下其他键。随后释放其他键,事件才会触发。
  2. 配合keydown使用:正常触发事件。

自定义键名:Vue.config.keyCodes.自定义键名 = 键码

.ctrl
.alt
.shift
.meta

十、计算属性computed

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

2、原理:底层借助了Objcet.defineProperty方法提供的getter和setter(计算属性默认只有 getter,不过在需要时你也可以提供一个 setter:)

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

  • 初次读取计算属性时会执行一次
  • 当计算属性==所依赖的属性发生改变时会被再次调用==,其他时候获取name时都是从缓存中读取的,增加效率

4、set函数什么时候执行?

  • 当name属性改变时会调用set方法

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

6、注意:

  • 计算属性最终会出现在vm上,直接读取使用即可
  • 被vue管理的函数不要写箭头函数。
  • 如果计算属性要被修改,那必须写set函数去响应修改,且set中要引起计算时依赖的数据发生改变
<body>
  <div class="box"><input type="text" v-model:value="frilstername"><br><input type="text" v-model:value="lastername"><br>
    全名<span>{
  {name}}</span>
  </div>
</body>
<script>
  let vm = new Vue({
     
    el: ".box",
    data: {
     
      frilstername: "张",
      lastername: "三"
    },
    methods: {
     
    },
    computed: {
     
      name: {
     
        // 当读取name属性时,get就会被调用,
        // 注意:初次读取name属性时和所依赖的数据发生变化时才会调用get
        // 其他获取name时都是从缓存中读取的,增加效率
        get () {
     
          console.log("get方法被调用了");
          // get方法中的this执行vm
          return this.frilstername + this.lastername
        },
        // 当name属性改变时会调用set方法
        set (value) {
     
          console.log("get方法被调用了");
          // get方法中的this指向vm
          this.frilstername = value[0]
          this.lastername = value[1]
        }
      }
    }
  })
</script>

计算属性简写形式

计算属性简写前提:当所用的计算属性只考虑读取,不考虑修改时,才可以简写

<body>
  <div class="box"><input type="text" v-model:value="frilstername"><br><input type="text" v-model:value="lastername"><br>
    全名<span>{
   {username}}</span>
  </div>
</body>

<script>
  let vm = new Vue({
      
    el: ".box",
    data: {
      
      frilstername: "张",
      lastername: "三"
    },
    computed: {
      
      // 当所用的计算属性只是用来获取,不会修改时,才可以简写,将计算属性的set方法省略,
      // 计算属性可以不写成对象形式,计算属性直接是一个函数 相当于get方法
      // username: function () {return this.frilstername + this.lastername},


      // 再进一步简写:无构造函数的函数,不要function
      username () {
       return this.frilstername + this.lastername }
    }
  })
</script>

十一、属性监视watch

  • 当被监视的属性变化时, 回调函数自动调用, 进行相关操作
  • 监视的属性必须存在,才能进行监视
  • 监视的两种写法:
    • (1).new Vue时传入watch配置
    • (2).通过vm.$watch监视

😂 注意:watch默认不监测对象内部值的改变(只监视一层),要想深度监视需要配置开启深度监视

第一种监视方法

<body>
  <div class="box">
    姓名:<samp>{
   {user.name}}</samp>
    年龄:<span>{
   {user.age}}</span>
    <span>{
   {use}}</span>
    <button @click="fun">切换</button>
  </div>
</body>

<script src="../js/vue.js"></script>
<script>
  new Vue({
      
    el: ".box",
    data: {
      
      user: {
       name: "zs", age: 18 }
    },
    methods: {
      
      fun () {
      
        // this._data.user.name = "王五"
        this.user = {
       name: "wz", age: 20 }
      }
    },
    computed: {
      
      use () {
      
        return this.user.name + this.user.age
      }
    },
    watch: {
      
      // 监视user属性,并不是监视user属性的内容发生变化
      user: {
      

        // 1、handler():当user属性发生改变时,调用handler()方法
        // newvalue:被监视属性变化后的值,oldvalue:被监视属性变化前的值
        
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值