vue脚手架
- 一、项目环境配置
- 二、 vue-cli 路由
- 三、路由懒加载、动态组件、keep-alive、自定义指令
- 四、数据
- 五、兄弟组件传值----中央事件总线
- 六、VUEX(同级可以传,跨级 也可以)
- 七、vue逆向传值(子组件向父组件传递数据)
- 八、解决vue跨域的问题
- 九、UI组件的引用
- 十、vue指令
- 十一、配置别名
- 十二、vuex模块化数据管理
- 十三、vue混入
一、项目环境配置
1、安装 node.js
下载地址:https://nodejs.org/en/download/
2、 扩展–修改npm 镜像源
npm i -g cnpm --registry=http://registry.npm.taobao.org
测试:npm config get registry
3、 vue-cli @4
1)10月16日,官方发布消息称Vue-cli 4.0正式版发布
2)安装和vue-cli3.0的是一模一样的,与3.0的脚手架,除了目录发生变化一些,其他的都一样
3)由于近期才推出 企业中还在使用3.0 但是4.0使用方式与3.0相同。
4、 vue-cli @4安装
1)npm install -g @vue/cli (他是全局安装,只装一次就好)
2)vue --version查看版本
3)vue create 项目名
注:选择 default (babel,eslint)
4)cd 项目名
5)npm run serve
5、 单文件组件(通过一个.vue为后缀的文件来完成一个组件的封装)
1)模板在单文件组件中的书写方式
2)js在单文件组件中的书写方式(export default 暴露
)
3)css在单文件组件中的书写方式
<style scoped>
/*scoped 加他是为了 防止定义的名,影响全局的样式(即当前样式只对当前组件生效)*/
</style>
6、组件的创建
1)在src——》compnents文件夹中创建一个×××.vue的文件
2)需要使用自己创建的单文件组件时,在app.vue里进行如下操作:
注:① @ 代表src文件;
② 调用写在components:{ 组件名 };
③使用可以是双标签<组件名></ 组件名>,或者单标签<组件名 />
7、变量、函数的使用
8、便利:v-for 、key的使用
为遍历数组或元素中的唯一标识,增加或删减元素时,通过这个唯一标识key判断是否是之前的元
素,vue会直接对已有的标签进行复用,不会整个的将所有的标签全部重新删除和创建,只会重新渲染
数据,然后再创建新的元素直到数据渲染完为止。(这个唯一标识,因为vue循环就是创建这个 DOM,所以我们给循环加这个唯一标识,让其通过这个唯一标识进行判断:这条数据是新的,还 是旧的,如果是新的,就进行加载;是旧的就使用以前的,不进行渲染,不进行渲染的好处是提 高速度;所以加这个唯一标识符,只会让其渲染新的数据
)而且官方不建议使用下标,因为下标是可能重复的,建议我们使用一个不重复的数据。
注:便利数据,点击隐藏(可以给加动画)
9、在父组件中,使用子组件(在父组件中 引用——》调用——》使用);并且夫组件向子组件中传值(正向传值)。
1)在App.vue里引用、调用、使用 父组件
2)父组件
3)子组件
注:当值是变量的时候,使用v-bind。
10、逆向传值(子组件向父组件中传值)
1)子组件
2)父组件
二、 vue-cli 路由
注:可以把路由封装成一个组件,那个页面,要用,那个页面就引用、调用、使用。
1、一级路由
1)下载路由
npm install --save vue-router
2)引入路由,在src下创建一个router的文件夹用来存放路由
①在router文件夹下创建一个index.js用来配置路由,相当于路由的一个入口
②在index.js中写入如下内容进行路由配置
//引包
import Vue from 'vue'
import Router from 'vue-router'
//引入下面创建的页面
import 文件引入之后起的名字 from '@/pages/页面名.vue'
import 文件引入之后起的名字 from '@/pages/页面名.vue'
//在vue中使用路由
Vue.use(Router);
export default new Router({
routes: [
{name:" ",path:"/地址",component:文件引入之后起的名字},
{name:" ",path:"/地址",component:文件引入之后起的名字},
//重定向
{path:"/*",redirect:"/地址"},
]
})
注:建议使用下面这个方法:
import Vue from "vue";
import Router from "vue-router";
Vue.use(Router);
const router = new Router({
routes:[
//下面使用了 懒加载
{name:" ",path:"/地址",component:() => import("@/pages/单页面名字.vue")}
]
});
export default router;
注:export default导出和export导出的区别
:
①export default
只能导出一个默认模块,这个模块可以匿名(同时这个模块可以时一个变量,也可以是一个函数),然后在文件里引入就好,这样就可以使用了 import 自己起的模块名 from "模块的文件位置"
。
② export 可以导出多个命名模块,所以在导入的时候,要给模块名加{}
;import { 模块名 , 模块名 } from '模块文件位置'
。
3)创建路由页面
src——>pages或者views里写页面
注:需要几个就写几个,一个路由对应一个页面
页面的基本代码:
<template>
<div>
</div>
</template>
<script>
export default {
}
</script>
<style scoped>
</style>
4)在main.js文件中(把路由注入)
//①配置路由器(引用)
import router from '@/router/index.js';
//② 引用
new Vue({
render: h => h(App),
router
}).$mount('#app')
4)使用声明式的展示(例:写App.vue)
<router-link to="/地址">XXX</router-link>配置路由跳转
5)路由出口(那块要显示,就给那块使用;例如:App.vue)
<!-- 路由对应组件的显示 -->
<router-view></router-view>
展示效果如下:
2、二级路由
1)在src——>router——>index.js 里面引用二级路由页面;配置二级路由路径参数中使用 children 配置(在二级路由的地址里,不要加 / )在一级路由里写children。
2)在要显示二级路由的页面进行 路由页面配置
<!-- 设置路由跳转 -->
<router-link to="/home/era">era</router-link>
<router-link to="/home/erb">erb</router-link>
<!-- 设置路由规则 -->
<router-view></router-view>
3)点到二级路由的父级的时候,让其显示二级路由的第一个内容的解决办法
在一级路由的展示 跳转后面加上二级路由的地址
三、路由懒加载、动态组件、keep-alive、自定义指令
1、 路由懒加载
1)概念
①懒加载简单来说就是延迟加载或按需加载,即在需要的时候的时候进行加载。
②为给客户更好的客户体验,首屏组件加载速度更快,解决白屏问题。做的一些项目越来越大。vue打包后的js文件也越来越大,这会是影响加载时间的重要因素。当构建的项目比较大的时候,懒加载可以分割代码块,提高页面的初始加载效率。
2)常用的懒加载方式有两种:即使用vue异步组件懒加载 和 ES中的import
① ES 提出的import(推荐使用)
const 自己定义的模块名 =( )=>import(‘需要加载的模块地址’);
② vue异步组件懒加载-- resolve
主要是使用了Promise.resolve()的异步机制,用require代替了import,实现按需加载
component:resolve=>(require([“引用的组件路径”],resolve))
2、动态组件
1)让多个组件使用同一个挂载点,并动态切换,这就是动态组件。
2)在什么情况下,使用动态组件?
在这个位置,我不知道 具体显示那个组件,而是我们使用一些 逻辑操作的时候。(在当前页面中,需要在多个组件中进行切换的时候,使用动态组件 )
3)使用动态组件,实现标签页:
需要几个标签页,就要创建 几个页面:
<template>
<div>
<!-- 点击的时候,改变变量 -->
<button @click="com='Tapa'">AAA</button>
<button @click="com='Tapb'">BBB</button>
<button @click="com='Tapc'">CCC</button>
<br />
<!-- 动态添加 -->
<component :is="com"></component>
</div>
</template>
<script>
import Tapa from '@/components/tapbar/a.vue';
import Tapb from '@/components/tapbar/b.vue';
import Tapc from '@/components/tapbar/c.vue';
export default {
data() {
return {
//初始一个要显示的页面
com:Tapa
}
},
components:{
Tapa,
Tapb,
Tapc
}
}
</script>
<style scoped>
</style>
3、 keep-alive
1)在上一个demo中我们不停的切换两个标签页的内容时候,会发现在练习我们中选择好的内容,切换路由之后会恢复初始化。
2)也就是说之前的状态丢失。原因是每次切换路由的时候,Vue 都创建了一个新的组件实例
。
3)解决这个问题,我们可以用一个<keep-alive>
元素将其路由出口包裹起来。在切换过程中将状态保留在内存中,防止重复渲染DOM,减少加载时 间及性能消耗,提高用户体验性
4、 自定义指令
除了内置指令外, 用户自定义的指令。
1)局部指令定义:(与data同级)
directives:{
自定义指令的名字:{
自定义指令钩子函数(el){
操作逻辑
}
}
},
注:自定义指令的钩子
①bind:绑定指令到元素上,只执行一次;
②inserted:绑定了指令的元素插入到页面中展示时调用,基本上都是操作这个钩子函数(指的是当前指令绑到页面上,自动生效);
③update:所有组件节点更新时调用;
④componentUpdated:指令所在组件的节点及其子节点全部更新完成后调用;
⑤unbind:解除指令和元素的绑定,只执行一次。
2)实现一个输入框,在页面加载完成之后,光标直接进入
<template>
<div>
<!-- 自定义指令 -->
<input type="text" v-xiao>
</div>
</template>
<script>
export default {
directives:{
xiao:{
inserted(el){
//形参就是 绑定的那个demo元素(focus指的是 获取焦点)
el.focus();
}
}
}
}
</script>
<style scoped>
</style>
四、数据
1、 axios数据交互
1) axios 请求环境配置
①下载axios:
npm install --save axios
②在src文件加下的main.js中添加
import axios from 'axios'
Vue.prototype.axios = axios
③实现网络请求
2)Axios数据请求——综合交互post get请求
·this.axios(utl:‘请求地址’,method:‘请求方式’,data/params:{k:v}).then((ok)=>{})
·使用get发送数据的时候 使用params:{key:val}发送数据
·使用post发送数据需要使用 var param=new URLSearchParams();修改传参方法
·使用param.append(“uname”,“xixi”)添加数据并且使用data发送数据
①get发送数据和请求数据
<template>
<div>
数据请求
<button @click="getfun()">get发送数据</button>
</div>
</template>
<script>
export default {
created() {
// 请求数据
this.axios({
url:"URL",
method:"get"
}).then((ok)=>{
window.console.log(ok.data.data.commentList)
})
},
methods: {
getfun(){
this.axios({
url:"http://localhost:3000/get",
method:"get",
params:{
udata:"哈哈哈"
}
}).then((ok)=>{
window.console.log(ok);
})
}
},
}
</script>
<style scoped>
</style>
②post请求数据和发送数据
<template>
<div>
数据请求
<button @click="postfun()">post发送数据</button>
</div>
</template>
<script>
export default {
created() {
// 请求数据
this.axios({
url:"http://localhost:3000/post",
method:"post"
}).then((ok)=>{
window.console.log(ok)//打印出来 请求的数据
})
},
methods: {
postfun(){
let param=new URLSearchParams();//使用URLSearchParams对 对象进行操作
//使用实例化的这个对象 下的 append这个方法,往里面键值对插入
param.append("udata","哈哈");//后台需要神魔发神魔
this.axios({
url:"http://localhost:3000/post",
method:"post",
data:param
}).then((ok)=>{
window.console.log(ok);
})
}
},
}
</script>
<style scoped>
</style>
2、 mock模拟数据
1)在前端开发过程中,有后台配合是很必要的。但是如果自己测试开发,或者后台很忙,没时间,那么我们需要自己提供或修改接口。
2)npm install --save mockjs
3)在src文件夹下创建相关文件与文件夹
mock——>data里放数据——XXX.json
[
{"name":"哈哈哈"}
]
4)设置请求文件index.js
//引用mockjs
let Mock=require("mockjs")
//调用一下mock这个方法
Mock.mock("/模拟的请求地址","请求方式",require("模拟数据的文件地址(返回i数据)"));
5)在main.js引用mock
//引用mock文件夹
require("./mock");
6)使用(那个页面要用 就在那块写)
//
created() {
this.axios({
url:"/lala",
method:"get"
}).then((ok)=>{
window.console.log(ok);
})
},
五、兄弟组件传值----中央事件总线
1、就是给他俩之上创建一个夫文件,他就是关系他俩的桥梁。
在src/assets/下创建一个xxx.js文件在其中只创建一个新的Vue实例,以后它就承担起了组件之间通信的桥梁了,也就是中央事件总线。
//引入vue
import Vue from "vue";
//暴露一个vue实例
export default new Vue;
2、传值方法(创建出A、B两个组件,要在组件里引入上面这个文件)
1)A组件(发)
<template>
<div>
<p>A组件</p>
<button @click="fun()">点我吧数据传递给B组件</button>
</div>
</template>
<script>
//引用中央事件总线
import Index from '@/assets/index.js'
export default {
data() {
return {
text:"我是a组件传向b的数据"
}
},
methods: {
fun(){
//tong过中央事件总线吧数据抛出
Index.$emit("apao",this.text);
}
},
}
</script>
<style scoped>
</style>
2)B组件(接)
<template>
<div>
{{texta}}
</div>
</template>
<script>
//1引用中央事件总线
import Index from '@/assets/index.js'
export default {
//2zai 组件中创建一个变量,来接受数据
data() {
return {
texta:""
}
},
//3 必须在模板创建完毕这个钩子里 同过vue实例来就接受
mounted() {
Index.$on("apao",(val)=>{
this.texta=val;
})
},
}
</script>
<style scoped>
</style>
六、VUEX(同级可以传,跨级 也可以)
1、vuex是一个状态(数据)管理工具
可以很方便的来解决组件之间的数据传递 因为把数据全部都放到一个仓库中谁用谁用去拿
vuex只能用于单个页面中不同组件(例如兄弟组件)的数据流通。
2、下载vuex
npm install --sava vuex
3、在sec——>store——>store.js 来存放vuex的
Vuex 使用单一状态——用一个对象就包含了全部的应用层级状态。至此它便作为一个“唯一数据源 ”而存在。这也意味着,每个应用将仅仅包含一个 store 实例。
1)创建store实例(他是固定写法)
//引用vue和vuex
import Vue from "vue";
import Vuex from "vuex";
//在vue中使用vuex
Vue.use(Vuex);
//创建vuex的store实例;南无首先 就要暴露(export是导出的意思,因为他要让外部使用)
export let store=new Vuex.Store({
//写xuex的核心属性
})
2)建立关系,在main.js里引入vuex;
//1 引用vuex
//下面是一个结构赋值(对象结构)
import {store} from "@/store/store";//一对大括号的原因是,指定要从其他模块导入的变量名。
new Vue({
render: h => h(App),
//2 调用
store
}).$mount('#app')
4、vuex的核心属性(他们几个都是在store.js里面,并且都是同级)
1)state
①vuex中的数据源state,我们需要保存的数据就保存在这里。(存数据,只能存在它里面 单一数据源);state里面存放的数据是响应式的
,Vue组件从store中读取数据,若是store中的数据发生改变,依赖这个数据的组件也会发生更新;它通过mapState把全局的 state 和 getters 映射到当前组件的 computed 计算属性中
。
//引用vue和vuex
import Vue from "vue";
import Vuex from "vuex";
//在vue中使用vuex
Vue.use(Vuex);
//创建vuex的store实例;南无首先 就要暴露(export是导出的意思,因为他要让外部使用)
export let store=new Vuex.Store({
//核心属性一 state——存数据的
state:{
//数组
arr:[
{name:"小米",age:18},
{name:"小号",age:19},
{name:"小黑",age:12},
{name:"小绿",age:199},
{name:"小黄",age:23}
]
}
})
②那个组件要用,就到它这个里面去取,取值要用到计算属性( computed)
<template>
<div>
{{vuexadata}}
</div>
</template>
<script>
export default {
//获取vuex的数据
computed: {
// 计算属性返回的数据(){
// return 数据(有计算的逻辑)
// }
vuexadata(){
return this.$store.state.arr;
}
},
}
</script>
<style scoped>
</style>
2) Getters
①getters相当于之前组件中学习的计算属性,getters属性主要是对于state中数据的一种过滤;
a、使用场景:在项目开发中,有时候希望对state中的某个属性在多个组件中展示出不同行态(不改变原数据);
b、Getter特性是?
*getters 可以对State进行计算操作,它就是Store的计算属性
*虽然在组件内也可以做计算属性,但是getters 可以在多组件之间复用
*如果一个状态只在一个组件内使用,是可以不用getter
//引用vue和vuex
import Vue from "vue";
import Vuex from "vuex";
//在vue中使用vuex
Vue.use(Vuex);
//创建vuex的store实例;南无首先 就要暴露(export是导出的意思,因为他要让外部使用)
export let store=new Vuex.Store({
//核心属性一 state——存数据的
state:{
//数组
arr:[
{name:"aaaa",age:18},
{name:"小号",age:19},
{name:"小黑",age:112},
{name:"小绿",age:199}
]
},
//vuex中的计算属性
getters:{
//接受state数据作为参数
big(state){
//转成大写
return state.arr[0].name.toUpperCase();
},
small(state){
//转成小写的
return state.arr[0].name.toLowerCase();
},
//显示小于50的数据
xiaofive(state){
//循环过滤数据 ta会得到一个新的内容
let newxiaofive=state.arr.filter((v,i)=>{
// 给一个判断 小于50
if(v.age<50){
//返回给v 然后在赋值给newxiaofive
return v;
}
})
//在一个return 返回给 xiaofive
return newxiaofive;
}
}
})
②那个组件要使用就调用(可以在不同的组件中条用他们,方法一样)
<template>
<div>
aaa
<!-- {{计算属性返回的数据}} -->
{{bigdata}}
{{small}}
{{xiaoyu}}
</div>
</template>
<script>
export default {
//获取vuex的数据
computed: {
// 计算属性返回的数据(){
// return 数据(有计算的逻辑)
// }
bigdata(){
return this.$store.getters.big;
},
small(){
return this.$store.getters.small;
},
xiaoyu(){
return this.$store.getters.xiaofive;
}
},
}
</script>
<style scoped>
</style>
3)mutations
①就是用来修改state中的数据的
;mutations,里面装着一些改变数据方法的集合,就是把处理数据逻辑方法全部放在mutations里面(当触发事件的时候想改变state数据的时候使用mutations);他是响应式的,不会改变原数据
修改操作也是响应式的
//引用vue和vuex
import Vue from "vue";
import Vuex from "vuex";
//在vue中使用vuex
Vue.use(Vuex);
//创建vuex的store实例;南无首先 就要暴露(export是导出的意思,因为他要让外部使用)
export let store=new Vuex.Store({
//核心属性一 state——存数据的
state:{
//数组
arr:[
{name:"aaaa",age:18},
{name:"小号",age:19},
{name:"小黑",age:112},
{name:"小绿",age:199}
]
},
//修改数据,需要在页面中通过this.$store.commit() 调用来修改
mutations:{
updata(state){
//吧aaaa修改成小明
state.arr[0].name="小明"
}
}
})
②在组件
<template>
<div>
aaa
<!-- 计算属性返回的数据 -->
{{vuexadata}}
<button @click="fun()">点我修改数据</button>
</div>
</template>
<script>
export default {
//获取vuex的数据
computed: {
// 计算属性返回的数据(){
// return 数据(有计算的逻辑)
// }
vuexadata(){
return this.$store.state.arr;
}
}
methods: {
//修改数据
fun(){
// 需要调用mutations来进行vuex的数据修改
this.$store.commit("updata");
}
},
}
</script>
<style scoped>
</style>
4)Mutations 提交载荷(Payload)
①组件给Mutations传递一个参数
<template>
<div>
bbb
<button @click="fun('嘿嘿')">点我修改vuex里面的数据</button>
<button @click="funb(3)">点我给年龄+3</button>
</div>
</template>
<script>
export default {
methods: {
// 上面传实参,这里需要一个形参 进行接收
fun(val){
//触发vuex的修改
this.$store.commit("chuandata",val);//直接传过去接好
},
funb(num){
this.$store.commit("agedata",num);
}
},
//使用的是本地存储
created(){
//在页面加载时读取localStorage里的状态信息
if (localStorage.getItem("data")){//data可以自己改
//replaceState替换数据 Object.assign合并对象
this.$store.replaceState(Object.assign({}, this.$store.state,JSON.parse(localStorage.getItem("data"))));
}
//在页面刷新时将vuex里的信息保存到localStorage里
window.addEventListener("beforeunload",()=>{
localStorage.setItem("data",JSON.stringify(this.$store.state));
})
},
}
</script>
<style scoped>
</style>
②src——>store——>store.js
//引用vue和vuex
import Vue from "vue";
import Vuex from "vuex";
//在vue中使用vuex
Vue.use(Vuex);
//创建vuex的store实例;南无首先 就要暴露(export是导出的意思,因为他要让外部使用)
export let store=new Vuex.Store({
//核心属性一 state——存数据的
state:{
//数组
arr:[
{name:"aaaa",age:18},
{name:"小号",age:19},
{name:"小黑",age:112},
{name:"小绿",age:199}
]
},
//修改数据,需要在页面中通过this.$store.commit() 调用来修改
mutations:{
//接受前台的参数 根据发送过来的数据来进行数据的修改 jiu叫 提交载荷 payload
//接收传过来的参数 payload是一个形参,可以随便写,但是建议写payload
chuandata(state,payload){
state.arr[0].name=payload;
},
agedata(state,payload){
//把所有的数据,年龄加前台发过来的
state.arr.forEach((v)=>{ //i (下标这块用不到,所以我们直接不写,写了会报错)
v.age+=padload;
})
}
},
})
但是刷新之后就没有了,解决方法如下:(比如登录状态,他就不能让刷新丢失)它要写在组件里(那个组件传的数据,就写那个组件,也就是在哪修改,在那块进行保存)
//使用的是本地存储
created(){
//在页面加载时读取localStorage里的状态信息
if (localStorage.getItem("data")){//data可以自己改
//replaceState替换数据 Object.assign合并对象(也叫合并数组)
this.$store.replaceState(Object.assign({}, this.$store.state,JSON.parse(localStorage.getItem("data"))));
}
//在页面刷新时将vuex里的信息保存到localStorage里
window.addEventListener("beforeunload",()=>{
localStorage.setItem("data",JSON.stringify(this.$store.state));
})
},
注:他在编写数据的时候,有可能会出错,在开发的时候,可以先注掉它。
5) Actions
以后只要是使用vuex的修改数据,都用的是Actions,而不是 mutation
①Actions 类似于 mutation,但是Actions 提交的是 mutation,而不是直接变更状态。Actions 可以异步操作。
<template>
<div>
<p>使用actions来异步修改数据(今后修改vuex的数据只能用必须用下面这种)</p>
<!-- 1、用户触发函数/事件触发函数 -->
<button @click="fun()">点我异步修改vuex数据</button>
</div>
</template>
<script>
export default {
methods: {
fun(){
// 2、在函数中使用this.$store.dispatch("actions的名字")
this.$store.dispatch("acta");//调一个acta的action
}
},
}
</script>
<style scoped>
</style>
②在src——>store——>store.js里
//引用vue和vuex
import Vue from "vue";
import Vuex from "vuex";
//在vue中使用vuex
Vue.use(Vuex);
//创建vuex的store实例;南无首先 就要暴露(export是导出的意思,因为他要让外部使用)
export let store=new Vuex.Store({
//核心属性一 state——存数据的
state:{
//数组
arr:[
{name:"aaaa",age:18},
{name:"小号",age:19},
{name:"小黑",age:112},
{name:"小绿",age:199}
]
},
//修改数据,需要在页面中通过this.$store.commit() 调用来修改
mutations:{
updata(state){
//吧aaaa修改成小明
state.arr[0].name="小明"
}
},
// 3、在vuex文件中创建actions
actions:{
acta(context){//context 等同与(即就是) this.$store
//4、在actions中调用mutations(this.$stroe.commit("xxxx"))
context.commit("updata")//在这调用mutations里面的修改操作
}
}
})
6)Action同样支持载荷
①在组件或者页面中
<template>
<div>
b_____{{xiaodata}}
<button @click="func()">actions修改操作</button>
<button @click="fund(1)">actions的载荷+1</button>
</div>
</template>
<script>
export default {
computed: {
xiaodata(){
return this.$store.getters.xiaoyu
}
},
methods: {
func(){
this.$store.dispatch("acta");
},
fund(nums){//这块是给年龄加1
this.$store.dispatch('actaTwo',nums)
}
},
}
</script>
<style scoped>
</style>
②在src——>store——>store.js
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
export let store=new Vuex.Store({
state:{
arr:[
{name:"aaaa",age:18},
{name:"小号",age:19},
{name:"小黑",age:112},
{name:"小绿",age:199}
]
},
mutations:{
actiosResive(state){
state.arr[0].name='永远永远'
},
actiosResiveTwo(state,padload){
state.arr.forEach((v)=>{
v.age+=padload;
})
}
},
actions:{
acta(context){
context.commit('actiosResive')
},
actaTwo(context,padload){
context.commit('actiosResiveTwo',padload)
}
}
})
5、vuex的一个小案例(vuex表单双向数据修改 绑定)
1)在组件或者页面
<template>
<div>
<hr>
<p>表单</p>
<!-- 2、操作数据
1)通过事件调用dispatch()来触发一个异步的actions
-->
<!-- 在函数里面传一个event事件对象
5)把state当中的数据绑定给input的value
-->
<input type="text" @input="fun($event)" :value="statetext">
<!-- 1、即读取数据 -->
<p>{{statetext}}</p>
</div>
</template>
<script>
export default {
//1、获取vuex中的text()
computed: {
statetext(){
return this.$store.state.text;
}
},
methods: {
fun(e){
//2)通过dispatch来调用actions并且吧输入框的值传递给actions
this.$store.dispatch("texts",e.target.value)
}
},
}
</script>
<style scoped>
</style>
②在src——>store——>store.js 文件里
//引用vue和vuex
import Vue from "vue";
import Vuex from "vuex";
//在vue中使用vuex
Vue.use(Vuex);
//创建vuex的store实例;南无首先 就要暴露(export是导出的意思,因为他要让外部使用)
export let store=new Vuex.Store({
//核心属性一 state——存数据的
state:{
text:'我是state中的默认数据'
},
mutations:{
//4)创建mutations 修改操作
demomu(state,payload){
state.text=payload;
}
},
actions:{
//3)zai store文件中创建actions
texts(context,payload){
context.commit("demomu",payload);
}
}
})
6、vuex-axios数据请求
1)下载axios
npm install --save axios
2)在store.js中引用axios
import axios from 'axios'
3)actions是异步的,通过payload发送给mutations。
4)在页面的合适位置(可以是用都触发的函数/生命周期触发函数)调用dispath()触发一个actions来进行数据请求。
<template>
<div>
<button @click="fun()">点我请求数据</button>
{{text}}
</div>
</template>
<script>
export default {
methods: {
fun(){
//1、调用action
this.$store.dispatch("axiosdata");
}
},
//5、huo去state里的数据
computed: {
text(){
return this.$store.state.arraxios
}
},
}
</script>
<style scoped>
</style>
②在actions里完成数据请发,然后在发送给mutations。
//引用vue和vuex
import Vue from "vue";
import Vuex from "vuex";
//在vue中使用vuex
Vue.use(Vuex);
//3、引用axios
import axios from "axios"
//创建vuex的store实例;南无首先 就要暴露(export是导出的意思,因为他要让外部使用)
export let store=new Vuex.Store({
//核心属性一 state——存数据的
state:{
arraxios:[]
},
//修改数据,需要在页面中通过this.$store.commit() 调用来修改
mutations:{
//4、创建mutations 修改state里的数据
axiosmu(state,payload){
state.arraxios=payload;
}
},
actions:{
//2、创建一个axios的请求
axiosdata(context){
//完成数据请求
axios({
url:"",//这里是请求地址
method:"get"
}).then((ok)=>{
window.console.log(ok.data.data.commentList);
//发给mutations
context.commit("axiosmu",ok.data.data.commentList);
})
}
}
})
vuex中页面刷新数据丢失问题,(使用H5本地存储的特性)与mutations同级;在那修改,在那块使用)
created () {
//在页面加载时读取localStorage里的状态信息
if (localStorage.getItem("data") ) {
//replaceState替换数据 Object.assign合并对象
this.$store.replaceState(Object.assign({}, this.$store.state,JSON.parse(localStorage.getItem("data"))))
}
//在页面刷新时将vuex里的信息保存到localStorage里
window.addEventListener("beforeunload",()=>{
localStorage.setItem("data",JSON.stringify(this.$store.state))
})
},
七、vue逆向传值(子组件向父组件传递数据)
1、父组件
<template>
<div>
home
<Zi @zipao="fufun"/>
<Zib ref="demob"/>
<button @click="funb()">点我得到zib的内容</button>
</div>
</template>
<script>
import Zi from '@/components/zi'
import Zib from '@/components/zib'
export default {
components:{
Zi,
Zib
},
methods:{
fufun(val){
window.console.log(val)
},
funb(){//text是子组件那,定义出来的
window.console.log(this.$refs.demob.text)
}
}
}
</script>
<style scoped>
</style>
2、子组件(有两种方法)
1)传统写法(推荐使用的)
<template>
<div>
zizizizi
<button @click="fun()">点我逆向传值</button>
</div>
</template>
<script>
export default {
methods:{
fun(){
this.$emit("zipao","我是子组件的数据")
}
}
}
</script>
<style scoped>
</style>
2)ref 这个方法来实现
<template>
<div>
zibbbbbbbbb
</div>
</template>
<script>
export default {
data(){
return{
text:"我是zib的数据"
}
}
}
</script>
<style scoped>
</style>
八、解决vue跨域的问题
vue-cli http-proxy-middleware 代理跨域
cli4 相对于之前的cli 少了配置文件的地方
那么我们就需要自己来进行配置在根路径(根路径与src同级)下创建vue.config.js
注意:当我们添加或者修改这个文件时候必须 重启服务
产生下面的报错,他就产生了跨域:
解决方法
module.exports = {
// 基本路径
publicPath: './', //部署应用包时的基本 URL
outputDir: 'dist', // 输出文件目录
assetsDir: '',//放置生成的静态资源 (js、css、img、fonts) 的 (相对于 outputDir 的) 目录
runtimeCompiler: false, //是否使用包含运行时编译器的 Vue 构建版本。设置为true可以使用template
productionSourceMap: false,//生产环境是否生成 sourceMap 文件
lintOnSave: true,
chainWebpack(config) {
config.resolve.alias
// .set('style', resolve('public/style'))
config.output.filename('js/[name].[hash:16].js');//hash值设置
config.output.chunkFilename('js/[id].[hash:16].js');
// config.output.filename('css/[name].[hash:16].css');//hash值设置
},
configureWebpack: () => {
},
// css相关配置
css: {
// 是否使用css分离插件 ExtractTextPlugin
extract: true,
// 开启 CSS source maps?
sourceMap: false,
// css预设器配置项
loaderOptions: {},
// 启用 CSS modules for all css / pre-processor files.
modules: false
},
parallel: require('os').cpus().length > 1,//是否为 Babel 或 TypeScript 使用 thread-loader
// PWA 插件相关配置
// see https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-pwa
pwa: {},
// webpack-dev-server 相关配置
devServer: {
open: process.platform === 'darwin',
host: '0.0.0.0',
port: 1111, //端口号:自己修改(可以快速修改地址,防止有时候,产生冲突)
https: false,
hotOnly: false,
// 设置代理
proxy: {
'/api': {// /api 顶替了'localhost:3000'这个地址
target: 'http://localhost:3000', //对应自己的接口(后台给你的地址;前面有个地址,改变的是后面的路由的地址; 一般都是服务器(即网址,一般不会改变的)/xxx,)
changeOrigin: true,
ws: true,
pathRewrite: {
'^/api': ''
}
}
},
},
// 第三方插件配置
pluginOptions: {
// ...
}
}
使用:
九、UI组件的引用
1、vantUI
1)下载:
npm i vant -S
2)选择方式三 导入所有组件
把它下面导入的代码粘贴到min.js里
import Vue from 'vue';//这个不要,因为里面都有了
import Vant from 'vant';
import 'vant/lib/index.css';
Vue.use(Vant);
3)需要什么就引入什么(比如危险按钮)
<van-button type="danger">危险按钮</van-button>
2、ElementUI(主写PC端)
1)下载
npm i element-ui -S
2)选择完整引用(在mina.js里粘贴)
import Vue from 'vue'; //这个不要,因为里面都有了
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import App from './App.vue'; //这个也不要,因为里面都有了
Vue.use(ElementUI);
3)那个页面要用,就在那个页面粘贴自己需要的;以下面成功按钮为例:
<el-button type="success">成功按钮</el-button>
3、echarts的使用
官网:https://echarts.apache.org/zh/index.html
1)进入官网——>文档——>教程
注:在实例中查看各种图表
2)下载
npm install --save echarts
3)引用(哪个页面或者组件要用它,就引用它)
import echarts from "echarts";
4)使用
1)在页面或者组件中设置一个容器;
2)在mounetd(创建完成)里面把js代码粘入;
选中不同的图表,进行实验,但是,有些是代码是不变的,具体如下:
<template>
<div>
<div id="main" style="width: 600px;height:400px;"></div>
</div>
</template>
<script>
import echarts from "echarts"
export default {
mounted() {
// 基于准备好的dom,初始化echarts实例
var myChart = echarts.init(document.getElementById('main'));
// 指定图表的配置项和数据
var option = {
这个里面指定图标的样式和数据
};
// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option);
},
}
</script>
<style scoped>
</style>
十、vue指令
1、v-if(v-else)和v-show
注:true是显示,flase是不显示
1)v-if和v-else,他俩是配套使用的
<template>
<div>
<div v-if="isLongin">你好!XXXX</div>
<div v-else>请登录...</div>
</div>
</template>
<script>
export default {
data() {
return {
isLongin:false
}
},
}
</script>
<style scoped>
</style>
2)v-show的使用
<template>
<div>
<div v-show="isLongn">你好!XXXX</div>
<!-- 上面这块是是不显示的 -->
</div>
</template>
<script>
export default {
data() {
return {
isLongin:false
}
},
}
</script>
<style scoped>
</style>
3)他俩的区别:
①v-if是删除和添加DOM元素,它可以进行判断是否加载,减轻服务器压力;
②v-show是调整display的属性,是客户端操作更加流畅。
2、v-for 循环
<template>
<div>
<div v-for="item in arr" :key="item">
<p>{{item}}</p>
</div>
</div>
</template>
<script>
export default {
data() {
return {
arr:[11,29,13,55,46,16,7]
}
},
computed:{
},
}
</script>
<style scoped>
</style>
十一、配置别名
配置别名是为了,在找文件的时候,不用使用相对路径了,直接使用别名加路径就好
1、在项目里创建vue.config.js(与src同级)
// 在这里 配置别名
const path = require('path');
function resolve(dir) {
return path.join(__dirname, dir)
}
module.exports = {
configureWebpack:{
resolve:{
// 在这配置别名(比如@就是src)
alias:{
//在这个里面进行别名的配置
'别名(自己起)':resolve('src/对应自己要配置的文件名'),
}
/*
// 配置它,有些后缀名就可以不写了(在这可以不写,因为它已经配置过了)
extensions:[],
*/
}
}
}
2、使用
import XXX from '自己起的别名下所对应你想要的文件';
十二、vuex模块化数据管理
1、下载vuex
npm install --sava vuex
2、创建数据状态管理文件
在src——>store里创建三个文件:
1)modules里面存放各个页面中要管理的数据
2)getters.js里面放修改的数据,对其进行监听;
3)index.js里面是vuex里面的唯一数据源,共同维护一个state。
3、在mine.js中引用
import Vue from 'vue';
import App from './App.vue';
Vue.config.productionTip = false;
import store from './store';
new Vue({
render: h => h(App),
router,
store
}).$mount('#app')
4、mutations、actions 的使用
1)在store——>index.js里
//在这注入自己写的js
import Vue from 'vue';
import Vuex from 'vuex';
import getters from './getters.js';
import one from "./modules/one.js";
Vue.use(Vuex);
//这块是指 共同维护一个store,并且把他new实例化出来(定义store并注册modules,getters)
const store = new Vuex.Store({
modules:{
one
},
getters//这块是指把getters里面的内容实例化,并且暴露出去
});
export default store;
2)在store——>getters.js里
//他相当于计算属性,对vuex里面state的数据 进行监听变化
const getters = {
//导出,在外面使用的时候,直接使用
modify: state => state.one.modify,
}
export default getters; //在这暴露,在index.js里引用
3)在store——>modules——>one.js
//创建模块,每个模块 都有自己的state/mutation/getter/action
const state = {//state里面也可以 再放一个对象
str:"我是one",
modify:9
}
const mutations = {
Add:(state,num) =>{
//这快是每次给modify 加 1
state.modify = state.modify + num;
}
}
const actions = {
// 这个是修改state里面的数据
change({commit},num){
console.log(num);//这个num是外部传进来的
commit("Add",num);
}
}
export default {
state,
mutations,
actions
}
4)在页面中使用
①读取数据
<template>
<div>
{{oneStr}}
</div>
</template>
<script>
export default {
computed:{
oneStr(){
return this.$store.state.one.str;
},
},
}
</script>
<style scoped>
</style>
②修改数据
<template>
<div>
<button @click="fun()">点我+1</button>
{{figure}}
</div>
</template>
<script>
export default {
computed:{
figure(){
return this.$store.state.one.modify;
},
},
methods:{
fun(){
this.$store.dispatch("change",1);//这块是调用vue里面的方法,并且传一个参数进去
}
}
}
</script>
<style scoped>
</style>
5、getters 的使用
注:这块涉及的比较多,案例参考vue-element-admin,具体用法看
vuex官网。
<template>
<div>
<button @click="fun()">点我+1</button>
{{modify}}
</div>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
computed:{
...mapGetters([
'modify'
])
},
methods:{
fun(){
this.$store.dispatch("change",1);//这块是调用vue里面的方法,并且传一个参数进去
}
}
}
</script>
十三、vue混入
1、在需要的地方创建mixins文件夹
注:如果他是页面的,就常见在页面里,如果是公共的,就创建在src下。
mixins文件夹——>index.js
let practice = {
data() {
return {
num: 10
}
},
methods: {
mixFun() {
console.log("你好");
}
},
}
export { practice };
2、在页面中使用
<template>
<div>
{{num}}
</div>
</template>
<script>
import { practice } from "@/mixins/index.js";
export default {
mixins: [practice]
}
</script>
<style scoped>
</style>