混合开发(服务器端渲染)
前后端分离
后端提供接口,前端开发界面效果(专注于用户的交互)
库
库提供大量API,需要自己调用这些API简化开发。
框架
框架提供了一些基础服务,一般不需要自己调用,会自动完成一些基本功能。
一款非常优秀的前端 Javascript 框架,由尤雨溪创建开发
可以轻松构建单页 (SPA) 应用程序
通过 指令 扩展了 HTML,通过 表达式 绑定数据到 HTML
最大程度上解放了 DOM 操作
它能让你更加的享受编程的乐趣
数据驱动,开源
官网
简单易用
灵活渐进式
轻量高效
虚拟 DOM
MVVM
组件化
Vue.js 不支持 IE8 及其以下版本
最新稳定版本:2.5.16
直接下载
开发版本:https://vuejs.org/js/vue.js
生产版本:https://vuejs.org/js/vue.min.js
CDN
使用 npm下载(默认安装最新稳定版)
npm install vue
通过数据绑定的方式,在界面上展示Hello World
{{ msg }}Vue实例创建Vue实例每一个Vue应用都是通过Vue构造函数创建一个Vue的实例开始
var vm = new Vue({ // Vue的选项});Vue的选项
el 选项:指定Vue作用的范围
data 选项:data提供数据对象,绑定的数据
Vue.js 使用了基于 HTML 的模板语法,允许开发者声明式地将 DOM 绑定至底层 Vue 实例的数据。所有 Vue.js 的模板都是合法的 HTML ,所以能被遵循规范的浏览器和 HTML 解析器解析。
插值表达式数据绑定最常见的形式就是使用“Mustache”语法 (双大括号) 的文本插值:
{{ msg }}Javascript表达式对于所有的数据绑定,Vue.js 都提供了完全的 Javascript 表达式支持。
{{ number + 1 }}
{{ age > 18 ? '年满18岁' : '未满18岁' }}
{{ message.split('').reverse().join('') }}
{{ msg }}
注意:差值表达式中不能写语句。例如:var a = 10;
指令指令 (Directives) 是带有 v- 前缀的特殊特性。指令特性的值预期是单个 Javascript 表达式(v-for 是例外情况,稍后我们再讨论)。指令的职责是,当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM。参考文档
v-html/v-textv-text
v-text 标签的指令更新整个标签中的内容
差值表达式,可以更新标签中局部的内容
v-text和差值表达式的区别
v-html
可以渲染内容中的HTML标签
尽量避免使用,否则会带来危险(XSS攻击 跨站脚本攻击)
可以绑定标签上的任何属性。
动态绑定图片的路径
绑定a标签上的id
删除
绑定class
对象语法和数组语法
对象语法
如果isActive为true,则返回的结果为
hei
数组语法
渲染的结果
hei
绑定style
对象语法和数组语法
对象语法
渲染的结果
hei
数组语法
abc
简化语法
表单元素的绑定
双向数据绑定
数据发生变化可以更新到界面
通过界面可以更改数据
绑定文本框
当文本框的值发生边框后,div中的内容也会发生变化
{{ name }}绑定多行文本框
{{ name }}注意:多行文本框中不能使用{{ name }}的方式绑定
绑定复选框
{{ checked }}吃饭:
睡觉:
打豆豆:
{{ checklist }}绑定多个复选框
此种方式需要input标签提供value属性
绑定一个复选框
绑定单选框
男女{{sex}}绑定下拉框
Selected: {{ selected }}
绑定事件
事件修饰符:
.prevent
.once
简化语法
删除
一次性绑定
当创建一个 Vue 实例时,你可以传入一个选项对象。你可以在 API 文档 中浏览完整的选项列表。
el 选项
参考文档:https://cn.vuejs.org/v2/api/#el
提供一个在页面上已存在的 DOM 元素作为 Vue 实例的挂载目标。可以是 CSS 选择器,也可以是一个 HTMLElement 实例。
注意:
不能作用到 或者
上也可以通过 实例.$mount() 手动挂载
data 选项
参考文档:https://cn.vuejs.org/v2/api/#data
Vue 实例的数据对象,能够响应式数据变化(双向绑定)
可以通过 vm.$data 访问原始数据对象
Vue 实例也代理了 data 对象上所有的属性,因此访问 vm.a 等价于访问 vm.$data.a
视图中绑定的数据必须显式的初始化到 data 中
methods 选项
参考文档:https://cn.vuejs.org/v2/api/#methods
methods 将被混入到 Vue 实例中。可以直接通过 vm 实例访问这些方法,或者在指令表达式中使用。方法中的 this自动绑定为 Vue 实例。
注意: 不应该使用箭头函数来定义 method 函数 (例如 plus: () => this.a++)。理由是箭头函数绑定了父级作用域的上下文,所以 this 将不会按照期望指向 Vue 实例,this.a 将是 undefined。
var vm = new Vue({ data: { a: 1 }, methods: { plus: function () { this.a++ } } }) vm.plus() vm.a // 2
展示列表数据
删除数据
添加数据
总结:
Vue 最大程度上减少了页面上的 DOM 操作
让开发人员更专注于业务操作
通过简洁的指令结合页面结构与逻辑数据
代码结构更合理
维护成本更低
数据驱动
VueJS 解放了传统 Javascript 中频繁的 DOM 操作
https://github.com/vuejs/vue-devtools
MVVMMVVMPattern.png
其它知识点过滤器Vue.js 允许你自定义过滤器,可被用于一些常见的文本格式化。过滤器可以用在两个地方:双花括号插值和 v-bind 表达式 (后者从 2.1.0+ 开始支持)。
需求:对表格案例中的日期进行格式化。
计算属性{{ item.date | fmrTime('YYYY-MM-DD HH:mm:ss') }}
模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的。
计算属性当依赖的data中的数据发生变化的时候执行
计算属性是基于它们的依赖进行缓存的,计算属性只有在它的相关依赖发生改变时才会重新求值。
参考文档
通过获取时间,演示计算属性和methods中方法的区别(缓存数据的差异)。
计算属性和方法的区别
方法每次调用都会执行
计算属性只有当依赖的数据方法变化才会执行
需求:表格案例中实现搜索功能
.... ref 在Vue.js中操作DOM。
需求:表格案例中让文本框默认获得焦。
给要获取焦点的元素增加ref属性
在mounted中通过$refs获取DOM元素
注意:Vue.js中不推荐直接操作DOM,除非必须否则不建议这么使用。
自定义指令除了核心功能默认的指令,例如:v-model 和 v-show,Vue 也允许注册自定义指令。
需求:表格案例中让文本框默认获得焦。 给文本框增加自定义指令 v-focus
发送网络请求在Vue.js中发送网络请求本质还是ajax,我们可以使用插件方便操作。
axios
vue-resource
Vuejs的插件,已经不维护,作者不推荐使用
axios
可以在任何地方使用,推荐
既可以在浏览器端又可以在node.js中使用的发送http请求的库,支持Promise,默认不支持jsonp。官网
表格案例
发送get请求
axios.get('http://localhost:3000/brands') .then(res => { console.log(res.data); }) .catch(err => { console.dir(err) });发送delete请求
axios.delete('http://localhost:3000/brands/109') .then(res => { console.log(res.data); }) .catch(err => { console.dir(err) });发送post请求
axios.post('http://localhost:3000/brands', {name: '小米', date: new Date()}) .then(res => { console.log(res); }) .catch(err => { console.dir(err) });jsonp
https://github.com/axios/axios/blob/master/COOKBOOK.md
jsonp('http://localhost:3000/brands', (err, data) => { if (err) { console.dir(err.msg); } else { console.dir(data); } });过渡和动画
数据列表
删除数据
添加数据
查询数据
watch: { searchKey: function (newValue, oldValue) { // 发送请求获取列表数据 axios.get('http://localhost:3000/brands?name_like=' + newValue) .then(res => { this.list = res.data; }) .catch(err => { console.log(err); }); }
侦听器
监听data对象的searchKey属性的变化,执行相应的操作
Vue 在插入、更新或者移除 DOM 时,提供多种不同方式的应用过渡效果。
在 CSS 过渡和动画中自动应用 classVue 提供了 transition 的封装组件,在下列情形中,可以给任何元素和组件添加进入/离开过渡
// v要替换成transition组件的name属性值v-enter:定义进入过渡的开始状态。 v-enter-active:定义进入过渡生效时的状态。 v-enter-to: 2.1.8版及以上 定义进入过渡的结束状态。 v-leave: 定义离开过渡的开始状态。 v-leave-active:定义离开过渡生效时的状态。 v-leave-to: 2.1.8版及以上 定义离开过渡的结束状态。示例:
自定义过渡动画的类名.box { position: absolute; left: 0; top: 50px; width: 100px; height: 100px; background-color: red; } .slide-enter, .slide-leave-to { left: 200px; opacity: 0; } .slide-enter-active, .slide-leave-active { transition: all 2s; } .slide-enter-to, .slide-leave { left: 0px; opacity: 1; } 可以通过transition组件自定义过渡动画的类名,可以方便结合第三方的动画库使用,比如:animate.css
// transition组件的属性 enter-classenter-active-classenter-to-class (2.1.8+) leave-classleave-active-classleave-to-class (2.1.8+)示例:
组件什么是组件hello 组件系统是 Vue 的另一个重要概念,因为它是一种抽象,允许我们使用小型、独立和通常可复用的组件构建大型应用。仔细想想,几乎任意类型的应用界面都可以抽象为一个组件树:
components.png
组件和模块
模块:侧重于功能或者数据的封装
组件:包含了 template、style 和 script,而它的 script 可以由各种模块组成
b25efd3e8af188b5ab36ccb66baddd71_hd.jpg
Vue中的组件开发组件是可复用的 Vue 实例,且带有一个名字,比如
。把这个组件作为自定义元素来使用。组件的好处是写一次可以进行任意次数的复用。 组件参考文档
全局组件Vue.component('my-breadcrumb', { template: ` {{ level1 }} / {{ level2 }} `, data() { return { level1: '用户管理1', level2: '用户列表1' }; }, methods: { t() { alert('hello'); } } });私有组件注意:
组件的模板中必须有且只有一个根标签
组件是一个特殊的Vue实例
组件中的data是一个方法,目的是让每一个组件维护一个自己的数据
组件有自己的作用域
// 私有组件var ComponentA = { template: '{{ msg }}', data() { return { msg: 'hello' }; } };var vm = new Vue({ el: '#app', components: { 'component-a': ComponentA } });通过Props给子组件传值Vue实例的生命周期
子组件可以通过 props 选项接收一个一些值,通过 props 传递的值变成了改组件的一个属性。
var ComponentA = { template: '{{ title }}', props: ['title'], };当然子组件具有 props 选项后,数据可以通过标签的自定义属性传递给子组件
在vue的实例中提供该属性值
var vm = new Vue({ el: '#app', data: { msg: 'hello heima', }, components: { 'component-a': ComponentA } });
什么生命周期
定义:生命周期是指vue实例或者组件从诞生到消亡经历的每一个阶段,在这些阶段的前后可以设置一些函数当做事件来调用。
参考
生命周期
生命周期中的钩子函数
//创造vue实例之后运行此函数,vm中的data/methods中的成员不可用beforeCreate: function () { console.log("beforeCreate") }//创造vue实例之后运行此函数,vm中的data/methods属性可用created: function () { console.log("created") }//当vue实例的el节点或组件挂载到页面以前运行次函数beforeMount: function () { console.log("beforeMount") }//当vue实例的el节点或组件挂载到页面以后运行次函数mounted: function () { console.log("mounted") }//当vue实例数据发生改变前触发此函数beforeUpdate: function () { console.log("beforeUpdate") }//当vue实例数据发生改变后触发此函数updated: function () { console.log("updated") }前端路由单页应用vue-router快速体验
什么是单页应用
单页应用(single page web application,SPA),是在一个页面完成所有的业务功能,浏览器一开始会加载必需的HTML、CSS和Javascript,之后所有的操作都在这张页面完成,这一切都由Javascript来控制。
单页应用优缺点
首次加载大量资源(可以只加载所需部分)
对搜索引擎不友好
开发难度相对较高
操作体验流畅
完全的前端组件化
优点
缺点
单页应用的原理
History 路由是基于 HTML5 规范,在 HTML5 规范中提供了 history.pushState || history.replaceState 来进行路由控制。
利用URL上的hash,当hash改变不会引起页面刷新,所以可以利用 hash 值来做单页面应用的路由,
并且当 url 的 hash 发生变化的时候,可以触发相应 hashchange 回调函数。
模拟实现
Hash路由
var app = document.getElementById('app');window.onhashchange = function () { var hash = location.hash.replace('#', ''); switch (hash.toLowerCase()) { case '/': app.innerHTML = '首页内容'; break; case '/users': app.innerHTML = '用户管理内容'; break; …… } };History路由
动态路由匹配
导入vue和vue-router
设置HTML中的内容
用户管理 创建组件
// 创建组件// 组件可以放到单独的js文件中var Home = { template: '这是Home内容'};var Users = { template: '这是用户管理内容'};配置路由规则
// 配置路由规则var router = new VueRouter({ routes: [ { name: 'home', path: '/', component: Home }, { name: 'users', path: '/users', component: Users } ] });设置vue的路由选项
var vm = new Vue({ el: '#app', router });假设有一个用户列表,想要删除某一个用户,需要获取用户的id传入组件内,如何实现呢?
此时可以通过路由传参来实现,具体步骤如下:
webpack
路由规则中增加参数,在path最后增加 :id
{ name: 'users', path: '/users/:id', component: Users },通过
传参,在路径上传入具体的值 用户管理 在组件内部可以使用,this.$route 获取当前路由对象
var Users = { template: '这是用户管理内容 {{ $route.params.id }}', mounted() { console.log(this.$route.params.id); } };webpack 是一个模块打包器。webpack 的主要目标是将 Javascript 文件打包在一起,打包后的文件用于在浏览器中使用。
参考网站: 中文参考网站 官网
安装webpack最新webpack版本4.x
本地安装webpack
安装webpack的命令行工具 webpack-cli
$ npm install webpack webpack-cli --save-dev快速实践参考官网
项目结构,默认的目录和文件名称不可修改
webpack-demo |- package.json + |- /dist + |- index.html |- /src |- index.js
入口js文件,默认名称index.js
math.js
export default { add(a, b) { return a + b; }, sub(a, b) { return a - b; } };index.js
import Math from './math';var x = 5;var y = 6;console.log(Math.add(5, 6));console.log(Math.sub(5, 6));
运行
$ npm webpack配置文件 webpack.config.jswebpack4.x 以前,必须要有配置文件。在 webpack 4.x 以后,可以无须任何配置使用(),然而大多数项目会需要很复杂的设置,这就是为什么 webpack 仍然要支持。
webpack常用的Loader
使用步骤
const path = require('path');module.exports = { // 配置入口文件 entry: './src/index.js', // 配置打包的文件和路径 output: { filename: 'bundle.js', path: path.resolve(__dirname, 'dist') } };$ npm webpack --config webpack.config.js注意:打包的文件名改变后,要修改index.html的script标签引入的文件名
运行命令
项目根目录下,手动新建webpack.config.js
NPM脚本
输入上面的命令太繁琐,可以直接在终端运行 webpack,会默认加载webpack.config.js配置文件。
"scripts": { "test": "echo "Error: no test specified" && exit 1", "build": "webpack" },$ npm run build
终端输入
在package.json中新增
webpack 最出色的功能之一就是,除了 Javascript,还可以通过 loader 引入任何其他类型的文件。webpack 可以把所有文件作为模块,动态打包(dynamically bundle)所有依赖项。
参考文档
打包CSS打包less
安装和配置 style-loader 和 css-loader
$ npm install --save-dev style-loader css-loaderconst path = require('path'); module.exports = { entry: './src/index.js', output: { filename: 'bundle.js', path: path.resolve(__dirname, 'dist') }, + module: { + rules: [ + { + test: /.css$/, + use: [ + 'style-loader', + 'css-loader'+ ] + } + ] + } };
配置,在webpack.config.js中
安装
在入口index.js中,导入css模块
import './css/index.css';运行webpack命令
$ npm run build打包sass
安装和配置
$ npm install less-loader less --save-dev{ test: /.less$/, use: [ 'style-loader', 'css-loader', 'less-loader' ] }less
@color: yellow;body { background-color: @color; }加载图片
安装和配置
$ npm install sass-loader node-sass --save-dev{ test: /.scss$/, use: [ 'style-loader', 'css-loader', 'sass-loader' ] }scss
$color: red;body { background-color: $color; }使用 file-loader 可以加载图片和字体
加载字体
安装和配置
$ npm install --save-dev file-loader{ test: /.(png|svg|jpg|gif)$/, use: [ 'file-loader' ] }webpack常用插件
配置
{ test: /.(woff|woff2|eot|ttf|otf)$/, use: [ 'file-loader' ] }除了通过loader去处理不同的资源文件以外,webpack还支持插件机制,通过插件可以完成更多的事情。
HtmlWebpackPlugin自动生成index.html,并引入资源文件,还可以通过配置压缩HTML。
CleanWebpackPlugin
安装
npm install --save-dev html-webpack-plugin配置
const HtmlWebpackPlugin = require('html-webpack-plugin'); ...... plugins: [ new HtmlWebpackPlugin({ // 文档的标题 title: 'Output Management', // 生成的文档文件名 filename: 'index.html', // 模板文件 template: 'index.html', minify: { collapseWhitespace: true } }) ] ......清空dist目录。
使用source map
安装
npm install clean-webpack-plugin --save-dev配置
const CleanWebpackPlugin = require('clean-webpack-plugin'); ……new CleanWebpackPlugin(['dist']), ……参考文档
在webpack.config.js中添加
devtool: 'inline-source-map',使用 webpack-dev-serverwebpack-dev-server 为你提供了一个简单的 web 服务器,并且能够实时重新加载(live reloading)。让我们设置以下:
$ npm install --save-dev webpack-dev-serverwebpack.config.js
devServer: { contentbase: './dist'},package.json
"start": "webpack-dev-server --open"启用HMR模块热替换(Hot Module Replacement 或 HMR)是 webpack 提供的最有用的功能之一。它允许在运行时更新各种模块,而无需进行完全刷新。
webpack.config.js
const webpack = require('webpack'); ....... devServer: { contentbase: './dist', hot: true}, ....... ....... new webpack.NamedModulesPlugin(), new webpack.HotModuleReplacementPlugin() .......综合案例单文件组件可以通过 .vue 文件封装组件,参考文档
案例演示
处理 .vue 文件 — 使用 vue-loader
vue-loader使用比较特殊,如下
$ npm install vue-loader --save-dev $ npm install vue-template-compiler --save-dev// 配置插件// 配置loader{ test: /.vue$/, loader: 'vue-loader'}image-20180526145007221.png
搭建项目结构配置根组件
新建项目
# 注意项目名称不能有中文$ npm init -y"devDependencies": { "clean-webpack-plugin": "^0.1.19", "css-loader": "^0.28.11", "file-loader": "^1.1.11", "html-minifier": "^3.5.16", "html-webpack-plugin": "^3.2.0", "less": "^3.0.4", "less-loader": "^4.1.0", "node-sass": "^4.9.0", "sass-loader": "^7.0.1", "style-loader": "^0.21.0", "url-loader": "^1.0.1", "vue-loader": "^15.2.0", "vue-template-compiler": "^2.5.16", "webpack": "^4.8.3", "webpack-cli": "^2.1.4", "webpack-dev-server": "^3.1.4" }, "dependencies": { "vue": "^2.5.16" }$ npm install$ npm install bootstrap@3.3.7 --save
下载bootstrap3
安装依赖
拷贝 webpack.config.js 到根目录
拷贝依赖
初始化package.json
项目结构
[图片上传失败...(image-de211b-1527597271494)]
提取子组件
从模板中复制自定义样式 index.css 到assets/css目录
入口文件 src/index.js
import Vue from 'vue';import App from './App.vue';// 导入bootstrap样式import 'bootstrap/dist/css/bootstrap.css';// 导入自定义样式import './assets/css/index.css';const vm = new Vue({ el: '#app', render: c => c(App) });根组件 src/App.vue
复制模板中index.html的内容到App.vue中
运行测试
$ npm start使用 Vue-Router 实现页面导航管理
提取头部组件 components/header.vue
提取侧边栏组件 components/sidebar.vue
提取英雄列表组件 views/hero-list.vue
根组件 src/App.vue 中加载组件
import Header from './components/header.vue';import Sidebar from './components/sidebar.vue';import Heroes from './views/heroes.vue';export default { components: { Header, Sidebar, Heroes } };Hero List Add
Vue-Router 能帮我们实现点击某个导航链接的时候动态的展示一个组件
JSON Server
安装路由模块
$ npm install vue-router --save注册路由插件
在index.js中,加载路由插件
import VueRouter from 'vue-router';// 注册路由插件Vue.use(VueRouter);加载组件,配置路由规则
index.js中
// 加载组件import Heroes from './views/heroes/heroes.vue';import Weapons from './views/weapons.vue';import Equips from './views/equips.vue';// 配置路由规则const router = new VueRouter({ routes: [ // 设置根路径跳转到英雄管理界面 {'name': 'home', path: '/', redirect: {name: 'heroes'}}, {'name': 'heroes', path: '/heroes', component: Heroes}, {'name': 'weapons', path: '/weapons', component: Weapons}, {'name': 'equips', path: '/equips', component: Equips} ] });new Vue({ el: '#app', render: c => c(App), // 设置路由 router });在 src/App.vue 组件中留路由出口(告诉路由往哪里渲染 path 匹配到的组件)
在侧边栏 src/components/sidebar.vue 组件中 增加两个导航链接
将激活-class-应用在外层元素
英雄列表 武器列表 装备列表 可以快速开启 REST API 测试服务器的工具命令行工具。官网
安装$ npm install json-server -g使用$ json-server --watch db.json接口地址
获取英雄列表
请求路径:http://localhost:3000/heros
请求方法:GET
实现项目功能
根据英雄id获取一个英雄
:id 需要给定一个英雄的 id
请求路径:
http://localhost:3000/heros/:id请求方法:GET
添加英雄
{ name: '英雄名称', gender: '英雄性别'}
请求路径:http://localhost:3000/heros
请求方法:POST
请求体:
删除英雄
:id 需要给定一个英雄的 id
请求路径:
http://localhost:3000/heros/:id请求方法:DELETe
编辑英雄
:id 需要给定一个英雄的 id
请求路径:
http://localhost:3000/heros/:id请求方法:PATCH
请求体:
{ name: '英雄名称', gender: '英雄性别'}安装 axios 到项目中
$ npm install axios --save英雄列表JS
import axios from 'axios';export default { data() { return { heroes: [] }; }, mounted() { this.loadData(); }, methods: { async loadData() { const res = await axios.get('http://localhost:3000/heros'); this.heroes = res.data; } } };HTML
删除英雄{{ index + 1 }} {{ item.name }} {{ item.gender }} edit delete HTML
deleteJS
async handleClick(id) { const is/confirm/ied = confirm('确认要删除该英雄?'); if (!is/confirm/ied) { return; } const res = await axios.delete(`http://localhost:3000/heros/${id}`); if (res.status === 200) { this.loadData(); alert('删除成功'); } else { alert('删除失败'); } }添加英雄路由
新建 src/views/heroes/heroes-add.vue
配置路由
import HeroesAdd from '../views/heroes/heroes-add.vue';// 增加一个路由规则{'name': 'heroesadd', path: '/heroes/add', component: HeroesAdd}, {'name': 'heroes', path: '/heroes', component: Heroes},src/views/heroes/heroes.vue 中点击添加按钮
Add HTML
添加英雄
JS
import axios from 'axios';export default { data() { return { formdata: { name: '', gender: '' } }; }, methods: { async handleAdd() { const res = await axios.post('http://localhost:3000/heros', this.formData); if (res.status === 201) { // 跳转到列表页面 this.$router.push({ name: 'heroes' }); } else { alert('添加失败'); } } } };编辑英雄路由
新建 src/views/heroes/heroes-edit.vue
配置路由
import HeroesEdit from '../views/heroes/heroes-edit.vue';// 增加一个路由规则{'name': 'heroes', path: '/heroes', component: Heroes}, {'name': 'heroesadd', path: '/heroes/add', component: HeroesAdd}, {'name': 'heroesedit', path: '/heroes/edit/:id', component: HeroesEdit},src/views/heroes/heroes.vue 中,设置编辑
edit HTML
和添加英雄一样
JS
import axios from 'axios';export default { data() { return { formdata: { name: '', gender: '' }, heroId: -1 }; }, created() { this.heroId = this.$route.params.id; this.getHeroById(); }, methods: { // 根据id,获取英雄信息 async getHeroById() { const res = await axios.get(`http://localhost:3000/heros/${this.heroId}`); if (res.status === 200) { this.formData = res.data; } }, // 更新英雄信息 async handleEdit() { const res = await axios.patch(`http://localhost:3000/heros/${this.heroId}`, this.formData); if (res.status === 200) { // 跳转到列表页面 this.$router.push({ name: 'heroes' }); } else { alert('编辑失败'); } } } };NPM 缓存安装需要曾经从网络使用NPM安装过想要的包
$ npm --cache-min 9999999 install webpack --save-dev
作者:他爱在黑暗中漫游
链接:https://www.jianshu.com/p/77ea57cc82f1Vue.js相关栏目本月热门文章
- 1【Linux驱动开发】设备树详解(二)设备树语法详解
- 2别跟客户扯细节
- 3Springboot+RabbitMQ+ACK机制(生产方确认(全局、局部)、消费方确认)、知识盲区
- 4【Java】对象处理流(ObjectOutputStream和ObjectInputStream)
- 5【分页】常见两种SpringBoot项目中分页技巧
- 6一文带你搞懂OAuth2.0
- 7我要写整个中文互联网界最牛逼的JVM系列教程 | 「JVM与Java体系架构」章节:虚拟机与Java虚拟机介绍
- 8【Spring Cloud】新闻头条微服务项目:FreeMarker模板引擎实现文章静态页面生成
- 9JavaSE - 封装、static成员和内部类
- 10树莓派mjpg-streamer实现监控及拍照功能调试
- 11用c++写一个蓝屏代码
- 12从JDK8源码中看ArrayList和LinkedList的区别
- 13idea 1、报错java: 找不到符号 符号: 变量 log 2、转换成Maven项目
- 14在openwrt使用C语言增加ubus接口(包含C uci操作)
- 15Spring 解决循环依赖
- 16SpringMVC——基于MVC架构的Spring框架
- 17Andy‘s First Dictionary C++ STL set应用
- 18动态内存管理
- 19我的创作纪念日
- 20Docker自定义镜像-Dockerfile
热门相关搜索路由器设置 木托盘 宝塔面板 儿童python教程 心情低落 朋友圈 vim 双一流学科 专升本 我的学校 日记学校 西点培训学校 汽修学校 情书 化妆学校 塔沟武校 异形模板 西南大学排名 最精辟人生短句 6步教你追回被骗的钱 南昌大学排名 清朝十二帝 北京印刷学院排名 北方工业大学排名 北京航空航天大学排名 首都经济贸易大学排名 中国传媒大学排名 首都师范大学排名 中国地质大学(北京)排名 北京信息科技大学排名 中央民族大学排名 北京舞蹈学院排名 北京电影学院排名 中国戏曲学院排名 河北政法职业学院排名 河北经贸大学排名 天津中德应用技术大学排名 天津医学高等专科学校排名 天津美术学院排名 天津音乐学院排名 天津工业大学排名 北京工业大学耿丹学院排名 北京警察学院排名 天津科技大学排名 北京邮电大学(宏福校区)排名 北京网络职业学院排名 北京大学医学部排名 河北科技大学排名 河北地质大学排名 河北体育学院排名



