vue基础笔记

本文详细介绍了Vue.js的基础知识,包括框架与库的区别、MVVM模式、Vue的生命周期、Mustache语法、声明式渲染、指令、计算属性、属性使用及事件处理。通过实例解析了Vue中的v-if/v-show、v-for、v-bind、v-on等关键概念,并探讨了Vue中样式绑定和过滤器的使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

建议首先要明白它主要用来干什么的?怎么用?不要盲目跟从使用,要符合自己项目开发要求,适合才用。—使用前一定要明白

框架和库的区别

  • 框架:是一套完整的解决方案;对项目的侵入性较大,项目如果需要更换框架,则需要重新架构整个项目。
    • node中的express。
  • 库(插件):提供某一个小功能,对项目的侵入性较小,如果某个库无法完成某些需求,可以很容易切换到其他库实现需求。

MVC 与 MVVM 之间区别

  • MVC 是后端的分层开发概念。
  • MVVM是前端视图层概念,主要关注与视图层分离,分为了三部分:Model、View、VM ViewModel。

在这里插入图片描述

Vue与MVVM之间的对应关系

<div id="app">
    <!--vue实例所控制的这个元素区域,就是v-->
    <p>{{msg}}</p>
</div>
<script>
    // new 出来的这个vm对象,就是mvvm中的vm调度者
    var vm = new Vue({
        // 表示,当前 new 的这个vue实例要控制页面上的哪个区域
        el: '#app',
        // data 属性中,存放的是el 中要用到的数据
        // 这里的data就是MVVM中的M,专门保存每个页面的数据的
        data: {
            msg: '欢迎学习Vue'
        }
    });
</script>

Vue的生命周期(重要)

  • 什么是生命周期:从Vue实例创建、运行、到销毁期间,总是伴随着各种各样的事件,这些事件,统称为生命周期!

  • 生命周期钩子:就是生命周期事件的别名而已;

  • 生命周期钩子 = 生命周期函数 = 生命周期事件

  • 主要的生命周期函数分类:

  • 创建期间的生命周期函数:

    • beforeCreate:实例刚在内存中被创建出来,此时,还没有初始化好 data 和 methods 属性
      • created:实例已经在内存中创建OK,此时 data 和 methods 已经创建OK,此时还没有开始 编译模板
      • beforeMount:此时已经完成了模板的编译,但是还没有挂载到页面中
      • mounted:此时,已经将编译好的模板,挂载到了页面指定的容器中显示
  • 运行期间的生命周期函数:

    • beforeUpdate:状态更新之前执行此函数, 此时 data 中的状态值是最新的,但是界面上显示的 数据还是旧的,因为此时还没有开始重新渲染DOM节点
      • updated:实例更新完毕之后调用此函数,此时 data 中的状态值 和 界面上显示的数据,都已经完成了更新,界面已经被重新渲染好了!
  • 销毁期间的生命周期函数:

    • beforeDestroy:实例销毁之前调用。在这一步,实例仍然完全可用。
      • destroyed:Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。

在这里插入图片描述

<div id="app">
    <input type="button" value="修改msg" @click="msg='No'">
    <h3 id="h3">{{msg}}</h3>
</div>

<script>
    new Vue({
        el: '#app',
        data: {
            msg: 'ok'
        },
        methods: {
            show: function () {
                console.log('执行了show方法');
            }
        },
        // 第一个生命周期函数,表示实例完成被创建出来之前会执行它
        beforeCreate() {
            // 输出为undefined,因为Vue还没有初始化
            // 注意:在beforeCreate声明周期函数执行的时候,data和methods中的数据都还没有初始
            console.log(this.msg);
        },
        // 第二个生命周期函数
        created() {
            // 在created中,data和methods都已经初始化好了
            console.log(this.msg);
        },
        // 第三个生命周期函数
        beforeMount() {
            // 表示模板已经在内存中编辑完成率,但是尚未把模板渲染到页面中
            console.log(document.getElementById('h3').innerText);
        },
        // 第四个生命周期函数
        // 是实例创建期间的最后一个生命周期函数,当执行完mounted就表示
        mounted() {
            // 表示内存中的模板,已经真实的挂载到了页面中
            console.log(document.getElementById('h3').innerText);
        },
        // 运行中的两个事件
        beforeUpdate() {
            // 表示界面没有被更新,但数据已经更新了
            console.log('界面上元素的内容:' + document.getElementById('h3').innerText);
            console.log('data中的msg:' + this.msg);
        },
        updated() {
            console.log('界面上元素的内容:' + document.getElementById('h3').innerText);
            console.log('data中的msg:' + this.msg);
        }

    });
</script>

Mustache 语法 (双大括号)

<p>{{msg}}</p>
  • 使用JavaScript表达式,每个绑定都只能包含单个表达式。
{{ ok ? 'YES' : 'NO' }}
<!-- 流控制也不会生效,请使用三元表达式 -->
{{ if (ok) { return message } }}

声明式渲染

  • 通过js中new Vue声明一对象。
  • el 绑定的是要控制的区域的选择器。
  • data 数据源。
<!-- 使用vue必须引入它的js文件,即配置环境,后续代码省略 -->
<script src="lib/vue.js"></script>
<div id="app">
    <p>{{msg}}</p>
</div>
<script>
    var vm = new Vue({
        el: '#app',
        data: {
            msg: '欢迎学习Vue'
        }
    });
</script>

Vue是响应式的,会自动检测数据的变化,但以下变动是Vue无法检测的,也不会触发视图更新:

  • 通过索引直接设置项,比如app.books[3] = {…}。
  • 修改数组长度,比如app.books.length = 1。

解决第一个问题:

  1. 使用Vue内置的set方法:

    Vue.set(app.boos, 3, {
        name: '《CSS》',
        author: 'kim'
    });
    
  2. 使用$set (webpack中默认没有导入Vue):

    this.$set(app.boos, 3, {
        name: '《CSS》',
        author: 'kim'
    });
    
    // 这里的this指向的就是当前组件实例,即app
    
  3. 使用splice()方法

// arrayObject.splice(index,howmany,item1,.....,itemX)
this.books.splice(index, 1, newValue);
// this.books.splice(0, 1, 'kim');

指令

指令带有前缀 v-,以表示它们是 Vue 提供的特殊特性。

v-once

只执行一次性地插值,当数据改变时,插值处的内容不会更新。

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

v-cloak

  • 使用 v-cloak 能够解决 插值表达式 闪烁的问题(即网速过慢时,会看到插值表达式原代码)。
<style>
    [v-cloak] {
        display: none;
    }
</style>
<div id="app">
    <!--使用v-cloak能够解决 插值表达式闪烁的问题-->
    <p v-cloak>{{msg}}</p>
</div>

<script>
    var vm = new Vue({
        el: '#app',
        data: {
            msg: '123'
        }
    });
</script>

v-text

  • 格式:v-text:"vmData"

  • 默认v-text 是没有闪烁问题的。

  • **v-text 会覆盖元素中原本的内容,**但是插值表达式只会替换之间的这个占位符,不会整个元素的内容替换掉。

<div id="app">
    <h4 v-text="msg">================</h4>
</div>
<script>
    var vm = new Vue({
        el: '#app',
        data: {
            msg: '123'
        }
    });
</script>

v-html

  • v-html 也会覆盖元素中原本的内容,不过会把数据以html渲染方式展示。
<div id="app">
    <!--输出为h1样式的 hahahaha -->
    <div v-html="msg2"></div>
</div>
<script>
    var vm = new Vue({
        el: '#app',
        data: {
            msg2: '<h1>hahahaha</h1>'
        }
    });
</script>

v-bind 绑定属性

  • 格式:v-bind:属性="vmData"

  • v-bind: 可以被简写为 :

  • v-bind 用于绑定属性的指令,可以写合法的js表达式。

<div id="app">
    <!-- 当指向button时会出现 这是一个自定义title123 标题 -->
    <!-- <input type="button" value="按钮" :title="mytitle + 123"> -->
    <input type="button" value="按钮" v-bind:title="mytitle + 123">
</div>
<script>
    var vm = new Vue({
        el: '#app',
        data: {
            mytitle: '这是一个自定义title'
        }
    });
</script>

动态参数

从 2.6.0 开始,可以用方括号括起来的 JavaScript 表达式作为一个指令的参数:

<a v-bind:[attributeName]="url"> ... </a>

这里的 attributeName 会被作为一个 JavaScript 表达式进行动态求值,求得的值将会作为最终的参数来使用。例如,如果你的 Vue 实例有一个 data 属性 attributeName,其值为 "href",那么这个绑定将等价于 v-bind:href

注意:要回避大小写和空格

v-on 事件绑定机制

  • 格式:v-on:事件="事件函数名"
  • 在 vue对象中的 methods 编写自定义函数。
  • 缩写为 @ ,比如:@事件="事件函数名"
<div id="app">
    <input type="button" value="按钮" v-on:click="show">
    <!--缩写为 @-->
    <input type="button" value="按钮" @click="show">
</div>
<script>
    var vm = new Vue({
        el: '#app',
        data: {},
        methods: {
            show: function () {
                alert('hello');
            }
        }
    });
</script>

事件修饰符

  • .stop 阻止冒泡。
  • .prevent 阻止默认事件。
  • .captaure 添加事件侦听器时使用事件捕获模式(冒泡的相反执行顺序,从外到里)。
  • .self 只当事件在该元素本身(比如不是子元素)触发时触发回调。
  • .once 事件只触发一次。
<div id="app">
    <!--使用.stop阻止事件冒泡-->
    <div class="inner" @click="divHandler">
        <input type="button" value="点击" @click.stop="btnHandler">
    </div>
    <!--使用 .prevent 阻止默认行为-->
    <a href="https://www.baidu.com" @click.prevent="linkClick">有问题,去百度</a>
</div>
<script>
    var vm = new Vue({
        el: '#app',
        data: {},
        methods: {
            divHandler: function () {
                console.log('这是触发了 inner div 的点击事件');
            },
            btnHandler: function () {
                console.log('这是触发了 btn 的点击事件');
            },
            linkClick: function () {
                console.log('这是触发了 a 的点击事件');
            }
        }
    });
</script>

按键修饰符

在监听键盘事件时,经常需要检查常见的键值。Vue 允许为 v-on 在监听键盘事件时添加按键修饰符。

<input v-on:keyup.enter="submit">
<!-- 也可以直接指定键码,但不推荐 -->
<input v-on:keyup.13="submit">
  • 默认Vue定义的按键别名
    • enter
    • tab
    • delete
    • esc
    • up
    • down
    • left
    • right

自定义按键修饰符

<script>
    Vue.config.keyCodes.别名 = 按键码值;
</script>

js 里面的键盘事件对应的键码

v-model 双向数据绑定

  • 格式:v-model="vmData"

  • 只能在表单中使用。

  • 唯一可以实现双向数据绑定的指令。

<div id="app">
    <input type="text" v-model="text">
</div>
<script>
    var vm = new Vue({
        el: '#app',
        data: {
            text: null
        }
    });
</script>

v-for 循环

  • 循环数组格式:v-for="(item, index) in 循环的vmData"
  • 循环对象格式:v-for="(item, key, index) in 循环的vmData"
  • 参数1必写,其他可选。
  1. 迭代数组
<ul id="app">
  <li v-for="(item, i) in list">
      索引:{{i}} --- 姓名:{{item.name}} --- 年龄:{{item.age}}
  </li>
</ul>
<script>
    var vm = new Vue({
      el: '#app',
      data: {
        list: [1, 2, 3, 4, 5, 6]
      }
    });
</script>
  1. 迭代对象中的属性
	<!-- 循环遍历对象身上的属性 -->
<div id="app">
    <p v-for="(user, i) in list">
        Id:{{ user.id }} --- 名字:{{ user.name }} --- 索引:{{i}}
    </p>
</div>

<script>
    // 创建 Vue 实例,得到 ViewModel
    var vm = new Vue({
      el: '#app',
      data: {
        list: [
          { id: 1, name: 'zs1' },
          { id: 2, name: 'zs2' },
          { id: 3, name: 'zs3' },
          { id: 4, name: 'zs4' }
        ]
      }
    });
</script>
  1. 迭代数字
<p v-for="i in 10">这是第 {{i}} 个P标签</p>

key

2.2.0+ 的版本里,当在组件中使用 v-for 时,key 现在是必须的。

当 Vue.js 用 v-for 正在更新已渲染过的元素列表时,它默认用 “就地复用” 策略。如果数据项的顺序被改变,Vue将不是移动 DOM 元素来匹配数据项的顺序, 而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。

为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,需要为每项提供一个唯一 key 属性。

这个默认的模式是高效的,但是只适用于不依赖子组件状态或临时 DOM 状态 (例如:表单输入值) 的列表渲染输出

key属性注意点:

  • 格式::key="uniqueVmData"

  • v-for 循环的时候,key 属性只能使用 number获取string。

  • key 在使用的时候,必须使用 v-bind 属性绑定的形式,指定 key 的值。

  • 在组件中,使用v-for循环的时候,或者在一些特殊情况中,如果 v-for 有问题,必须 在使用 v-for 的同时,指定 唯一的 字符串/数字 类型 :key 值。

<div id="app">
    <div>
      <label>Id:
        <input type="text" v-model="id">
      </label>
      <label>Name:
        <input type="text" v-model="name">
      </label>
      <input type="button" value="添加" @click="add">
    </div>
    <p v-for="item in list" :key="item.id">
      <input type="checkbox">{{item.id}} --- {{item.name}}
    </p>
</div>
<script>
    var vm = new Vue({
      el: '#app',
      data: {
        id: '',
        name: '',
        list: [
          { id: 1, name: '李斯' },
          { id: 2, name: '嬴政' },
          { id: 3, name: '赵高' },
          { id: 4, name: '韩非' },
          { id: 5, name: '荀子' }
        ]
      },
      methods: {
        add() { // 添加方法
          this.list.unshift({ id: this.id, name: this.name })
        }
      }
    });
</script>

v-if 判断

一般来说,v-if 有更高的切换消耗而 v-show 有更高的初始渲染消耗。因此,如果需要频繁切换 v-show 较好,如果在运行时条件不大可能改变 v-if 较好。

  • v-elsev-else-ifv-if
  • v-ifv-for 不推荐同时使用,v-for 优先级比 v-if 高。
<div id="app">
    <input type="button" value="toggle" @click="flag=!flag">
    <h3 v-if="flag">这是用v-if控制的元素</h3>
    <h3 v-show="flag">这是用v-show控制的元素</h3>
</div>
<script>
    var vm = new Vue({
      el: '#app',
      data: {
        flag: false
      }
    });
</script>

<template> 元素上使用 v-if 条件渲染分组

如果想切换多个元素,可以把一个 <template> 元素当做不可见的包裹元素,并在上面使用 v-if。最终的渲染结果将不包含 <template> 元素。

<template v-if="ok">
  <h1>Title</h1>
  <p>Paragraph 1</p>
  <p>Paragraph 2</p>
</template>

v-show

  • 带有 v-show 的元素**始终会被渲染并保留在 DOM 中。v-show 只是简单地切换元素的 CSS 属性 display。 **
  • v-show 不支持 <template> 元素,也不支持 v-else

计算属性(computed)

  • 对于任何复杂逻辑,应当使用计算属性。

  • 格式:

    computed: {
    	名: 值 | 函数return
    }
    
    var vm = new Vue({
      el: '#demo',
      data: {
        firstName: 'Foo',
        lastName: 'Bar'
      },
      computed: {
        fullName: function () {
          return this.firstName + ' ' + this.lastName
        }
      }
    });
    
  • 计算属性默认只有getter属性,不过也可以添加setter方法。

    // ...
    computed: {
      fullName: {
        // getter
        get: function () {
          return this.firstName + ' ' + this.lastName
        },
        // setter
        set: function (newValue) {
          var names = newValue.split(' ')
          this.firstName = names[0]
          this.lastName = names[names.length - 1]
        }
      }
    }
    // ...
    

计算属性缓存 vs 方法

不同的是计算属性是基于它们的依赖进行缓存的。只在相关依赖发生改变时它们才会重新求值。而方法则每当触发重新渲染时总会再次调用。

watch属性的使用

  • 在Vue对象中,使用 watch 声明。
  • 格式:watch: {'data中属性名': function(){} }
  • 使用这个属性,可以监视data中指定数据的变化,然后触发这个watch中对应的function处理函数,每个function都有两个可选参数,第一个newVal新值,第二个oldVal旧值。
  • 优势:可以监听非DOM(如地址)的变化。
  1. 监听data中属性的改变:
<div id="app">
    <input type="text" v-model="firstname">+
    <input type="text" v-model="lastname">=
    <input type="text" v-model="fullname">
</div>

<script>
    var vm = new Vue({
        el: '#app',
        data: {
            firstname: '',
            lastname: '',
            fullname: ''
        },
        methods: {},
        watch: {
            'firstname': function (newVal) {
                this.fullname = newVal + this.lastname;
            },
            'lastname': function (newVal) {
                this.fullname = this.firstname + newVal;
            }
        }
    })
</script>
  1. 监听路由对象的改变:
<div id="app">
    <router-link to="/login">登录</router-link>
    <router-link to="/register">注册</router-link>

    <router-view></router-view>
</div>

<script>
    var login = {
        template: '<h3>这是登录子组件,这个组件是 奔波霸 开发的</h3>'
    }

    var register = {
        template: '<h3>这是注册子组件,这个组件是 霸波奔 开发的</h3>'
    }

    var router = new VueRouter({
        routes: [
            {path: '/', redirect: '/login'},
            {path: '/login', component: login},
            {path: '/register', component: register}
        ]
    });

    var vm = new Vue({
        el: '#app',
        data: {},
        methods: {},
        router: router,
        watch: {
            '$route.path': function (newVal, oldVal) {
                if (newVal === '/login') {
                    console.log('欢迎进入登录页面');
                } else if (newVal === '/register') {
                    console.log('欢迎进入注册页面');
                }
            }
        }
    })
</script>

watchcomputedmethods之间的对比

  1. computed属性的结果会被缓存,除非依赖的响应式属性变化才会重新计算。主要当作属性来使用。
  2. methods方法表示一个具体的操作,主要书写业务逻辑。
  3. watch一个对象,键是需要观察的表达式,值是对应回调函数。主要用来监听某些特定数据的变化,从而进行某些具体的业务逻辑操作;可以看作是computedmethods的结合体。

在Vue中使用样式(利用v-bind绑定class属性)

使用class样式

PS:必须要用单引号括起,否则默认当变量去vue对象中找。配合v-bind使用

  1. 数组

    <h1 :class="['red', 'thin']">这是一个H1</h1>
    
  2. 数组中使用三元表达式

    <h1 :class="['red', 'thin', isactive?'active':'']">这是一个H1</h1>
    <script>
        var vm = new Vue({
            el: '#app',
            data: {
                isactive: true
            }
        });
    </script>
    
  3. 数组中嵌套对象

    <div id="app">
        <h1 :class="['red', 'thin', {'active': isactive}]">这是一个H1</h1>
    </div>
    <script> // ...与上面script一样... </script>
    
  4. 直接使用对象

    <h1 :class="{red:true, italic:true, active:true, thin:true}">这是一个H1</h1>
    

使用内联样式

PS:含有-的css属性必须用单引号括起。

  • 自动添加前缀:当 v-bind:style 使用需要添加浏览器引擎前缀的 CSS 属性时,如 transform,Vue.js 会自动侦测并添加相应的前缀。

  • 多重值:从 2.3.0 起可以为 style 绑定中的属性提供一个包含多个值的数组,常用于提供多个带前缀的值。这样写只会渲染数组中最后一个被浏览器支持的值。

    <div :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }"></div>
    
  1. 直接在元素上通过 :style 的形式,书写样式对象
<h1 :style="{color: 'red', 'font-size': '40px'}">这是一个善良的H1</h1>
  1. 将样式对象,定义到 data 中,并直接引用到 :style
  • 在data上定义样式:
data: {
        h1StyleObj: { color: 'red', 'font-size': '40px', 'font-weight': '200' }
}
  • 在元素中,通过属性绑定的形式,将样式对象应用到元素中:
<h1 :style="h1StyleObj">这是一个善良的H1</h1>
  1. :style 中通过数组,引用多个 data 上的样式对象
  • 在data上定义样式:
data: {
        h1StyleObj: { color: 'red', 'font-size': '40px', 'font-weight': '200' },
        h1StyleObj2: { fontStyle: 'italic' }
}
  • 在元素中,通过属性绑定的形式,将样式对象应用到元素中:
<h1 :style="[h1StyleObj, h1StyleObj2]">这是一个善良的H1</h1>

过滤器

Vue.js 允许自定义过滤器,可被用作一些常见的文本格式化

过滤器可以用在两个地方:mustache 插值和 v-bind 表达式。过滤器应该被添加在 JavaScript 表达式的尾部,由“|”符指示。

使用过滤器

  • 可添加多个过滤器,执行顺序从左向右。
  • 名字后可带可不带 () ,如果要传参数则需要。
  • 过滤器执行先查找私有再公有,若有同名,私有优先公有。
{{ dataname | 过滤器名字 [|...] }}

私有过滤器(filters属性)

  • 在声明vm对象中通过 filters 属性定义。
  • 第一个参数默认是传过来的参数。
<td>{{item.ctime | capitalize }}</td>
filters: {
  capitalize: function (value) {
    if (!value) return '';
    value = value.toString();
    return value.charAt(0).toUpperCase() + value.slice(1);
  }
}

全局过滤器

  • Vue.filter('过滤器的名称', function (){ // 过滤处理 });
  • 第一个参数默认是传过来的参数。
<td>{{item.ctime | capitalize('123') }}</td>
Vue.filter(capitalize, function (value, addValue = '') {
    if (!value) return '';
    value = value.toString();
    return value + addValue;
});
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值