前端框架vue
使用vue前需先安装nodejs
nodejs下载安装
官网:https://nodejs.org/en/download/
窗口输入指令
node -v 显示nodejs版本安装成功 npm -v 显示npm版本自带npm安装成功
环境配置
(1)找到安装nodejs的路径
(2)新增 node_global 和 node_cache 文件夹
(3)高级选项:用户变量 path :C:\Program Files\nodejs\node_global
系统变量 NODE_PATH :C:\Program Files\nodejs\node_modules
linux上环境变量,进入:vi /etc/profile
export NODE_HOME=/home/workspaces/node-v14.17.1-linux-x64 export PATH=$PATH:$NODE_HOME/bin export NODE_PATH=$NODE_HOME/lib/node_modules
vue2的下载安装
#去掉npm代理 npm config rm proxy npm config rm https-proxy #修改npm的资源镜像链接 npm config set registry http://registry.npm.taobao.org # 升级或安装 cnpm npm install cnpm -g # 最新稳定版 $ cnpm install vue # 全局安装 vue-cli $ cnpm install --global vue-cli # 创建一个基于 webpack 模板的新项目 $ vue init webpack my-project
vue3的下载安装
如果是windows系统npm需要管理员运行cmd
由于 npm 安装速度慢
# 升级或安装 cnpm npm install cnpm -g # 安装淘宝镜像 npm install -g cnpm --registry=https://registry.npm.taobao.org # 更新/最新稳定版 cnpm install vue@next # 安装脚手架,全局安装 vue-cli yarn global add @vue/cli # 或 cnpm install -g @vue/cli # 安装完后查看版本 vue --version #在 Vue 项目中运行 vue upgrade --next #全局安装一个桥接工具 # vue init的运行效果将会跟 vue-cli@2.x 相同 npm install -g @vue/cli-init #vue init 命令来创建一个项目,这里需要进行一些配置,默认回车即可 vue init webpack my-project #进入项目 cd my-project #安装并运行 cnpm run dev
方式二:
#创建vue项目(不可以有大写) vue create xxxx #进入项目 cd xxxx #运行项目 npm run serve
用idea使用vue
打开idea,用idea打开我们刚才创建的vue项目
在idea-->setting-->plugins-->下载vue.js插件
vue使用流程是:
- 先写VUE文件,写要展示的东西
- 在
router/index.js
中导入(import)刚写的VUE,然后通过path
,name
和component
3个属性来定位他(vue语法要求:对象值前要加空格) - 在App.vue中写
router-link to="xxxx"
使用图形化界面
#可以通过 vue ui 命令来打开图形化界面创建和管理项目: vue ui
Vue3 项目打包
需要在my-project项目下运行:
cnpm run build
出现“Build complete”打包成功
执行完成后,会在 Vue 项目下会生成一个 dist 目录,该目录一般包含 index.html 文件及 static 目录,static 目录包含了静态文件 js、css 以及图片目录 images(如果有图片的话)。
如果直接双击打开 index.html,在浏览器中页面可能是空白了,要正常显示则需要修改下 index.html 文件中 js、css 文件路径。
例如我们打开 dist/index.html 文件看到 css 和 js 文件路径是绝对路径:
<link href=/static/css/app.33da80d69744798940b135da93bc7b98.css rel=stylesheet>
<script type=text/javascript src=/static/js/app.717bb358ddc19e181140.js></script>
我们把 js、css 文件路径修改为相对路径:
<link href=static/css/app.33da80d69744798940b135da93bc7b98.css rel=stylesheet>
<script type=text/javascript src=static/js/app.717bb358ddc19e181140.js></script>
vue安装axios
与后端交互需用到ajax,每个VUE项目都要下载一次。在项目路径下
方法1安装axios 会安装到plugins目录下
vue add axios
在main.js引入axios
import axios from './plugins/axios'
若还是报错,axios加上this,即this.axios.get(…)
方法二安装axios(推荐)
使用npm安装axios
npm install --save axios
在相应页面声明axios变量
const axios = require('axios');
1.axios发送get请求
const axios = require('axios');
1.1.参数写在路径后面
// Make a request for a user with a given ID axios.get('/user?ID=12345') .then(function (response) { // handle success console.log(response); }) .catch(function (error) { // handle error console.log(error); }) .then(function () { // always executed });
1.2.参数不写在路径后面
// Optionally the request above could also be done as axios.get('/user', { params: { ID: 12345 } }) .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); }) .then(function () { // always executed });
1.3.用异步async/await语法
// Want to use async/await? Add the `async` keyword to your outer function/method. async function getUser() { try { const response = await axios.get('/user?ID=12345'); console.log(response); } catch (error) { console.error(error); } }
2.axios发送post请求
2.1.常规用法
axios.post('/user', { firstName: 'Fred', lastName: 'Flintstone' }) .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); });
axios.post('/user', JSON.stringify(data),{
harders:{
'Content-Type':'application/json'
}, firstName: 'Fred', lastName: 'Flintstone' }) .then(response => { console.log(response); }) .catch(error => { console.log(error); });
2.2.复合用法
// Send a POST request axios({ method: 'post', url: '/user/12345', data: { firstName: 'Fred', lastName: 'Flintstone' } });
3.axios.all用法(Promise.all)
可以同时请求多个接口
axios.all( [getUserAccount(), getUserPermissions()]) .then( axios.spread(function(acct,perms)) )
4.axios拦截器
4.1.请求拦截---request
// Add a request interceptor axios.interceptors.request.use(function (config) { // Do something before request is sent return config; }, function (error) { // Do something with request error return Promise.reject(error); });
4.2.响应拦截---response
// Add a response interceptor axios.interceptors.response.use(function (response) { // Any status code that lie within the range of 2xx cause this function to trigger // Do something with response data return response; }, function (error) { // Any status codes that falls outside the range of 2xx cause this function to trigger // Do something with response error return Promise.reject(error); });
eslintrc语法校验
vue .eslintrc.js文件配置在rules下
//在结尾不检查分号
'semi': 0
//禁止在参数的(前面有空格)
'space-before-function-paren': ['error', 'never']
//()前不检查空格
'space-before-function-paren': 0
//ESLint 限定缩进是 2 个空格,而我们一般使用 Tab 键的缩进是 4 个空格 Expected indentation of 2 spaces but found 4. eslint(indent) [8, 1]
'indent': ['off',2]
vue语法要求:对象值前要加空格
跨域问题解决
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
@Configuration
public class CrosConfig{
@Bean
public CorsFilter corsFilter() {
//1. 创建CorsConfiguration对象
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedOrigin("*");//设置允许那些域来访问,*是通配符,允许所有域
corsConfiguration.addAllowedHeader("*");//请求头字段
corsConfiguration.addAllowedMethod("*");//请求方式(GET,POST,DELETE,PUT)
//设置source
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", corsConfiguration);//1.映射路径 2.传入CorsConfiguration对象
return new CorsFilter(source);
}
}
vue安装element ui
安装element-ui
cnpm i element-ui --save
在main.js文件引入
import ElementUI from 'element-ui' import 'element-ui/lib/theme-chalk/index.css' Vue.use(ElementUI)
在页面使用(直接复制组件中的代码)
<template>
<el-table
:data="tableData"
border
style="width: 100%">
<el-table-column
prop="date"
label="日期"
width="180">
</el-table-column>
<el-table-column
prop="name"
label="姓名"
width="180">
</el-table-column>
<el-table-column
prop="address"
label="地址">
</el-table-column>
</el-table>
</template>
<script>
export default {
data() {
return {
tableData: [{
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-04',
name: '王小虎',
address: '上海市普陀区金沙江路 1517 弄'
}, {
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀区金沙江路 1519 弄'
}, {
date: '2016-05-03',
name: '王小虎',
address: '上海市普陀区金沙江路 1516 弄'
}]
}
}
}
</script>
<style scoped>
</style>
表格组件有可能用不了,卸载重新安装只有2.8版本生效
npm uninstall element-ui npm install element-ui@2.8.0
官网:https://element.eleme.cn/#/zh-CN/component/installation
根template只能有一个子元素
1.现象
每个组件文件中的根template,也就是最外层的template只能有一个子元素。非根template没有限制,可以有多个。以下的template均指的是根template,不要混淆了。
当template有多个子元素时,报错,如下
意思是说,每个template根元素只能有一个元素。
这个时候,可以进行修改,可以在所有的子元素外层,包一个div,如下:
2.原因
vue在动态创建dom的时候,会将template中的子元素作为入口进行创建,根据这个入口,遍历以该子元素作为根节点的整个节点树,然后创建虚拟dom。template用于创建单文件组件,实际上是一种原子化的设计,可以一次定义,然后在任何地方生成dom,如果有多个子元素,就违背了这种原子设计,也就是说,一个template就只会渲染一个子组件树。如果template有多个子元素,那么vue就无法获取确切入口,就得刻意去指定某个元素作为根节点,而同时其他节点也就成为了费节点,这样无疑就增大了程序设计的复杂性,而且还增加了无用代码,有必要吗,木有啊。所以,在语法检查的时候,就会进行校验,防止出现费力不讨好的情况发生。
vue中this指向问题:(uncaught (in promise) Typeerror:connot set)
(1)funtion普通函数中this指向window;所以如果需要在function函数中使用this对象,需要事先把this对象赋值给其他变量,如:
let self = this; this.getReportId().then(function(result) { self.id = result; alert(self.id); });
(2)箭头函数中this指向vue实例:箭头函数相当于匿名函数,并且简化了函数定义。看上去是匿名函数的一种简写,但实际上,箭头函数和匿名函数有个明显的区别:箭头函数内部的this是词法作用域,由上下文确定。此时this在箭头函数中已经按照词法作用域绑定了。很明显,使用箭头函数之后,箭头函数指向的函数内部的this已经绑定了外部的vue实例了。如:
this.getReportId().then(result => { this.id = result; alert( this.id); });
2、写法转换:以下两种写法效果是一样的:
formatter: function(params) { return params.name + ' 已接入: ' + params.data.num[2]; } formatter: params => { return params.name + ' 已接入: ' + params.data.num[2]; }
vue获取当前页面地址关于url的相关获取
-
window.location.href (当前url)—— http://www.xxxxxx.com:8000/test?id=123&username=xxx
-
window.location.protocol
(协议)—— http: -
window.location.host
(域名 + 端口)—— www.xxxxxx.com:8000 -
window.location.hostname
(域名)—— www.xxxxxx.com -
window.location.port
(端口)—— 8000 -
window.location.pathname
(路径)—— /test -
window.location.search
(请求的参数)—— ?id=123&username=xxx -
window.location.origin
(路径前面的url)—— http://www.xxxxxx.com:8000
vue跳转页面带参数
不带参数
this.$router.push('/login'); this.$router.push({name: 'Login'}); this.$router.push({path: '/login'});
this.$router.back();//退出登录
方式1:path+query a.vue向b.vue跳 前者是a
a.vue
this.$router.push({ // 跳转到的页面路径 path: '/detailPage', // 传递的参数集合 query: { detailData: data//{} } })
// b.vue接参 created(){ this.detailData = this.$route.query.detailData }
方法2:name+params
this.$router.push({ // 跳转到的页面名 name: 'detailPage', // 传递的参数集合 params: { detailData: data//{} } })
created(){ this.detailData = this.$route.params.detailData }
query与params的区别
相同点:都是Object类型
不同点:
query: 一个 key/value 对象,表示 URL 查询参数。例如,对于路径 /4?age=21,则有 $route.query.age == 21,如果没有查询参数,则是个空对象。地址栏中会显示传递的参数信息,因此这种方式不太安全。建议用这个
params: 一个 key/value 对象,包含了动态片段和全匹配片段,如果没有路由参数,就是一个空对象。刷新页面数据会丢失
注意
name与params,path与query搭配使用
push中的path与name对应router(路由配置)下index.js配置的path与name
注意区分$router 与 $route
$router: 全局的 router 实例。通过 vue 根实例中注入 router 实例,然后再注入到每个子组件,从而让整个应用都有路由功能。
$route : 路由对象,表示当前激活的路由的状态信息,包含了当前 URL 解析得到的信息
解决使用name+params传参时,刷新页面,参数丢失的问题
路由配置
// 在path后将参数带上 { path: '/detailPage/:id', name: 'detailPage', component: Detail, }
通过 $router.push 的 params 传参
toDetailPage(data) { this.$router.push({ name: 'detailPage', params: { id: data.id } }) },
获取参数
created(){ const id = this.$route.params.id }
退转页面后禁止回退,在需要禁止回退的页面添加以下代码
created(){ history.pushState(null, null, document.URL); window.addEventListenter('popstate', function() { history.pushState(null, null, document.URL); }); }
elementui使用总结
使用组件中的参数用“:”修饰。eg::model
使用组件中的事件用“@”修饰。eg:@click
return中修饰的是全局参数或对象,根据后面的配置决定是什么类型。eg:user: {}对象类型,users: []数组类型
method中修饰的是全局的方法。
调用return或method中的参数或方法时需使用this(需重定义:const that = this)
修饰全局方法:export function xxx(param1,param2 ...){}
清空弹窗form表单中的数据:
在<el-dialog>中新增 @open="initForm" 在<el-from>中新增ref="form" 在form的子标签<el-form-item>新增prop="type"(属性名称如:user.type) 在method中新增 initForm() { this.$refs['form'].restFields(); }
隐藏table中一列的数据:在<el-table-colum>中添加v-if="false"
span属性是控制宽度的:最大24