Vue框架基础知识
一、初始Vue.js
1.是一套用于构建用户界面的渐进式框架 -- 前端框架
2.自底向上逐层应用
3.数据驱动型框架
4.构建SPA应用 -- 单页应用程序
5.MVVM结构
6.作者:尤雨溪
7.上线时间:2014年2月
8.兼容性:IE8以上
9.版本:V2.x:2.6.14 -- 只维护不更新
V3.x:3.2.36 -- 维护更新
二、安装
1.下载后使用<script>引入:①下载后引入
②使用CDN
2.使用NPM
3.使用vue-cli:vue的脚手架工具
三、基本语法
1.使用<script>引入vue后,Vue就被注册成了全局变量
2.组件:一个预定义选项的vue实例(vue.js的实例就是组件)
3.vue应用:一个根实例和多个vue实例组成
vue.js应用都是由一个根组件和多个子组件组成
4.创建根实例
var vm = new Vue({// el:"#app", //挂载元素(vue的作用范围) }).$mount("#app")5.实例选项:
el:挂载元素(vue的作用范围) 注意:1.只能用在根实例2.不能挂载到html或body上 data:实例的数据对象 -- 只有写在data当中的数据才能够在HTML中直接访问 注意:根实例上为对象;子实例中是一个函数,返回数据对象 methods:实例的方法(自定义) -- 对象格式,对象的属性名就是方法名,属性值就是方法体 4.生命周期钩子:本质是一个函数,由组件在实例化过程中自动调用 beforeCreate(),created(),beforeMount(),mounted(), beforeUpdate(),updated(),beforeDestroy(),destroyed()6.实例方法或属性:属性和方法前有$
vm.$el:获取根实例绑定的el属性 vm.$mount():手动绑定el属性$data:获取实例的数据对象模板语法
1.作用:将DOM和vue中数据双向绑定
2.插值:①{{msg}}:将msg作为字符串插入,标签之间
②v-text:将数据作为字符串输出
③v-html:将数据作为HTML内容插入 -- xss攻击
④v-bind:将数据作为属性值插入
1.作为属性值绑定:val就是data中的变量 <div v-bind:attr="val"></div> 2.作为属性名绑定:attr和val都是data中的变量 <div v-bind:[attr]="val"></div> 3.简写 <div :attr="val"></div> 4.绑定多个属性值:ids,attr,title都是data中的变量 <div v-bind="{id:ids,[attr]:'myclass',title"</div> 5.使用修饰符 <div :attr.prop="val"></div>指令
1.是带有v-开头的特殊标签属性 -- 值变,DOM变
2.v-once:只渲染元素和组件一次 -- 没有参数
3.v-pre:跳过当前元素及子元素的编译 -- 没有参数
4.v-model:用来在表单控件或组件上创建双向绑定
1.绑定text的value属性,input事件 <input type="text" v-model="msg"> 2.修饰符: .lazy:将input事件更改为change事件 .number:将获取的input的值转换为number类型(value获取默认为string) .trim:过滤输入内容的前后空格 <input type="text" v-model.lazy.trim="msg">5.v-cloak:隐藏{{}}直到模板编译完成
1.css中设置v-cloak样式 [v-cloak]{display:none} 2.在{{}}标签上使用v-cloak指令 <div v-cloak>{{msg}}</div>6.v-on:绑定事件监听器
7.v-slot:提供具名插槽或需要接受prop的插槽
条件渲染
1.v-show:通过表达式的值真假,来切换元素的display属性
2.v-if:通过表达式的值真假,来渲染/不渲染内容
3.v-else-if:v-if的else-if块
4.v-else:`v-if块
区别:v-show是用过display属性实现;v-if是渲染或不渲染元素
列表渲染
1.v-for:基于一个数组渲染一个列表,参数可以是数组,对象,赋值,字符串,具有遍历器属性的值
<ul><li v-for="(val,key,index) in/of list" :key="val.id"></li> </ul>2.注意:①当为数值,遍历的是数值对应的次数
②对象和数组更新检测(pop,sort,shift,unshift,reverse,splite)
过滤器
1.作用:实现文本格式化
2.创建:①Vue.filter():创建全局过滤器 -- 所有组件可用,必须在组件实例化之前注册
Vue.filter("过滤器名",(val[,arg])=>{ //val是待过滤的值,arg是其他参数return v; //过滤之后的值 })Vue.filter("cap",val=>{ //val就是要过滤的值//判断val是否是字符串return val.charAt(0).toUpperCase()+val.slice(1); //return的返回值就是过滤之后的值}); //注册全局过滤器 -- 先注册再使用/* Vue.filter("cap",val=>{ //val就是要过滤的值//判断val是否是字符串return val.charAt(0).toUpperCase()+val.slice(1); //return的返回值就是过滤之后的值}); */②filters:实例选项,创建局部过滤器 -- 当前实例可用
filters:{过滤器名:function(val[,arg...]){return v} }filters:{cap(val,type){ //val:待过滤的值 type:就是参数if(type % 2)return val.toUpperCase();elsereturn val.toLowerCase();}}3.调用
1.{{val | 过滤器名}} 2.{{val| 过滤器1 | 过滤器2...}} 3.{{val | 过滤器名(arg)}} -- arg作为过滤器的第二个参数,依次类推 4.<div v-bind:title="val" | 过滤器>事件绑定
1.事件绑定:v-on
2.语法格式
<!-- 绑定事件 --><!-- <input type="button" value="计数器" v-on:click="counts"> --><!-- 绑定事件简写 --><input type="button" value="计数器" @click="counts"><!-- 绑定事件简写 (简写+动态) --><input type="button" value="计数器" @[c]="counts"><!-- 绑定事件传参 --><input type="button" value="计数器" @click="counts2(123,$event)"><!-- 绑定事件(使用修饰符:阻止默认行为+事件处理函数) --><a href="filter.html" @click.prevent="counts">过滤器</a><!-- 绑定事件(使用修饰符:阻止默认行为+省略了事件处理函数) --><a href="filter.html" @click.prevent>过滤器</a><!-- 错误:不能直接在事件绑定中写js代码 --><!-- <input type="button" value="点击" @click="alert(666)"> --><!-- 绑定事件(键盘事件+按键码作为修饰符-event.key) --><input type="text"@keydown.w="counts">3.注意:①事件如果没有传参,默认参数为event对象
②多个修饰符可直接使用.连接
③按键码作为修饰符时,需要转换为kebab-case
样式处理
1.样式绑定:v-bind
2.class绑定:①对象格式
<div :class="{active:true,active2:isActive,[className]:isTrue}"></div> active,active2是固定class名,className是动态class名 规则:对象的属性值为真时应用class <!-- 绑定样式(对象格式) --> <li v-for="name of names" :class="{'color-red':true}">{{name}}</li> <!-- 绑定样式(对象格式+) --> <h1 :class="{[colors]:isGreen}">Hello</h1>②数组格式
<div :class="['active',class2,{class3:isTrue},true ? class4 : class5]"></div> 规则:将数组中的样式全部应用到元素上3.style绑定:①对象格式
<div :style="{color:'red','font-size':'12px',fontWeight:'blod',[sname]:sval,background}"></div> 规则:对象的属性名就是css属性名对象属性对应的值就是css属性值②数组格式
<div :style="[{color:'red'},]"></div>组件基础
1.定义:可复用的vue实例,并且都有一个名字
2.组件注册:①全局注册:应用在注册之后所有新创建的根实例及子组件中
Vue.component("component-name",{//options -- 选项对象})②局部注册:应用在当前组件中
components:{"component-name":{//options} } 注意:组件名命名最后按kabab-case方式命名,也可以使用大驼峰命名,但是DOM当中只能用kabab-case方式调用3.组件选项:①template:实例的模板
{//template:"<h1></h1>", //直接使用html字符串作为模板template:"#tem", //匹配页面中template id为tem中的innerHTML作为模板data:function(){return {}},components:{"component-name":{}} }注意:template只能有一个根元素②data:必须是一个函数,返回一个数据对象
③components:用来注册子组件
④props:用来接受父传递的属性值
组件传值
1.父传子:props传值
1.父 <child-component msg="hello" :msg2="val"></child-component> 2.子 props:["msg","msg2"] props:{msg:String,msg2:{type:Number, //限制类型default:1, //当父没有传递这个值时显示默认值required:true, //是否必填//验证这个值validator:fuction(v){return true/false} } } 注意:①父传子默认值为string,如果需要传递的值的静态类型,则需要使用v-bind传递②单项数据流:子组件不能更改父传递的值2.子传父:父能够监听子组件的自定义事件
//1.触发自定义事件 vm.$emit("event-name",[,arge...]); //arg就是参数 //2.监听自定义事件 <component v-on:event-name="doThis"></componenet> -- 组件可以直接监听 vm.$on("event-name",function([val...]){//val就是自定义事件中传递的arg参数 }) vm.$once():只监听一次自定义事件 vm.$off():移除监听器函数3.兄弟传值:子传父,父传子
插槽
1.是一套内容分发的API:将父写在子组件之间的内容分发到子的模板中
2.用法:
1.父级模板 <div id="app"><child-component><!--msg是父实例的数据,是默认插槽的分发内容-->{{msg}}<!--下面指向slot为slot1的分发内容--><tempalte v-slot:slot1>Hello</tempalte><!--获取作用域插槽传递的数据并作为分发内容+v-slot简写+解构插槽prop--><tempalte #slot2="{user}">{{user}}</tempalte></child-component> </div> 2.子模板 <template id="child"><div><!--默认插槽:有默认值为Hi~,当没有传递分发内容时显示--><slot>Hi~</slot><!--具名插槽:指向template的v-slot属性--><slot name="slot1"></slot><!--作用域插槽:将自身的user作为插槽的prop传递给父--><slot name="slot2" :user="user"></slot></div> </template> 注意:msg是父实例中的数据!二、路由
1.vue-router:官方路由,用于实现单页应用
2.安装:1.通过<script>标签引入
2.通过包管理器安装
3.注意:vue.js 2.×对应的路由为v3.×
4.路由实现步骤:1.导入路由 -- 先导入vue再导入vue-router
2.挂载路由到根实例
new Vue({//挂载到根实例的router选项上router:new VueRouter({//路由的映射关系routes:[{path:"/",component:{},redirect:"/page1"}]} //router的构建选项linkActiveClass:"active" //全局设置选中链接的默认class) })3.通过<router-link>实现路由导航
<router-link to="/path">导航1</router-link> 注意:router-link会被渲染成一个超链接超链接默认选中样式为"router-link-active"4.设置渲染出口 -- 渲染的组件最终显示的位置
<router-view></router-view>一、环境搭建
1.cli工具:vue.js的脚手架工具
2.版本:vue-cli:老版本,主要基于vue.js v2.×+webpack构建应用
@vue/cli:新版本,主要基于vue.js v3.×+vite构建应用
3.用户端:vue-cli+vant
4.安装vue-cli:$ npm i vue-cli -g
5.问题:1.安装完成后不能识别为一个命令
原因:没有将vue-cli添加到环境变量 1.找到全局安装包路径:vue.cmd所在目录 2.添加为环境变量 3.重启终端或重启电脑2.安装完成后不能执行vue命令:powershell异常,cmd正常
原因:powershell执行策略 1.查看当前的执行策略:get-executionPolicyRestricted:不允许执行脚本 2.重新设置执行策略:set-executionPolicy 选择 'Y'RemoteSigned:允许执行脚本二、项目初始化
1.创建一个大项目目录:tiktok
2.进入目录,执行命令:$ vue init webpack web
... Vue build:通过方向键选择 -- 选择构建版本 1.完整版:运行时(Runtime)+编译器(Complier) 2.编译器:编译模板3.开启项目:1.进入项目目录:$ cd web
2.执行命令:$ npm run dev或npm start
4.开启成功之后根据提示打开对应的URL
5.目录结构:
build:webpack配置目录--打包相关 config:项目配置目录 node_modules:包目录 src:源文件目录--assets:静态资源目录--base64压缩--components:组件目录--router:路由目录--index.js:路由--App.vue:根组件--main.js:根组件实例化文件 static:静态资源目录--直接加载 .babelrc:babel配置文件 .postcssrc.js:转换css的配置文件 -- 加特定厂商前缀 index.html:主页 package.json package-lock.json6..vue文件:单文件组件,共包含三部分
<template></template>:组件模板 <script> export default {//组件选项 } </script>:JS代码 <style></style>:CSS代码 scoped:style添加这个属性即表示样式只能作用于当前组件三、搭建项目框架
vant框架
1.vant框架:是一个移动端组件库,于2017年开源 -- 移动端UI框架
2.版本:vant2:vue.js v2.×
vant3:vue.js v3.×
3.安装:
$npm i vant -s:vue3版本安装最新的vant $npm i vant@latest-v2 -S:vue2版本安装vant24.引入组件:自动按需引入组件
1.安装babel-plugin-import插件:是一款 babel 插件,它会在编译过程中将 import 的写法自动转换为按需引入的方式 $npm i babel-plugin-import -D 2..babelrc配置文件中添加配置 {"plugins": [["import", {"libraryName": "vant","libraryDirectory": "es","style": true}]] } 3.在main.js中导入vant组件并安装 import {Tabbar} from "vant" Vue.use(Tabbar);编程式导航
1.通过router实例方法实现导航(跳转页面)
2.路由实例:指向router/index.js中创建的实例,有对应的方法和属性,在vue实例中通过this.$router访问
3.路由对象:指向当前激活的路由状态信息,是一个对象,可以获取相关属性,在vue实例中通过this.$route访问
4.router实例方法:
router.push():给history添加新记录--跳转到新页面 router.replace():作用同push(),但是不会给history添加新记录,而是替换当前的history router.go(2):前进/后退n步嵌套路由
1.给路由添加children选项,用来配置子路由
{path:"/main",component:Main,children:[{path:"msg", //子路由,不需要加/,加/表示根路由component:Msg}] }2.在父路由组件中,依旧通过<router-view></router-view>作为渲染出口
Sass
1.安装依赖包:npm i node-sass -D
npm i sass-loader -D
2.引入sass:在vue文件的<style>中添加:lang="scss"
3.问题解决:
1.安装依赖报错:排除以下问题 1.1.使用的国外镜像,下载慢导致错误--使用cnpm或者将源设置为淘宝地址 1.2.更改用户目录下的.npmrc文件 -- npm get globalconfig查看npmrc文件位置 phantomjs_cdnurl=http://cnpmjs.org/downloads sass_binary_site=https://npm.taobao.org/mirrors/node-sass/ registry=https://registry.npm.taobao.org 2.页面中使用 <style lang="scss"> 如果编译不成功,排除是否是版本问题: 建议sass-loader安装7.3.1的版本 npm install sass-loader@7.3.1 -D npm install node-sass@4.14.1 -D 注意:上面sass版本需要配合node14版本 如果node版本过高,会报如下错误:Node Sass does not yet support your current environment: Windows 64-bit with Unsupported runtime (93) 3.如果电脑没有安装python,则需要下载安装python -V:查看是否有安装python登录组件
1.样式无法作用到组件上:给选择器添加>>>
.parent>>>.child{}2.调用接口,验证用户是否已经注册
Axios使用
1.安装Axios:npm i axios -S
2.绑定Axios到Vue:
main.js import Axios from "axios" Vue.prototype.$http = Axios设置代理,访问远程资源
1.配置config/index.js
proxyTable: {"/apis":{target:"http://localhost", //目标资源地址changeOrigin:true, //是否跨域pathRewrite:{"^/apis":"" //是否重写接口}}}2.接口调用更改:
this.$http.get("http://localhost/users/isregister?tel="+this.tel) 改为: this.$http.get("/apis/users/isregister?tel="+this.tel)assets图片调用
1.静态调用:可以直接调用,并且可以使用@
<img src="@/assets/logo.png" width="50%">2.动态绑定:不能使用@,也不能使用相对路径
3.动态绑定解决方案:1.将图片保存到static目录再加载
js: data{src:"../../static/logo.png"} html: <img :src="src" width="50%">2.使用require加载:可以使用@
js: data{src:require("@/assets/logo.png")} html: <img :src="src" width="50%">3.使用import加载:可以使用@
js: import logo from "@/assets/logo.png"data{src:logo} html: <img :src="src" width="50%">验证用户是否登录
导航守卫
1.监听路由访问,通过判断决定是否正常访问路由或取消
2.分类:①全局守卫
②路由独享守卫:针对单个路由
③组件内的守卫:只针对单个组件
3.格式:
//组件内的守卫 beforeRouteEnter(to, from, next) { //to:接下来访问的路由对象;from:从哪个路由对象过来;next:一个方法,表示下一步该如何执行,一定要调用 // 在渲染该组件的对应路由被 confirm 前调用// 不!能!获取组件实例 `this`// 因为当守卫执行前,组件实例还没被创建}beforeRouteEnter (to, from, next) {// ...to:接下来访问的路由对象//from:从那个路由对象来}4.使用next跳转报错:
解决方案:更改vue-router原型方法
router/index.js 在Vue.use(Router)之前添加如下代码: const originalPush = Router.prototype.push Router.prototype.push = function push(location, onResolve, onReject) { if (onResolve || onReject) return originalPush.call(this, location, onResolve, onReject) return originalPush.call(this, location).catch(err => err) }组件切换动画
1.<transition>组件:给任何元素和组件添加进入/离开过渡
2.使用动画:1.基于CSS类名绑定
1.给<transition>组件一个name属性,作为六个内置class的前缀 2.根据需求定义CSS:v-enter,v-enter-to,v-enter-activev-leave,v-leave-to,v-leave-active2.基于JavaScript钩子绑定
v-on:before-enter="beforeEnter"v-on:enter="enter"v-on:after-enter="afterEnter"v-on:enter-cancelled="enterCancelled"v-on:before-leave="beforeLeave"v-on:leave="leave"v-on:after-leave="afterLeave"v-on:leave-cancelled="leaveCancelled"上传组件
1.组件设置:
<van-field label="选择视频"><template #input><van-uploader v-model="video" accept="video/*" maxCount="1" :after-read="afterRead" /></template> </van-field>2.文件上传:after-read是文件读取后会执行的函数,读取的文件file为默认的形参
afterRead(file){console.log(file);console.log(this.video);file.status = "uploading";file.message = "上传中...";//将file格式化var formData = new FormData(); //表示表单键值对结构的表示方式,数据编码格式为multipart/form-dataformData.append("video",file.file);//调用接口上传文件this.$http.post("/apis/uploads",formData).then(data=>{file.status = "success";file.message = "上传成功~";console.log(data);})}3.如果需要after-read需要传递其他参数,那么file就需要作为一个函数返回
<van-field label="选择视频"><template #input><van-uploader v-model="video" accept="video/*" maxCount="1" :after-read="afterRead('video')" /></template> </van-field>js中: afterRead(param){return file=>{console.log(param); //videoconsole.log(file); //读取的文件对象} }接口
用户模块
一、验证用户是否已注册
1.地址:http://localhost/users/isregister
2.请求方式:GET
3请求参数
| 1 | tel | string | 手机号,必填 |
4.返回参数:JSON格式
{errCode:0, //错误代码errMsg:"", //错误信息 }二、用户注册/登录
1.地址:http://192.168.4.169/users/register -- 注册
http://192.168.4.169/users/login -- 登录
2.请求方式:POST
3.请求参数:
| 1 | tel | string | 手机号 |
| 2 | pwd | string | 密码 |
4.返回的参数:JSon格式
{errCode:0,errMsg:"注册成功",result: }三、文件上传
1.地址:http://localhost/uploads -- 视频上传
2.请求方式POST
3.参数:
| 1 | video | file | 需要上传的视频 |
总结
- 上一篇: PCM音频数据、DSD音频数据,spdi
- 下一篇: 2022年前端Vue常见面试题大全(三万