Vue.js学习
1、概念和特点
- 概念:Vue (读音 /vju?/,类似于 view) 是一套用于构建用户界面的渐进式JavaScript框架。 与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。发布时间为2014年2月。
- 特点
- 更加轻量20kb min + gzip
- 渐进式框架
- 响应式的更新机制
- 学习成本低
2、MVVM模式的实现者
-
Model:模型层,在这里表示avaScript对象
-
View:视图层,在这里表示DOM(HTML操作的元素)
-
ViewModel:连接视图和数据的中间件,Vue.js就是MVVM中ViewModel的实现者
在MVVM架构中,是不允许数据和视图直接通信的,只能通过ViewModel来通信,而ViewModel就是定义了一个Observer观察者 -
ViewModel能够视察到数据的变化,并对视图对应的内容进行更新
-
ViewModel能够监听到视图的变化,并能够通知数据发生改变
3、Vue基本语法
带有前缀v-的被称为指令,以表示它们是Vue提供的体术属性,它们会在渲染的DOM上应用特殊的响应式行为,该指令的意思是“将这个元素节点的title特性和Vue实例的message属性保持一致”
如果再次打开浏览器的JavaScript控制台,输入app.message="新消息",就会再一次看到这个绑定了title特性的HTML已经进行了更新。
- v-bind
Title
{{message}}
消息
- v-if和v-else
Title
成功
失败
- v-for
Title
{{arr.message}}
4、Vue绑定事件(v-on)
绑定事件
5、Vue双向绑定(v-model)
双向绑定
请输入内容:
输入的内容为:{{message}}
性别:男
女
选择的性别为:{{checked}}
兴趣爱好:
选择的兴趣爱好为:{{selected}}
注意:v-model会忽略所有表单元素的value、checked、selected特性的初始值,而总是将Vue实例的数据作为数据来源。你应该通过JavaScript在组件的data选项中声明初始值
6、Vue组件
组件
说明:
- Vue.component():注册组件
- my-component:自定义组件的名字
- template:组件的模板
- 使用props属性传递参数
向上面那样用组件没有任何意义,所以我们是需要传递参数到组件的,此时就需要使用props属性了。
组件
组件
7、Axios异步通信
Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中,是基于ajax的异步通信。
特性:
- 从浏览器中创建 XMLHttpRequests
- 从 node.js 创建 http 请求
- 支持 Promise API
- 拦截请求和响应
- 转换请求数据和响应数据
- 取消请求
- 自动转换 JSON 数据
- 客户端支持防御 XSRF
组件
8、计算属性
- 计算出来的结果,保存在属性中
组件
currentTime1:{{currentTime1()}}
currentTime2:{{currentTime2}}
说明:
- methods:定义方法,调用方法使用currentTime1(),需要带括号
- computed:定义计算属性,调用属性使用currentTime2,不需要带括号;this.message是为了能够让currentTime2观察到数据变化而变化
- 如果在方法中的值发生了变化,则缓存就会刷新。可以在控制台使用vm.message="zixin",改变下数据的值,再次测试观察效果
结论:
调用方法时,每次都需要进行计算,既然有计算过程则必定产生系统开销,那如果这个结果是不经常变化的,此时就可以考虑将这个结果缓存起来,采用计算属性可以很方便的做到这一点,计算属性的主要特性就是为了将不经常变化的计算结果进行缓存,以节约我们的系统开销。
9、插槽slot
在Vue.js中我们使用元素作为分发内容的出口,称为插槽,可以用用在组合组件的场景中。
slot插槽
10、自定义事件内容分发
事件分发
通过上面的代码不难发现,数据项在Vue的实例中,但删除操作要在组件中完成,那么组件如何才能删除Vue实例中的数据呢?此时就涉及到参数传递与事件分发了,Vue为我们提供了自定义事件的功能 ,很好地帮助了我们解决了这个问题:使用this.$emit('自定义事件名',参数),操作过程如下:
- 在Vue的实例中,增加了methods对象并定义了一个名为removeItem的方法
removeItem:function (index) {
console.log("要删除的为"+this.items[index]);
this.items.splice(index, 1);
}
- 修改son-item代办内容组件的代码,增加一个删除按钮,并绑定事件
template: "{{item}} ",
- 修改son-item代办内容组件的HTML代码,增加一个自定义事件,比如叫butClick,可以和组件的方法绑定,然后绑定到Vue的方法中
methods:{
butClick:function (index) {
this.$emit('remove', index);
}
}
全部代码:
事件分发
11、第一个vue-cli程序
准备工作
-
下载和安装Node.js
官网下载后打开文件,然后无脑下一步,即可安装完成。 -
检查Node.js是否安装成功
在控制台输入node -v与npm -v,若输出版本号表示安装成功 -
安装Node.js淘宝镜像加速器(cnpm)
Node.js有时候下载会很慢,下载淘宝加速器,下载会快很多
# -g 全局安装,在全局环境下都能使用
npm install cnpm -g
# 或每次需要用到淘宝加速器的时候手动添加如下语句解决npm速度慢的问题
npm install --registry=https://registry.npm.taobao.org
建议npm下载失败再用cnpm下载,因为cnpm下载的文件有时候会出问题
- 安装vue-cli
cnpm install vue-cli -g
#测试是否安装成功
#查看可以基于那些模块创建vue应用程序,通常我们选择webpack
vue list
创建项目步骤
-
创建一个Vue项目,我们随便建立一个空的文件夹在电脑上,我这里在F盘下新建一个目录
F:\ideaworkplace\vuestudy -
创建一个基于webpack模板的vue应用程序
#这里的myvue时项目名称,可以根据自己的需求起名
vue init webpack myvue
一路都选择no即可
说明:
- Project name:项目名称,默认回车即可
- Project description:项目描述,默认回车即可
- Author:作者
- Vue build:vue构建方式
- Install vue-router:是否安装路由
- Use ESLint to lint your code:使用ESLint对代码进行规范
- Set up unit tests:是否设置单元测试
- Setup e2e tests with Nightwatch:是否使用Nightwatch设置e2e
- Should we run
npm installfor you after the project has been created? (recommended):是否在工程创建后就去跑 npm 安装依赖
创建好的项目目录
- 初始化项目并运行
cd myvue
npm install
npm run dev
-
先执行前面两个命令,下载依赖
-
执行完成后,目录多了很多依赖
-
再执行
npm run dev运行项目
-
运行成功页面如下
12、webpack学习使用
- 安装
npm install webpack -g
npm install webpack-cli -g
- 测试是否安装成功
- webpack -v
- webpack-cli -v
- 配置
创建webpack.config.js配置文件
- entry:入口文件,指定WebPack用那个文件作为项目的入口
- output:输出,指定WebPack把处理完成的文件防止到指定路径
- module:模块,用于处理各种类型的文件
- plugins:插件,如:热更新、代码重用等
- resovle:设置路径指向
- watch:监听,用于设置文件改动后直接打包
modules.exports = {
entry:"",
output:{
path:"",
filename:""
},
modules:{
loaders:{
{test:/\.js$/,loader:""}
}
},
plugins:{},
resolve:{},
watch:true
}
- 使用webpack
- 创建一个项目(空文件夹,用idea打开)
- 创建一个名为modules的目录,用于放置JS模块等资源文件
- 在modules下创建模块文件,如hello.js,用于编写JS模块相关代码
//暴露一个方法
exports.sayHi = function(){
document.write("Hello WebPack!")
}
- 在modules下创建一个名为main.js的入口文件,用于打包时设置entry属性
//require导入一个模块,就可以调用这个模块中的方法了
var hello = require("./hello");
hello.sayHi();
- 在项目目录下创建webpack.config.js配置文件
module.exports = {
entry:"./modules/main.js",
output:{
filename:"./js/bundle.js"
}
};
-
直接运行webpack命令打包
-
项目中多个一个dist文件夹,里面存放刚刚打包的js文件
-
编写一个index.html页面,同时引入刚刚打包好的js文件
测试引入打包后的js文件
- 运行index.html文件,看效果
13、vue-router路由
- 概念
Vue Router是Vue.js官方的路由管理器。它和Vue.js的核心深度集成,让构建单页面应用变得易如反掌,包含的功能有:
- 嵌套的路由/视图表
- 模块化的、基于组件的路由配置
- 路由参数、查询、通配符
- 基于Vue.js过渡系统的视图过度效果
- 细粒度的导航控制
- 带有自动激活的CSS class的链接
- HTML5历史模式或hash模式,在IE9中自动降级
- 自定义的滚动行为
- 安装
基于第一个vue-cli进行测试学习,先查看node_modules中是否存在vue-router
vue-router是一个插件包,所以需要用npm/cnpm来进行安装的。打开命令行工具,进入项目目录,输入下面命令。
npm install vue-router --save
此时遇到安装失败如下
原因是npm版本过高,此时需要降低npm的版本,执行执行下面命令
#安装低版本的npm
npm install npm@6.14.10 -g
注意:如果在一个模块化工程中使用它,必须要通过Vue.use()明确地安装路由功能
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter);
- 测试
- 先删除没有用的东西
- components目录下存放我们自己编写的组件
- 定义一个Content.vue组件
内容页
- 定义一个Main.vue组件
首页
- 安装路由,在src目录下,新建一个文件夹:router,专门存放路由,在下面创建一个index.js文件
import Vue from 'vue'
import VueRouter from 'vue-router'
//导入组件
import Content from "../components/Content";
import Main from "../components/Main";
//安装路由
Vue.use(VueRouter);
//配置导出路由
export default new VueRouter({
routes:[
{
//路由路径
path:'/content',
name:'content',
//跳转的组件
component:Content
},
{
path: '/main',
name:'main',
component: Main
},
]
});
- 在main.js中配置路由
import Vue from 'vue'
import App from './App'
//自动扫描里面的路由配置
import router from './router'
Vue.use(router);
new Vue({
el: '#app',
//配置路由
router,
render:h=>h(App)
});
- 在App.vue中使用路由
路由首页
首页
内容页
- 测试,发现了下面的错误
问题原因:安装了最新的vue-router,版本大概是4.0.12,我最开始安装vuecli没有指定版本
解决方法:降低vue-router的版本,这里我换成了3.0.1
#卸载新版本的vue-router
npm uninstall vue-router
#安装指定版本的vue-router
npm i vue-router@3.0.1
- 重新运行,得到如下运行成功的页面
14、vue+elementUI
创建工程(命令行都要使用管理员模式运行)
-
创建一个名为hellovue的工程
vue init webpack hellovue -
安装依赖,我们需要安装vue-router、element-ui、sass-loader和node-sass四个插件
#进入工程目录
cd hellovue
#安装vue-router
npm install vue-router --save
#安装element-ui
npm i element-ui -S
#安装依赖
npm install
#安装sass加载器
cnpm install sass-loader node-sass --save-dev
#启动测试
npm run dev
- npm命令解释
npm install moduleName:安装模块到项目目录下npm installl -g moduleName:-g的意思是将模块安装到全局,具体安装到磁盘那个位置,要看npm config prefix的位置npm install -save moduleName:--save的意思是将模块安装到项目目录下,并在package文件的dependencies节点写入依赖,-S为该命令的缩写npm install --save-dev moduleName:--save-dev的意思是将模块安装到项目目录下,并在package文件的devDependencies节点写入依赖,-D为该命令的缩写
-
用idea打开项目,并删除多余的东西,重新使用
npm run dev运行项目,运行结果如下
-
测试
- Login.vue
欢迎登录
登录
请输入账号和密码
- Main.vue
用户管理
个人信息
用户列表
内容管理
分类管理
内容列表
个人信息
退出登录
- Profile.vue
个人信息
- UserList.vue
用户列表
- index.js
import Vue from 'vue'
import Router from 'vue-router'
//引入组件
import Main from "../components/Main";
import Login from "../components/Login";
import Profile from "../components/user/Profile";
import UserList from "../components/user/UserList";
//安装路由
Vue.use(Router);
let router = new Router({
routes:[
{
path:'/main',
name:'Main',
component:Main,
children:[
{
path:'/user/profile',
name:'Profile',
component:Profile,
},
{
path:'/user/list',
name:'UserList',
component:UserList,
}
]
},
{
path: '/login',
name:'Login',
component: Login
}
]
});
export default router
- main.js
import Vue from 'vue'
// import {createApp} from 'vue'
import App from './App'
//引入element-ui
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
//引入路由
import router from './router';
//
Vue.use(ElementUI);
Vue.use(router);
new Vue({
el: '#app',
router,
render: h => h(App)
});
- App.vue
运行时遇到问题
原因:因为node-loader版本过高导致的问题,我们尝试将版本降低到@4.14.1
解决方法:直接使用命令:npm install sass-loader@4.14.1 --save-dev 降低版本号,再进行npm run dev即可运行
15、路由嵌套
- 如上面的Main.vue页面中代码,点击这些链接,右边显示对应的页面
- 在router目录下的index.js中的routes数组,在component为Main中添加如下代码
children:[
{
path:'/user/profile',
name:'Profile',
component:Profile,
},
{
path:'/user/list',
name:'UserList',
component:UserList,
}
]
注意:必须要引入对应的组件
16、参数传递及重定向
- 参数传递
方式一
- 将Main.vue中的个人信息链接改成下面代码:
个人信息
- index.js中Profile组件的代码修改为如下:
{
path:'/user/profile/:id',
name:'Profile',
component:Profile,
},
注意:参数名必须与传过来的一致
- 重新运行,运行结果与预期一致
方式二
- 在Login.vue中的onSubmit方法跳转到main页面时添加参数:
onSubmit(formName) {
//为表单绑定验证功能
this.$refs[formName].validate((valid) => {
if (valid) {
//使用vue-router路由到指定页面,该方式称之为编程式导航
this.$router.push("/main/"+this.form.username);
} else {
this.dialogVisible = true;
return false;
}
});
},
- 在路由主文件中的Main路由对象中,开启props,同时在path的后面添加/:name
{
path:'/main/:name',
name:'Main',
component:Main,
props:true,
children:[
{
path:'/user/profile/:id',
name:'Profile',
component:Profile,
},
{
path:'/user/list',
name:'UserList',
component:UserList,
},
{
path:'/goTop',
redirect:'/main'
}
]
},
{
path: '/login',
name:'Login',
component: Login
},
{
path: '*',
name:'NotFound',
component: NotFound
}
- 在Main.vue页面中接收参数
- 显示在页面中
{{name}}
- 重新运行,运行结果与预期一致
- 重定向
- 在Main.vue中添加一个子菜单栏
系统管理
回到首页
- 在index.js中的children中添加如下代码
{
path:'/goTop',
redirect:'/main'
}
- 重新运行,点击回到首页链接,成功跳转
17、404和路由钩子
路由模式有两种
- hash:路径带#符号,http://localhost:8080/#/login
- history:路径不带#,http://localhost:8080/login
修改路由配置,代码如下:
export default new VueRouter({
mode:'history',
routes:[
]
})
处理404
- 在component文件夹下创建一个名为NotFound.vue的视图组件,代码如下:
页面不存在,请重试
- 在路由的主文件index.js中添加如入代码
{
path: '*',
name:'404',
component: NotFound
}
18.路由钩子与异步请求
- 路由钩子
beforeRouteEnter:在渲染该组件的第一营路由被confirm前调用,不能获取组件实例this,因为当守卫执行前,组件实例还没被创建
beforeRouteLeave:导航离开该组件的对应路由时调用,可以访问组件实例this
-
to: Route: 即将要进入的目标路由对象
-
from: Route: 当前导航正要离开的路由
-
next:理由的控制参数
- next():跳入下一个页面
- next('/path'):改变路由的跳转方向,使其跳到另一个路由
- next(false):返回原来的页面
- next((vm)=>{})仅在beforeRouteEnter中可用,vm使组件实例
测试:
- 在Profile组件中添加两个钩子函数
个人信息
{{$route.params.id}}
- 运行测试
点击个人信息链接时执行beforeRouteEnter,点击其他链接时执行beforeRouteLeave
- 在钩子函数中使用异步请求
- 安装Axios
cnpm install axios --save - 在main.js中引用Axios
import axios from 'axios'
// axios需要使用prototype将axios挂载到原型上 ,$后面是自己另起的名称,以后就可以使用该名称
Vue.prototype.axios = axios;
- 准备数据:只有我们的static目录下的文件是可以被访问到的,所以我们把静态文件放入该目录下
//静态数据存放的位置
static/jsondata/data.json
{
"name":"狂神说java",
"url": "http://baidu.com",
"page": "1",
"isNonProfit":"true",
"address": {
"street": "含光门",
"city":"陕西西安",
"country": "中国"
},
"links": [
{
"name": "B站",
"url": "https://www.bilibili.com/"
},
{
"name": "4399",
"url": "https://www.4399.com/"
},
{
"name": "百度",
"url": "https://www.baidu.com/"
}
]
}
- 在Profile.vue页面中的methods{}中添加一个getData方法
methods:{
getData(){
this.axios({
method:'get',
url:'http://localhost:8080/static/jsondata/data.json'
}).then(response=>{
console.log(response);
})
}
}
- 在beforeRouteEnter中进行异步请求
beforeRouteEnter(to, from, next){
console.log("进入组件时路由调用");
next((vm)=>{
vm.getData();
});
},
- 运行测试,遇到下面的问题
原因是:将this.axios写成了this.$axios
修改后成功获取到数据