vue基本概述 Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。 Vue.js是一套构建用户界面的渐进式框架,采用自底向上增量开发的设计。Vue的核心库关注于视图(html),不仅易上手,还便于与第三方库或项目整合。 渐进式:一步一步,不是将所有的东西都学完才能...
枫枫知道--Vue全系列课程
发布时间: 2025-07-23 (a year ago)
Vue

vue基本概述

Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。

Vue.js是一套构建用户界面的渐进式框架,采用自底向上增量开发的设计。Vue的核心库关注于视图(html),不仅易上手,还便于与第三方库或项目整合。

渐进式:一步一步,不是将所有的东西都学完才能使用。

自底向上设计:一种设计程序的过程和方法,就是先编写出基础程序段,然后在逐步扩大规范、补充和升级某些 功能,实际上是一种自底向上构造程序的过程。

Vue.js的核心是允许采用简洁式模板语法来声明的将数据渲染进DOM的系统

在使用数据之前需要先进性声明才可以使用

为什么要学习Vue?

简单,前端三大框架(Vue,React,angler)中是对小白最友好的框架

另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。

Vue和Jquery有什么区别?

数据驱动试图

  1. jquery到vue转变是一个思想的转变,是将jquery直接操作dom的思想转变到操作数据上去。
  2. jQuery是使用选择器选取DOM对象,对其进行赋值、取值、事件绑定等操作,其实和原生的HTML的区别只在于可以更方便的选取和操作DOM对象
  3. Vue则是通过Vue对象将数据和View完全分离开来了。对数据进行操作不再需要引用相应的DOM对象,可以说数据和View是分离的,他们通过Vue对象这个vm实现相互的绑定。这就是传说中的MVVM

什么时候学习Vue?

先把前端三件套熟悉(HTML,CSS,JavaScript)

Vue基本语法

官方文档

插值表达式

使用{{ }}进行渲染data:{}里面的变量

也可以是函数,不过在data里面的方法,在插值表达式中需要补充大括号

例如

HTML 复制代码
<div id="app">
    <div>{{ msg }}</div>
    <div>{{ getInfo() }}</div>
</div>

在插值表达式中,支持运算符,以及一些方法

vue指令:

v-text

渲染文本,和插值表达式类似

HTML 复制代码
<div></div>
<div>{{ msg }}</div>

也是支持运算符的

HTML 复制代码
<div></div>

v-html

渲染标签,如果字符串是含标签的特殊字符,那么vue会将它渲染成标签

如果是v-text或者是使用插值表达式,则会原样输出

注意:

v-html一般是用来渲染信任的文本,例如文章的详情内容等,最好不要用在用户提交的地方

容易造成XSS攻击

v-bind

可以给标签动态添加内容,也可以给动态的修改标签属性

不过在属性上的操作稍微和操作内容不太一样,我们使用v-bind指令

例如我想动态修改img标签的src属性,希望它去读取data里面的值

但是我们不能在属性中使用插值表达式

这样写src直接将我的内容原样输出了,所以我们需要使用v-bind,全称为动态属性

那么我可以这么做

HTML 复制代码
<img alt="">

当然,v-bind: 可以简写为 :

HTML 复制代码
<img alt="">

v-bind不仅可以用于HTML存在的属性,还可以应用在自定义属性上

例如

HTML 复制代码
<p></p>

实际结果:
<p id="p_01"></p>

在vue所有的指令中,都是支持表达式的

例如:

JavaScript 复制代码
<div class="name">
    {{ a.length === 0 ? '没有数据' : a }}
    -{{ a.split('.')[1] }}
</div>

什么是表达式?

JavaScript 复制代码
// 这是语句
var a = 1;

// 这是表达式
a.length === 0 ? '没有数据' : a

条件渲染

v-if和v-else的普通使用

v-if中的布尔值为true,则渲染这个div

如果if不成立,则渲染else中的代码块

HTML 复制代码
<div id="app">
    <div>{{ num }}</div>
    <div id="if">
        <div>大于0.9的概率</div>
        <div>v-if不满足显示我</div>
    </div>
</div>

v-else-if多条件语句

HTML 复制代码
<div id="v-else-if">
    <div>大于0.9的概率</div>
    <div>大于0.6的概率</div>
    <div>大于0.4的概率</div>
    <div>大于0.2的概率</div>
    <div>所有条件都不成立</div>
</div>

v-if="flag",为true的时候显示

为false的时候消失

JavaScript 复制代码
<div id="app">
    <div class="name">
        {{ name }}
    </div>
    <div>
        if没匹配到就显示我
    </div>

</div>

v-show与v-if的区别

  1. v-if如果是false,不会渲染
  2. v-show如果是false,不会显示 style="display: none;"

体会一下v-if和v-show

HTML 复制代码
一个是看不见,但是我存在,只是我隐藏了    v-show 
一个是看不见,因为我本来就没被渲染       v-if

列表渲染

主要分为遍历列表和遍历对象

遍历列表

JavaScript 复制代码
lis: [
    '张三',
    '王伟',
    '张伟',
    '王五',
]

此时的item就是每个元素

HTML 复制代码
<ul>
    <li>
        {{ item }}
    </li>
</ul>

key要唯一!!!

如果需要遍历出每个元素的索引

则在遍历的时候指定index

HTML 复制代码
<ul>
    <li>
        {{ index }} -- {{ item }}
    </li>
</ul>

遍历对象

JavaScript 复制代码
obj:{
    name: '张三',
    age: 21,
    addr: '北京市',
}

一个参数,就是遍历对象的值

二个参数,值和键

三个参数,值,键,索引

HTML 复制代码
<ul>
    <li>
        对象的值:{{ item }}
    </li>
</ul>
<ul>
    <li>
        对象的值:{{ item }}
        对象的键:{{ key }}
    </li>
</ul>
<ul>
    <li>
        对象的值:{{ item }}
        对象的键:{{ key }}
        变量的索引:{{ index }}
    </li>
</ul>

Vue事件

v-on:或者@

HTML 复制代码
<div id="app">
    <div>
        {{ num }}
    </div>
    <div>
        
        <button>点我 +</button>
        <button>点我 -1</button>
    </div>
</div>

事件所执行的方法是要被定义在methods里面

JavaScript 复制代码
methods: {
    add() {
        this.num ++
    }
}

参数问题

可以通过传参进行参数传递

HTML 复制代码
<button>点我 +</button>


...
add(number) {
    this.num += number
}
// 此时的add函数就能接收到传递进来的参数值

默认参数

默认参数就是触发当前事件的事件对象

JavaScript 复制代码
<button id="add" class="add_cls">点我 +</button>

一定是v-on:click="add",只写一个函数名,

而不是v-on:click="add()",这样获取不到事件对象

JavaScript 复制代码
// 获取触发当前事件的标签
add(event) {
    // 触发当前事件的事件对象
    console.log(event)
    // 获取标签
    console.log(event.target)
    // 获取id,class
    console.log(event.target.id)
    console.log(event.target.className)
}

如果有参数,想接收事件对象

使用$event进行传递

JavaScript 复制代码
<button id="add" class="add_cls">点我 +</button>

...

add(number, event) {
    this.num += number
    // 触发当前事件的事件对象
    console.log(event)
    // 获取标签
    console.log(event.target)
    // 获取id,class
    console.log(event.target.id)
    console.log(event.target.className)
}

图片轮播案例

HTML 复制代码
    
    <title>图片轮播</title>
    


<div id="app">
    <div>
        <img alt="">
    </div>
    <div>
        <button>上一张</button>
        <button>下一张</button>
    </div>
</div>

事件修饰符

在事件处理程序中调用 event.preventDefault()event.stopPropagation() 是非常常见的需求。尽管我们可以在方法中轻松实现这点,但更好的方式是:方法只有纯粹的数据逻辑,而不是去处理 DOM 事件细节。

为了解决这个问题,Vue.js 为 v-on 提供了事件修饰符。之前提过,修饰符是由点开头的指令后缀来表示的。

HTML 复制代码
<a></a>


<form></form>


<a></a>


<form></form>



<div>...</div>



<div>...</div>

<a href="http://www.fengfengzhidao.com">枫枫知道</a>

事件冒泡

HTML 复制代码
<div class="parent">
    <div class="center">
        <div class="child">
        </div>
    </div>
</div>

点击里元素,执行顺序

点击中间的元素

被父元素包裹的元素,点击事件发送后会逐级将事件向上传递

HTML 复制代码
<p>阻止事件冒泡</p>
<div class="parent">
    <div class="center">
        <div class="child">
        </div>
    </div>
</div>

添加stop事件修饰符之后,点击里元素,会阻止事件继续向上传播

键盘事件

HTML 复制代码
@keydown   键盘按下
@keyup     键盘回弹

按下回车触发

支持组合键

HTML 复制代码
<input type="text">
<input type="text">

> 使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生。因此,用 v-on:click.prevent.self 会阻止所有的点击,而 v-on:click.self.prevent 只会阻止对元素自身的点击。

2.1.4新增

HTML 复制代码
<a></a>

按键修饰符

最常见的可能就是在一个输入框中,判断用户是否按下了回车键

HTML 复制代码
<input>

一些必要的按键名称

HTML 复制代码
.enter
.tab
.delete (捕获“删除”和“退格”键)
.esc
.space
.up
.down
.left
.right

组合按键

HTML 复制代码
<input>


<div>Do something</div>

计算属性

  • 调用的时候不用加括号(只是一个属性)
  • 可以监听属性变化,属性变化,计算属性重新执行
  • 并且有缓存(多个计算属性,只执行一次)

和methods的区别

属性变化,methods方法全部重新获取

HTML 复制代码
    
    <title>计算属性</title>
    


<div id="app">
    <div>{{ name }}</div>
    <div>{{ name.split('').reverse().join('') }}</div>
    <div>{{ name.length === 5 ? '五言绝句' : '七言绝句' }}</div>
    <div>五言绝句</div>
    <div>七言绝句</div>
    <div>错了</div>

    
    <div>{{ getName }}</div>
    <div>{{ getName }}</div>
    <div>{{ getName }}</div>
    <div>{{ getName }}</div>
    <div>{{ getName }}</div>
    <div>{{ getName }}</div>
    <div>{{ getName }}</div>
    <div>{{ get_data_name() }}</div>
    <div>{{ get_data_name() }}</div>
    <div>{{ get_data_name() }}</div>
    <div>{{ get_data_name() }}</div>
    <div>{{ get_data_name() }}</div>

    <button>
        点我
    </button>
    <span>{{ num }}</span>
    <button>计算属性</button>
</div>

computed与watch,methods的区别

methods:可以放入函数,并且没有缓存

watch:

监听,当数据发送变化时,才会触发

可以得到现在的值和过去的值

还可以监听路由变化

和属性同名

自定义过滤器

创建一个过滤器

JavaScript 复制代码
// 自定义过滤器
filters:{
    // 截取最后一个字符
    getLastChar(item){
        return item.substr(item.length-1,1)
    }
}

使用过滤器

HTML 复制代码
<li>
    {{item.name|getLastChar }} -- {{ item.addr }}
</li>

时间过滤器

HTML 复制代码
<div id="app">
    <div>
        当前时间:{{ now|get_date }}
    </div>
    <ul>
        <li>
            id:{{ item.id }} 时间:{{ item.date|get_date }}
        </li>
    </ul>
    <div>
        时间过滤
    </div>
    <ul>
        <li>
            id:{{ item.id }} 时间:{{ item.date|time_to_filter }}
        </li>
    </ul>
</div>

参数问题

自定义过滤器也是可以接受参数,它的书写语法是

JavaScript 复制代码
<li>
    id:{{ item.id }} 时间:{{ item.date|time_to_filter('a', 'b') }}
</li>


...

filters: {
    ...
    time_to_filter(date_str, a, b) {
        // date_str  -&gt;  '自身的值'
        // a  -&gt; 'a'
        // b  -&gt; 'b'
        
        return date_str
    }
}

过滤器方法的第一个参数就是调用者本身的值,第二个参数之后就是调用的实参

并且支持链式过滤器

HTML 复制代码
<div>{{now|get_now|get_now1}}</div>

全局方法

需要将属性和方法挂载到Vue.prototype

JavaScript 复制代码
Vue.prototype.$com = "全局变量"

let global_method = ()=&gt;{
    return "全局方法"
}
function add(){
    return "全局 add 方法"
}
Vue.prototype.$global_method = global_method
Vue.prototype.$add = add

使用

HTML 复制代码
<div>
    {{ $global_method() }}
</div>
<div>
    {{ $add() }}
</div>

全局过滤器

JavaScript 复制代码
// 全局过滤器
let global_filter = (item) =&gt; {
    return item + '--global'
}
// 注册全局过滤器   (过滤器名称,方法)
Vue.filter('global_filter', global_filter)

使用全局过滤器

HTML 复制代码
<div>
    {{ $com|global_filter }}
</div>

局部组件

HTML 复制代码
    
    <title>局部组件</title>


<div id="app">
      
</div>

全局组件

HTML 复制代码
    
    <title>局部组件</title>


<div id="app">
      
</div>

组件通信

父传子

父传子:通过props来进行通信

HTML 复制代码
1. 在自组件中声明props接收在父组件挂载的属性
2. 可以在自组件的template在任意使用
3, 在父组件绑定自定义的属性

props传入一个对象

JavaScript 复制代码
props: ['title', 'likes', 'isPublished', 'commentIds', 'author']


props: {
  title: String,
  likes: Number,
  isPublished: Boolean,
  commentIds: Array,
  author: Object,
  callback: Function,
  contactsPromise: Promise // or any other constructor
}


props: {
    data: {
        type: String,  // 类型
        required: true,  // 必填项
        default: '张三'  // 如果没传值,那么这个默认值就是它
    }
}
HTML 复制代码
<div id="app">
      
</div>

created与mounted

JavaScript 复制代码
created(){
    console.log(this.data, 1)
},
mounted(){
    console.log(this.data, 2)
}

子传父

HTML 复制代码
1. 在父组件中,自组件上绑定自定义事件
2. 在自组件中,触发原生的事件,在事件函数通过this.$emit触发自定义的事件

父组件

JavaScript 复制代码
components: {
    comment1
},
methods: {
    eff(data) {
        // data 是子组件传递的数据
        console.log('父组件被调用了', data)
    }
}

子组件

JavaScript 复制代码
let comment1 = {
    template: `
      <div>
      <ul>
        <li>兰州拉面</li>
        <li>哈尔滨啤酒</li>
        <li>四川担担面</li>
        <button>点我触发父组件方法</button>
      </ul>
      </div>`,
    methods: {
        add() {
            this.$emit('eff', {name: '子组件传来的数据'})
        }
    }

}

平行组件

HTML 复制代码
    
    <title>平行组件</title>
    <style>
        body {
            margin: 0;
        }

        #app {
            display: flex;
        }

        #app > div {
            width: 50%;
            height: 200px;
            display: flex;
            justify-content: center;
            align-items: center;
        }

        #gouwuc {
            background-color: #3a8ee6;
        }

        #get {
            background-color: #b3d9d9;
        }
    </style>


<div id="app">
      
      
</div>

多次嵌套取值

HTML 复制代码
1. provide  提供变量  函数(){return {} },
2. inject  接收变量 inject: [],

匿名插槽

JavaScript 复制代码
let base_layout = {
    data() {
        return {}
    },
    template: `
      <div>
      <header>
        我是页头
      </header>
      </div>`
}
new Vue({
    el: '#app',
    components: {
        base_layout
    }
})

在模板中把想要替换的东西放在``标签中,这就是一个占位符

HTML 复制代码
实际的内容

这样就会将标签中的内容去代替slot中的内容

如果slot都没有名字,那么如果有多个slot,就会全部进行替换

具名插槽

如果你的模板中需要有多个地方被替换

那么匿名插槽就不太合适了,我们给每个插槽都起一个别名

JavaScript 复制代码
let base_layout = {
    data() {
        return {}
    },
    template: `
      <div>
      <header>
        我是页头
      </header>
      <main>
        我是内容
      </main>
      <footer>
        我是页脚
      </footer>
      </div>`
}

这样我们在进行替换的时候,指明要替换哪个slot就OK了

HTML 复制代码
    <template>
        头部
    </template>
    <template>
        身体
    </template>
    <template>
        尾部
    </template>

注意v-slot的写法

HTML 复制代码
v-slot:header

v-slot: 可以简写为 #

HTML 复制代码
 
    <template>
        
        <div>
            哈哈哈哈
        </div>
    </template>
    <template>
        身体
    </template>
    <template>
        尾部
    </template>

> 我们在替换的时候,是可以写任意标签的,也就是说,在替换的时候,你也可以将组件写入插槽中

HTML 复制代码
    <template>
        
        <div>
            哈哈哈哈
        </div>
    </template>
    <template>
        身体
    </template>
    <template>
        尾部
    </template>

作用域插槽

JavaScript 复制代码
let base_layout = {
    data() {
        return {
            user: {
                name: '枫枫',
                xin: '知道'
            }
        }
    },
    template: `
      <div>
      <main>
        {{ user.xin }}
      </main>
      </div>`
}

在子组件中,我在插槽里面显示的是user的xin,如果我想让它显示user的name应该怎么做呢

如果我们直接在父组件调用的时候这样写

HTML 复制代码
    {{ user.name }}

这是错误的写法,因为我们的user是被定义再自组件中的,在父组件中就无法使用这个user,所以就会报错啦

那么我们就应该将这个user对象传递给父组件

在子组件中

HTML 复制代码
{{ user.xin }}

通过动态属性的方式将user传递给父组件

在父组件中

HTML 复制代码
    <template>
        {{ slotProps.user.name }}
    </template>

接收传递来的user即可

slotProps可以是你自己定义的名字,它里面存储的是这样的

HTML 复制代码
{ "user": { "name": "枫枫", "xin": "知道" } }

所以我们将slotProps中的user中的name传递给子组件,就可以做到数据动态替换

如果你的组件中,有且只有一个默认插槽,那么在替换的时候,是可以这么做的

HTML 复制代码
    {{ slotProps }}

但是,如果出现了具名插槽,这样会导致作用域混乱

我们应该这样使用

JavaScript 复制代码
let base_1 = {
    data(){
        return {
            user: {
                name: '枫枫知道',
                age: 21
            }
        }
    },
    template: `
    <div>
    <header>
      我的名字是 {{ user.name }},年龄是{{ user.age }}
    </header>
    </div>`
}
HTML 复制代码
    <template>张子枫</template>
    <template>{{ slotBase }}</template>

动态组件

> ``元素是vue 里面的一个内置组件。
在里面使用 v-bind: is,可以实现动态组件的效果。

自定义指令

前面使用的v-if, v-show,以及v-for这些都是Vue为我们提供的内置指令

当然,我们也可以自己自定义一个指令

局部自定义指令

JavaScript 复制代码
directives: {
    focus: {
        // 指令的定义
        // 使用这个指令就会聚焦在输入框中
        inserted: function (el) {
            el.focus()
        }
    }
}

使用

HTML 复制代码
<input type="text">

在focus中有几个钩子函数,需要了解

  • bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
  • inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
  • update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。