因为项目需求要做前端要做vue,记录一下从0开始的学习路程,主要是通过一些文档和b站的视频。
b站来源链接:https://www.bilibili.com/video/BV1YE411A746?p=20
文档:https://www.runoob.com/vue2/vue-if.html,https://element.faas.ele.me/#/zh-CN/component/table
1.模板语法:data内的绑定方式:有3种,第一种和第二种都是通过函数返回
2.v-html输出html代码:
3.v-model双向绑定和v-bind单向绑定,正常的数据流向是从数据层到视图层,v-model双向绑定后视图层的改变会返回到数据层,因此v-bind绑定的时候拿到的数据就是修改后的数据。
3-1通过v-bind的方式实现双向绑定:
4.v-on click点击事件:
5.过滤器:格式:{{}xxx|xxx}},左边的是参数,右边的是过滤方法,如下的过滤器是把字符串的首字母转化为大写:
6.vue组件的声明使用:
7.全局组件声明,第一个参数是名字,第二个参数是options对象,使用的时候在template中直接挂载就可以
8.父组件app往子组件content传值:
1)在父组件中定义data数据并通过v-bind与子组件绑定,v-bind冒号后的名字是自定义的
2)子组件通过props属性取值
3)通过v-for遍历
9.属性计算:computed,区别与方法,作为属性使用,直接调用缓存的结果,提高效率,虽然存放的是函数,但在调用时作为属性调用(不加小括号)
10.watch监控,给属性title绑定函数,当属性改变时调用函数,调用函数时可以传两个参数,第一个是现在的值,第二个是之前的值
或者
11.vue改变样式,通过v-bind绑定一个class,如果这个red为true的话就应用red,否则的话还是用之前的。
12.vue改变样式2,通过computed往bind传入一个json数据实现改变样式,如果要传多个样式的话用[]括起来,形式:v-bind:class=“[zzz,zzz]”
13.内嵌style样式的写法,引用了vue中的内容,是一个键值对,所以需要大括号,注意写法,不要写成background-color
14.vue的diff算法和虚拟DOM
15.v-if,v-else-if,v-else用法,v-show比v-if效率更高,v-show改变的是元素的样式,不显示的时候display是none而v-if元素直接消失,
注:做项目的时候遇到一个问题:在父组件用子组件的时候,需要在子组件加载之前调用后端的接口往子组件传值,所以用了一个created钩子函数,但是发现子组件并没有成功调用,原因是值没有传过去
因为父组件加载子组件是在created之前的,这时候就需要v-if来解决这个问题,在created方法调用完后台接口之后用v-if加载一下子组件,这样就可以成功往子组件传值了。
16.v-for嵌套循环
17.改变另一个vue的值,也可以调用另一个vue的方法
18.ref的用法,相当于id
19.通过mount的方式实现页面元素和vue的动态绑定,之前是用el
20.vue的生命周期函数,见官网
21.node.js提供了一个服务器可以让javascript运行在服务端,vue-cli是vue的脚手架,npm install vue-cli -g g的意思是全局加载
22.利用vue-cli脚手架创建项目:
实例化一个项目:
1.vue init webpack-simple myVueDemo
2.下载依赖 npm install
3.运行 npm run dev
23.原来的new Vue 现在改成export default 写法
24.全局注册步骤:
新建子组件:在main中全局注册:在APP.vue中使用:
25.局部组件注册:
第一步同上,然后在别的Vue对象的components中注册就可以使用了。
26,父组件传参数到子组件,子组件用props接收
第一步先在父组件中定义要传递的参数,在这里用msg,然后通过v-bind与子组件定义的props,就可以在子组件取父组件的值了:
-》
27.props的第二种写法:传递string类型,当父组件没传值的时候设置默认值。
28.props的第三种写法:传递方法,注意,传值的话是在子组件传参,也可作为子组件向父组件传值
。。
29.改进子传父:通过事件发射$emit发射,样式 $emit('key','value'),父组件接受@key="用来接收的参数=$event",两个key的名字要保持一致
--
30。用axios发送请求,安装配置的话百度
使用的话在main.js中引入就可以在全局使用了
这是一个点击事件:
调用后端的接口发现报错,原因是跨域问题:
解决:后端配置一下:
@Configuration
public class corsConfig {
private CorsConfiguration buildConfig() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedOrigin("*"); // 1允许任何域名使用
corsConfiguration.addAllowedHeader("*"); // 2允许任何头
corsConfiguration.addAllowedMethod("*"); // 3允许任何方法(post、get等)
return corsConfiguration;
}
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", buildConfig()); // 4
return new CorsFilter(source);
}
}
然后在调用成功。
31.前端传值和后端接值:这种方式的传值是字符串传值,后端用相应的参数去接就可以
32.前端传值和后端接值:这种方式的传值是对象传值,后端得用对象来接:
33.vue路由,在一个vue组件中实现其他组件的切换。
1.首先安装路由模块:
npm install vue-router -s
重新添加依赖
npm install
2.设计路由界面
3.创建静态路由表,在src目录下创建routes.js
4.在main.js引入路由模块使用
5.在App.vue中加入<router-view></router-view>这个标签,用来显示视图
6.创建路由链接和路由视图
34.路由之间的参数传递
设参:通过路由表设置参数
传参:
在目标view中接参:
35.路由之间跳转的方式:
1.通过<router-link to="/xxx">
2.通过js实现路由的跳转
36.vue样式的作用范围
如果在子组件中style不加scope,那么默认会作用到整个页面,而不是当前组件
37.静态文件打包:
默认会从dist中获取静态文件,所以要先npm run build 打包并把静态文件放到dist文件夹下就可以正常读取了。
新项目
38.webPack骨架搭建vue项目
39.安装vue-router,element ui,sass-loader,node-sass
安装路由模块:npm install vue-router --save-dev
安装elementUI:npm i element-ui -S
安装sass加载器:npm install sass-loader node-sass --save-dev
安装axios:略
40.路由:
创建路由界面和在main.js中引入跟之前一样,创建路由表不一样,在router文件夹下创建index.js文件:
41.使用elementui,在main.js中使用
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
42.调用后端并进行路由跳转的时候,注意this声明在axios之外
43.路由嵌套
之前做的页面都是显示在APP.vue的<router-view>标签中,现在做路由嵌套的话就是在父组件内进行路由跳转并显示
首先建立路由页面并修改路由列表
子组件是加载到父组件的children中
然后在父组件需要显示视图的位置加上<router-view>
最后设置路由链接
44.路由重定向
。。。。
45.路由传递参数,之前已经说过怎么传参,现在深入了解一下复杂类型的传参(设参和接参跟之前一样,只有传参改变了)
注意原来的to改为:to,name对应的是路由列表中的name,params对应的是定义的参数
如果传参的类型是一个对象,里边有多个参数的话用下面这两种,复杂类型的传参的话在路由表里不用设参
如果在params中再添加一个name属性,多个参数的话路由列表这样写:
46.钩子函数,在加载完页面后调用后台接口注意this要定义在axios之外
47.路由钩子函数
48.通过session Storage存储登陆状态
在调用登录接口返回成功后用sessionStorage.setIetm(key,value)的方式存储,key和value都是String类型的,用法:在main.js中全局使用,在每次路由跳转的时候都进行判断
如果访问的登录页,看看sessionStorage中是否存储这个值,如果有的话就跳转到主页,没有的话就到登录页,访问的如果是退出的话,就清空sessionStorage中的内容并跳转到
登录页,关闭浏览器后sessionStorage内的东西会自动清空。
49.vuex,解决了sessionStorage的value中不能存放对象的问题。
1.安装npm install vuex --save 然后下载依赖npm install
2.然后在main.js中引入并使用
import ‘Vuex’ from 'vuex'
Vue.use(Vuex)
3.src下创建store目录和index文件。
里边有什么东西呢?注意$对应的是一个实例,之前的话用过this.$router,因为有对应的文件夹router
最后在main.js中全局引入就可以了
50.解决刷新后vuex数据不存在的问题,添加页面刷新时间
修改store中的index
51.最近遇到一个问题:写了一个dialog,里边有一个表格,本来在页面加载的时候把表格加载进去,但是加了v-if之后发现页面加载的时候没有加载表格
通过以下方法可以解决:意思是在页面dom加载完成之后再调用getList方法,getList方法就是获取表格的方法
this.$nextTick(() => {
this.getList()
})
52.vue给form表单元素赋初始值的时候,我是这样放的,this.form.xxx='xxxxx',但是居然发现这样不能双向绑定,请教别人之后才知道这样的话是不被vue的data监听的
应该这样改:
表单:this.$set(this.form, 'factoryCode', '6920')
集合:this.$set(this.multiList[this.index], 'administrationa', departs[0].label)
53.使用watch的时候,监听数组内的对象监听不到,这时候应该使用深度监听,这里的场景是监听所有明细的单价*数量和总数量
54.vue给把对象赋给另一个对象的两种方法
55.数据库行转列的需求,简单来说准备两个list,其中一个list中的key是另一个list中对象的value
<el-table
:data="this.tableData"
height="400px"
max-height="400px"
size="small"
row-class-name="row"
cell-class-name="column"
:highlight-current-row="true"
fit
>
<el-table-column prop="message" label="错误信息" align="center" width="75px"> </el-table-column>
<el-table-column prop="date" label="年月" align="center" width="75px"> </el-table-column>
<el-table-column prop="company" label="分公司" align="center" width="85px"> </el-table-column>
<el-table-column prop="company" label="海信电视" align="center">
<el-table-column prop="company" label="海信电视保内收入" align="center">
<el-table-column
v-for="(item, index) in tableLabel"
:key="index"
:width="item.width"
:label="item.label">
<el-table-column :label="item.labelCode" :prop="item.prop">
</el-table-column>
</el-table-column>
</el-table-column>
</el-table-column>
</el-table>
tableData: [
{ error: '不保修', date: '2018-07-24', sale1: 23.34, company: '北京', sale2: 137597.76, sale3: 137597.76 },
{ error: '', date: '2018-07-24', sale1: 23.34, company: '上海', sale2: 137597.76, sale3: 35394.05 },
{ error: '', date: '2018-07-24', sale1: 23.34, company: '天津', sale2: 137597.76, sale3: 35394.05 },
{ error: '', date: '2018-07-24', sale1: 23.34, company: '济南', sale2: 137597.76, sale3: 35394.05 },
{ error: '', date: '2018-07-24', sale1: 23.34, company: '武汉', sale2: 137597.76, sale3: 35394.05 }
],
tableLabel: [
// { label: '错误信息', '120', prop: 'error' },
// { label: '日期', '100', prop: 'date' },
// { label: '分公司', '100', prop: 'company' },
{ label: '洗衣机', '200', prop: 'sale1', labelCode: '1212' },
{ label: '电视', '200', prop: 'sale2', labelCode: '003323' },
{ label: '空调', '200', prop: 'sale3', labelCode: '7857878' },
],
57.字典值转换
getDictLabel(dictOptions, dictValue) {
if (dictValue !== undefined && dictValue !== '') {
let obj = {}
obj = dictOptions.find(item => item.labelDefault === dictValue)
if (obj) {
return obj.value
} else {
return dictValue
}
} else {
return dictValue
}
},
58.打开新页面方式