Vue基础
Vue 是什么之前端现状
Vue 是一个优秀的**
前端框架
** 国内大多数中小型公司都在用,开发者按照 Vue 的**
规范
**进行开发 => 不按照规范开发 就会报错
- 和 DOM**
解耦
** Vue 框架 显示数据 获取数据都不再通过 dom 对象- 适应当前**
SPA
**的项目开发 => single page application 单页应用程序 =>只有一个 html 页面- 传统网站开发 一般来说 需求不大
- 当下各种新框架都采用了**
类Vue
或者类React
**的语法去作 为主语法, 微信小程序/MpVue/uni-app
Vue 特点
响应式数据
数据驱动视图 可以让我们只关注数据 Vue 中数据是响应式的 => 数据变化 => 视图一定变化MVVM
双向绑定 => 数据 <=> 视图 , 数据变化 ==>视图变化 ,视图变化 => 数据变化
- model—模型,数据对象(data)
- view—视图,模板页面
- viewmodel**
(vm)
**—视图模型(Vue 的实例)
- **
指令
**增强了 html 功能 新特性 ,Vue 扩展了 html 标签的功能 用指令, /angular ng-组件化开发
复用代码 => SPA => 10 页面 => 10 个组件
相关链接
Vue 官方文档 >Vue 开源项目汇总 >Vue.js 中文社区
所有关于 Vue 的问题都可以通过**查阅文档
**解决
如何安装 Vue.js
采用本地文件引入的方式 直接下载 在 script 标签中引入
第一个程序–Hello World
1 | <!--1. 设置Vue实例管理的视图 --> |
实例选项
el
- 作用:
当前Vue实例所管理的html视图
在视图之外 ,就不能应用 Vue 特性- 值:通常是 id 选择器(或者是一个 HTMLElement 实例)
- 不要让 el 所管理的视图是 html 或者 body!
1 | //使用id选择器 |
data
- Vue 实例的数据对象,是响应式数据(数据驱动视图) 数据变化 => 视图变化
- 可以通过
vm.$data
访问原始数据对象 =>Vue 框架给所有的属性都加了$特殊符号- Vue 实例 **
vm
**也代理了 data 对象上所有的属性,因此访问vm.a
等价于访问vm.$data.a
- 视图中绑定的数据必须**
显式
**的初始化到 data 中- 数据对象的更新方式 直接 采用
实例.属性 = 值
1 | data: { |
methods
- methods 是一个对象
- 可以直接通过 VM 实例访问这些方法,或者在指令表达式中使用。
- 方法中的
this
自动绑定为 Vue 实例。- methods 中所有的方法 同样也被代理到了 Vue 实例对象上,都可通过 this 访问
- Vue 实例代理了 data 中所有属性,代理了 methods 方法 ,定义属性或者方法时 要考虑**
重名
**问题- 注意,**
不应该使用箭头函数来定义 method 函数
** (例如plus: () => this.a++
)。理由是箭头函数绑定了父级作用域的上下文,所以this
将不会按照期望指向 Vue 实例,this.a
将是 undefined
1 | methods: { |
created
mounted
插值表达式
作用:会将绑定的数据实时的显示出来:
形式: 通过 **
{{ 插值表达式 }}
**包裹的形式通过任何方式修改所绑定的数据,所显示的数据都会被实时替换(响应式数据)
1 | <!-- js表达式 --> |
系统指令
- 指令 (Directives) 是带有
v-
前缀的特殊特性。 对于 html 标签的功能扩展,一个指令对应一个功能- 指令特性的值预期是**
单个 JavaScript 表达式
**(v-for
是例外情况,稍后我们再讨论)。- 指令的职责是,当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM。
- 指令位置: 起始标签
语法
v-指令=“表达式” 如果 表达式想要是一个字符串 就必须这样写(用单引号包裹) v-指令=**" '字符串' "
**,否则会被当做一个 data 数据中的变量
1 | <p v-text="name"></p> |
v-text 和 v-html
很像 innerText 和 innerHTML
v-text:更新标签中的内容
v-text 和插值表达式的区别
- v-text 更新**
整个
**标签中的内容- 插值表达式: 更新标签中**
局部
**的内容v-html:更新标签中的内容/标签
可以渲染内容中的 HTML 标签
注意:尽量避免使用,容易造成危险 (XSS 跨站脚本攻击)
1 | <p v-text="name"></p> |
v-if 和 v-show–条件渲染
场景: 需要根据条件决定 元素是否显示 使用以上指令
使用: v-if 和 v-show 后面的表达式返回的布尔值 来决定 该元素显示隐藏
注意 :
v-if 是直接决定元素 的 添加 或者删除 而 v-show 只是根据样式来决定 显示隐藏
v-if
有更高的切换开销,而v-show
有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用
v-show
较好;如果在运行时条件很少改变,则使用
v-if
较好。如果 切换频繁 前者 开销更大
扩展
如果 有多个元素需要根据条件进行渲染,怎么办?我们可以用一个**div标签
来包裹多个元素
**,
但是这样的话 我们相当于**多了一个div标签
,我们可以采用一个template
**标签,来解决这个问题,template 标签不会产生任何实质的标签在页面上,并且能完成相应的功能
1 | <p v-if="showMessage">v-if</p> |
v-on–事件处理
- 场景: 使用 v-on 指令给元素绑定事件
- 使用: 绑定 v-on:事件名.修饰符=”方法名” 可使用 @事件名=”方法名的方式”
- 注意 方法名 中 可以采用$event 的方式传形参 也可以直接写事件名 默认第一个参数为 event 事件参数
- 如果只写方法名 不写括号 =>方法中默认传入的第一个参数就是事件参数 =>event
修饰符(可不写)
.once
- 只触发一次回调。.prevent
- 调用event.preventDefault()
。
1 | <div id="app"> |
v-for–列表渲染
v-for-数组
目标
:掌握 v-for 循环数组的用法
- 根据一组数组或对象的选项列表进行渲染。
v-for
指令需要使用item in items
或者item of items
形式的特殊语法,items
是源数据数组 /对象循环生成谁,就在谁的标签上写v-for指令
当要渲染相似的标签结构时用 v-for
1
2
3
4
5
6
7 item in
items(
// item为当前遍历属性数组项的值
item,
index
) in
items; //item为当前遍历属性数组项的值 index为数组的索引
1 | <div id="app"> |
v-for-对象
1 | 基本语法; |
1 | <div id="app"> |
v-for-key
目标
: 掌握在 v-for 循环中给循环项赋值 key
场景:列表数据变动会导致 视图列表重新更新 为了 提升性能 方便更新 需要提供 一个属性 key
使用: 通常是给列表数据中的唯一值 也可以用索引值
1 | <li v-for="(item,key,index) in person" :key="index"> |
当 v-if 和 v-for 相遇
v-for 的优先级大于 v-if ,所有 v-if 才能使用 v-for 的变量
1 | <li |
v-bind–Class 与 Style 绑定
v-bind–绑定一般属性
作用:
绑定标签上的任何属性场景:
当标签上的属性是变量/动态/需要改变的语法:
属性=”表达式”
1 | <img :src="src" alt=""> |
v-bind–绑定 Class-对象用法
语法
:class=”{ class 名称”: 布尔值 }”
1 | <p :class="{class名称:show}">内容</p> |
v-bind–绑定 Class-数组用法
语法
:class=”[class 变量 1,class 变量 2..]”
1 | <p class="default" :class="list"></p> |
v-bind–绑定 style-对象用法
语法
:style=”{css 属性名: 变量}”
1 | <p style="color: red;" :style="{fontSize:fsValue}">文本</p> |
v-bind–绑定 Style-数组用法
语法
:style=”[对象 1,对象 2…]”
1 | <p style="color:red" :style="[obj]">文本</p> |
v-model–表单输入绑定
特点: 双向数据绑定
- 数据发生变化可以更新到界面
- 通过界面可以更改数据
v-model
会忽略所有表单元素的value
、checked
、selected
特性的初始值而总是将 Vue 实例的数据作为数据来源。应该在data
选项中声明初始值。
1 | <input v-model="name" type="text"> |
语法糖
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 <p>{{name}}</p>
//不使用方法
<input type="text" :value="name" @input="name=$event.target.value">
//使用方法
<input type="text" :value="name" @input="fn">
//语法糖效果
<input type="text" v-model="name">
data: {
name: "",
},
methods: {
fn(event) {
this.name = event.target.value;
}
}
v-cloak–防止页面模板闪屏现象
解决页面初次渲染时 页面模板闪屏现象
1 | <style> |
v-once–使得所在元素只渲染一次
使得所在元素只渲染一次 使用场景:静态化数据
1 | <p>{{name}}</p> |
vue 过滤器
data 中的数据格式(日期格式/货币格式/大小写等)需要数据格式化时,可以采用过滤器进行过滤 =>
过滤器函数
=> 对于 data 中数据的格式化处理
使用过滤器
1 | <!-- 在双花括号中 --> |
定义过滤器
全局过滤器
1 | Vue.filter("过滤器名称", function(value) { |
局部过滤器
1 | var vm = new Vue({ |
ref 操作 dom
1 | <button ref="自定义名称">按钮</button> this.$refs.自定义名称.value; |
自定义指令
需要对普通 DOM 元素进行操作,这时候就会用到自定义指令
使用自定义指令
1 | <p v-自定义指令名称></p> |
全局自定义指令
1 | Vue.directive("自定义指令名称",{ |
局部自定义指令
1 | var vm = new Vue({ |
计算属性
当表达式过于复杂的情况下 可以采用计算属性 对于任何复杂逻辑都可以采用计算属性
- 说明: 计算属性的值 依赖 数据对象中的值 数据对象发生改变 => 计算属性发生改变=> 视图改变
- 计算属性**
必须有返回值
** 相当于对插值表达式**逻辑的一次封装
**- methods 方法和计算属性的区别
- 1 使用时 方法必须写括号**
()
**- 2 计算属性有**
缓存机制
** => 计算属性依赖 data 中的数据 => 第一次执行计算属性完毕之后,计算属性会将计算结果放入缓存 => 第二次执行计算属性时 => 发现计算属性依赖的数据没有变化 => 从缓存中获取缓存,不再执行计算属性逻辑- 计算属性可以抽提复杂的逻辑 /还比方法的效率更高
使用计算属性
1 | <p>{{计算属性名}}</p> |
定义计算属性
1 | var vm = new Vue({ |
json-server 工具的使用
安装
1 | npm i -g json-server |
使用
新建一个 json 文件 db.json 并创建内容
1 | { |
在相应的目录运行如下命令
1 | json-server --watch db.json |
RESTFUL 的接口规则
- RESTful 是一套接口设计规范
- 用**
不同的请求类型
发送同样一个请求标识
** 所对应的处理是不同的
- 同样的请求标识(同一个地址) =>不同的请求类型 => get/post/put/delete
- 通过 Http 请求的不同类型(POST/DELETE/PUT/GET)来判断是什么业务操作(CRUD )
- CRUD =>
增删改查
- json-server 应用了 RESTful 规范
HTTP 方法 | 数据处理 | 说明 |
---|---|---|
POST | Create | 新增一个没有 id 的资源 |
GET | Read | 取得一个资源 |
PUT | Update | 更新一个资源。或新增一个含 id 资源(如果 id 不存在) |
DELETE | Delete | 删除一个资源 |
查询数据 GET /brands 获取 db.json 下 brands 对应的所有数据
列表
GET /brands/1 查询 id=1 数据
单条
删除数据 DELETE /brands/1 删除 id=1 数据
修改数据 PUT /brands/1 请求体对象
上传/添加 POST /brands 请求体对象
查询 GET /brands?
title
_like=关键字 -> 模糊搜索
使用 axios 插件发送网络请求
promise 是一种对于 ajax**
回调地狱
**的一种 异形封装,它让代码看上去更优雅
安装
script 标签导入 点击下载
1 | <script src="https://unpkg.com/axios/dist/axios.min.js"></script> |
npm 方式安装
1 | npm install axios |
使用
1 | axios.get("url").then(function(data) { |
watch-监听
watch 选项就是 Vue 实例的选项 watch:{}
那个
data中的属性
发生改变就监听谁
1 | new Vue( |
组件
特点
:是一个特殊的Vue实例
每个组件都是
独立
的和 Vue 实例相似之处: data/methods/computed/watch 等一应俱全 Vue 实例有的 组件基本都有
组件没有 el ,但是有 template => 组件页面结构
注意 值得注意的是 data 和 Vue 实例的区别为 组件中 data 为一个函数 没有 el 选项
组件的 data 是一个带**
返回值的函数
** => 因为组件的数据是独立的,data => 返回一个新数据template 代表其**
页面结构
** (有且只要一个根元素)每个组件都是**
独立
**的 运行作用域 数据 逻辑没有任何关联template:有且只有一个根元素
data: 数据管理=>函数=>带返回值的函数=>{}
错误提示:
1 vue.js620 [Vue warn] Do not use built-in or reserved HTML elements as component id menu
不能使用内置或者保留的HTML或者组件作为组件id
意思就是你使用的组件名的名称跟系统(vue)的内置属性名冲突了,所以创建失败,最好的方法就是换个名字。
使用组件
1 | <组件名称></组件名称> |
全局组件
1 | Vue.component(组件名称, { |
局部组件
1 | var obj = { |
组件嵌套
在父模板中使用其他组件的标签
一旦形成
组件嵌套
,就会形成父子关系
1 | new Vue({ |
父组件给子组件传值 Props
- 定义属性 给谁传值 就给标签写传递的属性
- 接收属性 谁用属性谁接收
- 使用它 Vue 实例代理了所有的
data属性
/methods方法
/计算属性
/props属性
1 | <abc-d :test="name"></abc-d> |
1 | var vm = new Vue({ |
子组件给父组件传值(自定义事件)
可通过子组件中触发
$emit
事件
1 | <abc-d @clickfn="fn2"></abc-d> |
1 | var vm = new Vue({ |
非父子传值
- 在 A 组件绑定自定义事件,接收触发事件的数据。
- 在 B 组件触发自定义事件,提交数据即可。
- 补充:谁绑定的事件只有有谁触发。
- 使用 C 专门负责绑定事件。
在src
的根目录下创建eventBus.js
写入如下代码
1 | import Vue from "vue"; |
创建两个组件
com-a.vue
1 | <template> |
com-b.vue
1 | <template> |
动态组件
- activated – 激活组件的钩子
- deactivated – 离开组件的钩子
一级路由处理方法
Props:
include
- 字符串或正则表达式。只有名称匹配的组件会被缓存。exclude
- 字符串或正则表达式。任何名称匹配的组件都不会被缓存。max
- 数字。最多可以缓存多少组件实例。
二级路由处理方法
- 并非所有组件要做缓存,所以按需缓存
- 两层路由组件,根据路由规则信息,决定 keep-alive 是否包裹 router-view
在有需要缓存
的 vue 文件中写入
1 | <keep-alive> |
在router.js
文件下写入
1 | const routes = [ |
单页应用-SPA
- 传统模式 每个页面及其内容都需要从服务器一次次请求 如果网络差, 体验则会感觉很慢
- spa 模式,
第一次加载
会将所有的资源都请求到页面 模块之间切换不会再请求服务器
特点
- 优点
- 用户体验好
- 缺点
首屏
加载慢- 不利于 SEO
实现原理
通过页面的
锚链接
来实现spa
hash(锚链接)位于链接地址
#
之后hash 值的改变**
不会触发
**页面刷新hash 值是 url 地址的一部分,会存储在页面地址上 我们可以获取到
可以通过**
事件监听
**hash 值得改变拿到了 hash 值,就可以根据不同的 hash 值进行不同的**
模块切换
**
路由
js 实现路由
采用 hash 值改变的特性来进行前端路由切换
1 | <!-- 定义导航 --> |
1 | <script> |
vue-router-插件
下载安装 / CDN
通过 script 引入
通过 npm 安装
1 | npm install vue-router |
使用 VueRouter
使用步骤
- 引入 vue-router.js
- 定义导航
- 定义容器
- 实例化一个 VueRouter 对象
- 配置路由表=>实例化对象中配置路由表
- 发生关系 要讲
1 | <router-link to="/bj">北京</router-link> |
1 | <script src="/path/to/vue.js"></script> |
动态路由
- 定义路由产生
path:"/brand/:id"
- 传递路由参数
- 通过
this.$route.params.id
获取参数
路由规则 | 匹配路径 | $route.params |
---|---|---|
/user/:username | /user/evan | { username: 'evan' } |
/user/:username/post/:post_id | /user/evan/post/123 | { username: 'evan', post_id: '123' } |
1 | <router-link to="/user/北京/1">北京</router-link> |
1 | var router = new VueRouter({ |
to–命名路由
1 | <!-- 字符串 --> |
1 | var router = new VueRouter({ |
重定向
希望某个页面被强制中转,
拦截谁就在谁的组件上写redirect:
1 | <router-link to="/bj">北京</router-link> |
1 | var router = new VueRouter({ |
编程式的导航
跳转不同的组件 不仅仅可以用**
router-link
** 还可以采用**代码行为
**(Vue 实例)
this.$router
可以拿到当前路由对象的实例**
router-link
和push
**方法都是追加历史记录
$router
的方法如下push–追加记录
replace–替换记录
go–前进或后退
1 | //追加记录 |
激活样式
设置激活 class 样式
router-link-active 是一个固定的 class => 该 class 默认值就是 router-link-active,可以变,
linkActiveClass => 改变 router-link 的激活样式的 class
1 | <style> |
1 | var router = new VueRouter({ |
嵌套路由
如果存在组件嵌套,就需要提供多个视图容器<router-view></router-view>
1 | <router-link to="/bj">北京</router-link> |
1 | var router = new VueRouter({ |
过渡动效
采用了 v-if 或 v-show
是基本的动态组件,所以我们可以用
组件给它添加一些过渡效果:
1 | <style> |
1 | var vm = new Vue({ |