Vue是什么?
是一套用于构建用户界面的渐进式(Vue可以自顶向上做成的应用)JavaScript框架
Vue的特点
[Vue官方API网站](Vue.js - 渐进式 JavaScript 框架 | Vue.js (vuejs.org))
编写一个HelloWorld 小案例
HelloWorld,{{ name }}
总结1:
1.想让Vue工作,必须创建一个Vue实例(new Vue),且要传入一个配置对象
2.id为root中的div容器中的代码依然符合html规范,知识中间有一些特殊的Vue语法
3.root容器中的代码被称为【Vue模板】
4.Vue实例和容器是一一对应的
5.在真实的开发场景中,只存在一个Vue实例,配合组件一起使用
- {{ xxx }}中的内容需要写入js表达式,也就是一切可以返回值的东西
7.一旦data中的数据更新,页面中使用到该数据的地方也会自动更新
HelloWorld,{{ name }}
插值语法:{{ name }}
数据绑定
单项数据绑定:
双向数据绑定:
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实例了,如果没有向上继承,则this指代的是Window对象。
Vue中有两种数据绑定方式,使用指令语法:
注意:
1.双向绑定一般只应用于表单类元素上(input等)
2.v-bind可以简写为 : ,而v-model:value一般可以简写为v-model(因为默认收集的就是value值)
我们拆开来看:
1.M:模型(model):对应的是data中的数据
2.V:视图(View):对应页面或者实现页面的Vue模板
3.VM:视图模型(ViewModel):Vue实例
对应到代码中就是:
小结论:
1.data中所有的属性,最后都出现到了VM上(通过数据代理)
2.VM上的所有属性以及Vue原型上的所有属性,在Vue模板中都可以直接使用
案例:
事件的使用
小案例:
绑定键盘事件一般有两个
绑定按键写法:@keydown.key值/keyCode || @keyup.key值/keyCode
Vue中带用的按键别名:
小案例:
键盘事件:
什么是计算属性
写法:
数字1:
数字2:
求和:{{ sum }}
小案例:
今天天气很{{ info }}
a的值{{ num.a }}
区别:
1.computed能完成的功能,watch都可以完成。
2.watch能完成的功能,computed不一定能完成,例如: watch可以进行异步操作。两个重要的小原则:
1.所被Vue管理的函数,最好写成普通函数,这样this的指向才是vm或组件实例对象。
2.所有不被Vue所管理的函数,最好写成箭头函数(定时器的回调函数、ajax的回调函数等),这样this的指向才是vm或组件实例对象。
条件渲染指令
v-if系列
写法:v-if="表达式"
v-else-if="表达式"
v-else
(注意v-else是不需要写表达式的)
适用于:切换频率比较低的场景,因为它是暴力删除**,不符合条件的节点直接从页面上移除**。
注意:v-if、v-else-if、v-else可以一起使用,但是要求结构不能被打断,必须连贯使用
v-show
v-show="表达式"
小案例:
你好
等于1等于2都不是
列表渲染指令
v-for="(value,index) in xxx" :key="index"
,其中:key用于指定改遍历的节点是唯一的关于
:key
的说明1.虚拟DOM中key的作用:
key是虚拟DOM对象的标识,当数据发生变化时,Vue会根据【新数据】生成【新的虚拟DOM】 ,随后Vue进行【新虚拟DOM】与【旧虚拟DOM】的差异比较,比较规则如下:
2.对比规则:
(1).旧虚拟DOM中找到了与新虚拟DOM相同的key:
a.若虚拟DOM中内容没变,直接使用之前的真实DOM
b.若虚拟DOM中内容变了,则生成新的真实DOM,随后替换掉页面中之前的真实DOM(2).旧虚拟DOM中未找到与新虚拟DOM相同的key
创建新的真实DOM,随后渲染到到页面
使用遍历对象的索引作为key时:
使用唯一标识id作为key时:
3.使用index作为key可能会引发的问题
(1)若对数据进行:逆序添加、逆序删除等破坏顺序(原来索引对应的值)操作:
会产生没有必要的真实DOM更新==>界面效果没问题,但效率低
(2)如果结构中还包含输入类的DOM:
会产生错误DOM更新==>界面有问题如果没有特别指定key,vue会默认使用对象索引 index 作为key来唯一标识
4.开发中如何选择key? :
(1)最好使用每条数据的唯一标识作为key,比如id、手机号、身份证号、学号等唯一值。
(2)如果不存在对数据的逆序添加、逆序删除等破坏顺序操作,仅用于渲染列表展示,使用index作为key是没有问题的
小案例:
用户信息:
- {{ item.name }} - {{ item.age }}岁
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收集表单中的数据
若是普通:,则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:失去焦点再收集数据,常用于文本域textarea中
number:输入字符串转为有效的数字,常用于输入纯数字的文本框中
trim:输入首尾空格过滤
小案例:
Vue中的过滤器
定义:对要显示的数据进行特定格式化后再显示(适用于一些简单逻辑的处理),如对日期的显示格式会进行处理
语法:
1.注册过滤器:
全局注册:再创建Vue实例之前注册 Vue.filter(name,callback回调函数)
局部注册:再创建Vue实例之中注册 new Vue{filters:{}}
2.使用过滤
在插值语法中:{{ xxx|过滤器名 }}
绑定的自定义属性中: v-bind:属性 = “xxx|过滤器名"
注意:
1.过滤器也可以接收额外参数、多个过滤器也可以串联
2.并没有改变原本的数据,是产生新的对应的数据,只不过是以不同的格式显示
注意:
与差值语法的区别:
v-text
会替换掉当前节点中的所有内容,{{xxx}}
只会替换括号内
注意:
1.与差值语法的区别
(1)
v-html
会替换掉节点中所有的内容,{{xx}}
则不会。(2)
v-html
可以识别html结构。2.有安全性问题
(1)在网站上动态渲染任意HTML是非常危险的,容易导致XSS攻击
(2)一定要在可信的内容上使用v-html,永不要用在用户提交的内容上
v-cloak
可以解决网速慢时页面延迟解析模板内容(页面闪现)的问题。小案例:
这是初始值,{{ num }}
这是改变后的值,{{ num }}
v-pre会跳过编译
new Vue({ directives:{ 指令名,配置对象 } })
new Vue({ directives:{ 指令名,回调函数 } })
Vue.directive(指令名,配置对象)
Vue.directive(指令名,回调函数)
bind
:指令与元素成功绑定时调用。inserted
:指令所在元素被插入页面时调用。update
:指令所在模板结构被重新解析时调用。注意:
1.指令定义时不加
v-
,但使用时要加v-
2.指令名如果是多个单词,要使用kebab-case命名方式,不要用camelCase命名。
什么是Vue的生命周期
常见的生命周期钩子
beforeCreate、created、beforeMount、mounted、beforeUpdate、updated、beforeDestroy、destroyed
mounted
:发送ajax请求、启动定时器、绑定自定义事件、订阅消息等初始化操作。beforeDestroy
:清除定时器、解绑自定义事件、取消订阅消息等收尾工作。关于销毁Vue实例
1.销毁后借助Vue开发者工具看不到任何信息。
2.销毁后自定义事件会失效,但原生DOM事件依然有效。
3.一般不会在beforeDestroy操作数据,因为即便操作数据,也不会再触发更新流程了
生命周期图示
{{ n }}
传统方式编程,存在的问题:
1.依赖关系混乱,不好维护、
2.代码复用率不高,总的来说属于低内聚高耦合
所以,我们引出组件的概念
组件:实现应用中局部功能代码(html、csss、js)和资源(字体、视频、音乐等)的集合,分为非单文件组件和单文件组件
可以记住一句话:组件就是一块砖,哪里需要哪里搬
Vue使用组件的三大步骤
一、定义组件(创建组件)
如何定义一个组件
1、el不要写,为什么?—最终所有的组件都要经过一个vm的管理,由vm中的el决定服务哪个容器。
2、data必须写成函数,为什么?——避免组件被复用时,数据存在引用关系,而对象中的数据是共用的
备注:使用template可以配置组件结构。
创建组件和注册组件时,关于组件名:
一个单词组成:
第一种写法(首字母小写):school
第二种写法(首字母大写):School
多个单词组成:
第一种写法(kebab-case命名):my-school
第二种写法(CamelCase命名):MySchool(需要Vue脚手架支持)
备注:
(1).组件名尽可能回避HTML中已有的元素名称,例如:h2、H2都不行。
(2).可以使用name配置项指定组件在开发者工具中呈现的名字。
二、注册组件
在Vue实例中注册组件,在Vue实例中添加一个全新的配置项component
- 局部注册:靠new Vue的时候传入components选项
- 全局注册:靠Vue.component('组件名’,组件)
三、使用组件(在模板中编写组件标签)
双标签写法
单标签写法(在脚手架环境中使用)
一个文件中包含n个组件
使用非单文件组件形式使用组件
每当我们创建一个组件的时候,Vue.extend
都会帮我们创建一个不同的VueComponent组件实例。
关于VueComponent:
school组件本质是一个名为VueComponent的构造函数,且不是程序员定义的,是Vue.extend生成的。
我们只需要写
或
,Vue解析时会帮我们创建school组件的实例对象,即Vue帮我们执行的:new VueComponent(options)。
特别注意:每次调用Vue.extend,返回的都是一个全新的VueComponent
关于this指向:
组件的配置对象中:
data函数、methods中的函数、watch中的函数、computed中的函数它们的this均是VueComponent实例对象。
Vue实例的配置对象中:
data函数、methods中的函数、watch中的函数、computed中的函数它们的this均是Vue实例对象。
一个重要的内置关系:
//组件实例对象的隐式原型是等于Vue的原型
VueComponent.prototype._proto_ === Vue.prototype
为什么要有这个关系?
让组件实例对象(VueComponent)可以访问到Vue原型上的属性和方法。
第一步,全局安装@vue/cli
# 通过npm
npm install -g @vue/cli
# OR 通过yarn 这个自行搜索
yarn global add @vue/cli
如果安装下载缓慢,可以替换为npm淘宝镜像
npm config set registy http://registy.npm.taobao.org
第二步,创建一个文件夹,并且听过cd
进入到当前文件夹下,运行命令创建项目
vue create xxx(项目名)
第四步,当项目创建后,cd
到该项目包名下运行命令
npm run serve
第五步,浏览器访问http://localhost:8080/
出现如下页面 ,表示创建成功。
main.js 文件分析
/*
main.js 是整个Vue项目的入口文件
*/
//引入Vue
import Vue from 'vue'
//引入App组件,App组件所有组件的父组件
import App from './App.vue'
//这条语句用于关闭Vue默认的生产提示
Vue.config.productionTip = false
//创建Vue实例对象--vm
new Vue({
//将App组件放入到容器中
render: h => h(App),
}).$mount('#app')
index.html 文件分析
DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title>
<%= htmlWebpackPlugin.options.title %>
title>
head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled.
Please enable it to continue.strong>
noscript>
<div id="app">div>
body>
html>
关于不同版本的Vue:
1.vue.js 与vue.runtime.xxx.js的区别:
(1).vue.js是完整版的Vue,包含:核心功能+模板解析器。
(2). vue.runtime.xxx.js是运行版的Vue,只包含:核心功能**;没有模板解析器**。
2.因为vue.runtime.xxx.js没有模板解析器,所以不能使用template配置项,需要使用render函数接收到的createElement函数去指定具体内容。
//render函数,里面接收一个创建元素的回调函数createElement
render(createElement){
return createElement(页面元素或模板,也就是组件)
}
vue.config.js
是一个可选的配置文件,如果项目的 (和 package.json
同级的) 根目录中存在这个文件,那么它会被 @vue/cli-service
自动加载。你也可以使用 package.json
中的 vue
字段,但是注意这种写法需要你严格遵照 JSON 的格式来写。module.exports = {
pages: {
index: {
//配置入口文件
entry: 'src/main.js',
}
},
lintOnSave: false //关闭语法检查
}
被用来给元素或者子组件注册引用信息(作用于id类似)
应用在html结构元素标签上的时候获取的是真实DOM元素,应用在组件标签上是组件的实例对象(VueComponent)
使用方式:
打标识:
或
.....
获取:
this.$refs.xxx
小案例:
标签使用ref
可以看到,一个是真实DOM元素,一个是组件实例对象
功能:让组件接受外部传过来的数据
接收数据:
传递数据:
接收数据
第一种方式(只接受):
props:['name','robot']
第二种方式(限制类型):
props:{
name:String,
sex:String
}
第三种方式(限制类型、是否必须、默认值)
props:{
name:{
type:String, //类型
required:true // 是否必要
},
sex:{
type:String,
defult:'女' //默认值
}
}
注意:
props是只读的,Vue底层会监测你对props的修改,如果进行了修改,就会发出警告(报错),若业务需求确实需要修改,那么请复制props的内容到data中一份,然后去修改data中的数据。
小案例:
App.vue传过来的值
Ikaros.vue中接收值
name:{{ name }}
sex:{{ sex }}
myName:{{ myName }}
最终显示:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nsJ9dssl-1688828922359)(assets/image-20230705202814974.png)]
功能:可以把多个组件共用的配置提取成一个混入对象使用方式:
第一步定义混合,新建一个mixin.js
文件:
{
data(){....},
methods:{....}...
}
第二步使用混入:全局混入,局部混入
功能:用于增强Vue
本质:包含install方法的一个对象,install的第一个参数是Vue,第二个以后的参数是插件使用者传递的数据。
定义插件:
对象.install = function (Vue,options){
//1.添加全局过滤器
Vue.filter(....)
// 2.添加全局指令
Vue.directive(....)
//3.配置全局混入(合)
Vue.mixin(....)
//4.添加实例方法
Vue.prototype.$myMethod = function () {...}
Vue.prototype.$myProperty = XXXX
使用插件:
导入: import plugin from ''./路径'
使用: Vue.use(插件名)
标签中添加一个关键字scoped
标记,表示作用域只在该组件内生效