文章目录
- Vue
- 二组件
- 第五章
- es6文件导入出
- 1、导出export
- 组件(component)
- 1、定义
- 2、模块化与组件化
- 3、组件的分类
- 1、非单文件组件
- 非单文件三步骤
- 创建组件标准写法
- 简化写法
- 组件的嵌套
- 非单文件的不足之处
- 2、单文件组件
- vue单文件组件的使用
- 脚手架创建项目
- 重点关注文件
- 3、vue组件
- 第六章
- 1、脚手架
- 1、修改默认配置
- 2、获取文本框内容
- 1、通过dom获取
- 2、通过vue的ref语法
- 3、vue插件
- 1、plugin插件
- 4、scoped样式
- 5、props属性
- 1、子组件在接受父组件参数使用props的三种用法
- 用法1
- 用法2
- 用法3
- 2、父组件向给组件传递参数的写法
- 写法1
- 写法2
- 6、综合练习
- 实现头部功能
- 1、子组件向父组件传递参数
- 2、在向todos数组中添加数据时,每一条数据的id是唯一标识
- 实现底部数据显示
- 当鼠标悬停某一行数据时显示删除按钮
- 全选或者全取消
- 第七章
- 1、localstorage存
- 1、存放普通数据
- 2、存放对象数据
- 3、存放数组
- 2、localstorage取
- **1、取普通数据**
- 2、取数组
- 3、取对象
- 3、移除数据
- 4、监听
- 开启深度监听
- 5、自定义事件
- 6、全局消息总线
- 组件间的传递参数
- 第八章
- 1、全局消息总线
- 2、消息发布与订阅
- 1、使用步骤
- 2、参数传递的方式
- 3、vue服务器代理配置
- 跨域问题
- 4、slot插槽
- 1、默认插槽
- 2、具名插槽
- 5、vuex
- 第一个示例:
- 第九章
- 阶段1:计数器的示例
- **1、标准流程:**
- 2、简化流程
- 3、获取语法
- 4、简化state中属性的方法
- 5、简化Actions中事件的调用
- 6、简化Mutations中函数的调用
- 阶段2:模块化+命名空间
Vue
这是v2版
二组件
第五章
vue组件化 非单文件组件 es6导入、导出语法
单文件组件 单文件组件的基本语法 vue脚手架
es6文件导入出
1、导出export
export:导出作用:用于将当前资源对外暴露,方便其他模块引用方式1:分别暴露//index.js中的代码export let msg="hello,world";export function show(){alert(123);}//在html页面中引入index.js暴露的资源<script type="module">import * as m from './js/index.js'//m就代表index.js文件alert(m.msg);m.show();</script>方式2:统一暴露//index.js中的代码let str = "CNM";let qaq = "555";export { str, qaq }//在html页面中引入index.js暴露的资源<script type="module">import{str,msg} from './js/index.js'//此时就不用.xx来输出了console.log(qaq);</script>方式3:默认暴露//index.js中的代码export default{name:"arjun",show(){console.log("默认暴露");}}//在html页面中引入index.js暴露的资源import * as m1 from './js/index.js'm1.default.show()
组件(component)
1、定义
组件:实现应用中局部功能代码和资源的集合
组件是vue.js最强大的功能之一。组件可以扩展html元素,封装可重用的代码vye组件是页面(html代码,css代码)进行模块化
2、模块化与组件化
在vue应用中,一个页面可能是由多个区域构成,每一个区域可以封装成一个单独的组件每一个组件中就可以包含该区域要使用的html,js,css然后将这些组件组合在一起就可以形成完整的页面如果页面上某一个区域的内容要发生改变,只需要将对应的组件进行替换即可
3、组件的分类
1、非单文件组件
特点:非单文件组件:一个文件包含n个组件所有代码写在一文件中,它的文件名不是vue结尾缺点: 1、模板编写没有提示2、没有构建过程,无法将es6转换成es53、不支持组件的css4、真正开发中几乎不用
非单文件三步骤
创建组件: 1、template用于声明组件页面布局,它的内容写在``之间,它只能有一个根元素2、组件中的数据模型data是一个函数,需要指定在()并且用return声明3、组件中的其他用法:函数、计算属性,过滤器等用法都一样声明组件:var vm = new Vue({el: '#app',//指定的vue容器id名称//二、注册组件components: {//组件名:对应的组件(如果组件名与组件同名,可以省略只写一个)school}应用组件:<div id='app'><!-- 三、使用组件 --><school></school></div>//注意:在非单文件组件中不允许直接闭合<school/>
创建组件标准写法
<body><div id='app'><!-- 三、使用组件 --><myschool></myschool></div><script src='js/vue.js'></script><script>Vue.config.productionTip = false;// 一、定义组件const school = Vue.extend({// 1、指定模板(要显示的html标签)//模板中只能有一个根元素template: `<div><h1>学校信息</h1><h2>学校名称:{{schoolName}}</h2><h2>学校地址:{{address}}</h2> </div>`,// 2、指定组件中的数据模型(组件中的数据是一个函数)data() {return {schoolName: "东京大学",address: "日本"}}})var vm = new Vue({el: '#app',//指定的vue容器id名称//二、注册组件components: {//组件名:对应的组件(如果组件名与组件同名,可以省略只写一个)myschool: school}})</script>
</body>
简化写法
注册组件: const stu = {template: `<div><h1>学生信息</h1><h2>学生姓名:{{name}}</h2><h2>学生成绩:{{score}}</h2> </div>`,// 2、指定组件中的数据模型(组件中的数据是一个函数)data() {return {name: "张三",score: "90"}}}
组件的嵌套
1、先声明子组件const stu = {template: `<div><h1>学生信息</h1><h2>学生姓名:{{name}}</h2><h2>学生成绩:{{score}}</h2> </div>`,// 2、指定组件中的数据模型(组件中的数据是一个函数)data() {return {name: "张三",score: "90"}}}
2、在父组件注册子组件//创建父组件:schoolconst school = {template: `<div><h1>学校信息</h1><h2>学校名称:{{schoolName}}</h2><h2>学校地址:{{address}}</h2><hr> <stu></stu> </div>`,// 2、指定组件中的数据模型(组件中的数据是一个函数)data() {return {schoolName: "东京大学",address: "日本"}},// 在父组件中注册子组件components: {stu}};
非单文件的不足之处
1、它所有的组件包含在一个页面,编写代码并不方便
2、它的模板布局temolate要写在``中,且没有提示
//实际开发很少用到,更多的是单文件组件
2、单文件组件
把一个组件全部内容汇合到一个文件中,文件名字是以.vue结尾
一个组件就是一个独立的*.vue文件,它可以包含自己的js,template,css特点:1、它的后缀是.vue2、它可以将一个区域的内容封装成一个vue组件,该组件包含有:js css html3、将这些组件组合在一起,就可以形成完整的程序
在讲解单文件组件之前,我们首先要学习es6文件的导入、导出语法
vue单文件组件的使用
.vue文件就是一个单文件组件该方法中只能包含三个部分的内容:template:------用于指定模板,该组件的所有html代码都要包含在该区域srcipt:--------用于指定js代码style:---------用于指定组件的所有样式代码
安装插件–>vuter
vue脚手架:Vue CLI
脚手架创建项目
1、创建一个目录(该目录用于保存脚手架创建的项目)2、用cmd命令进入该目录3、执行命令使用脚手架创建项目vue create 项目名称vue create arjun4、当工程创建成功后,使用命令进入项目中cd arjun5、通过npm启动项目npm run serve6、通过返回的地址即可访问vue程序
main.js---------它是vue的入口js文件,vue的实例是在此文件中创建的,要导入各种插件,也需要在改文件中导入
app.vue是一个入口组件,其他组件都要通过它进行加载
重点关注文件
index.html 默认加载的页面
assets 它可以存放一些图片或者是css样式文件
cpmponents 它包含我们自己创建的vue组件
App.vue 它是入口组件,其他的vue组件需要通过它加载
main.js 它是入口js,用于配置vue实例,以及配置各种插件
vue.config.js 它是核心js
3、vue组件
我们自己创建的vue组件要放到components目录下组件名字:1、驼峰命名法2、中间-斜杠要求:1、名字必须采用帕斯卡命名法2、名称要求多个单词组合而成
第六章
1、脚手架
1、修改默认配置
在vue.config.js文件中编写如下代码
const { defineConfig } = require('@vue/cli-service')module.exports = defineConfig({transpileDependencies: true,//忽略语法检查lintOnSave:false
})
2、获取文本框内容
1、通过dom获取
alert(document.getElementById("user").value);
2、通过vue的ref语法
<input type="text" name="user" id="user" ref="msg" />//获取alert(this.$refs.msg.value);
3、vue插件
作用:进行vue功能的增强,实现功能的重复使用例如:我们要在插件中配置一个过滤器,进行日期类型的转换,其他组件要转换日期类型数据时,就不需要重复创建过滤器
1、plugin插件
1、创建Plugins.js 编写如下代码export default{//安装插件 vue是关键字,代表vue实例install(Vue){//在此处,我们可以配置过滤器、自定义指令Vue.filter("showDate",function(time){let date = new Date(time);//分别获得年月日let y = date.getFullYear();let m = (date.getMonth() + 1).toString().padStart(2, "0");let d = date.getDate().toString().padStart(2, "0");return `${y}年${m}月${d}日`;})}}
2、在main.js文件中引入插件,并且使用插件import Vue from 'vue'
import App from './App.vue'
//导入插件
import Plugins from './plugins'Vue.config.productionTip = false//使用插件
Vue.use(Plugins)new Vue({render: h => h(App),
}).$mount('#app')
3、在每一个vue组件,直接使用插件中声明的过滤器即可日期:{{t|showDate}}
牛了个大逼
4、scoped样式
scoped指令样式应用范围:在默认情况下,在每一个vue组件中声明的样式,最终都要在app.vue进行汇总,即使其他组件没有在内部声明样式,在app.vue中汇总的样式,其他组件也是可以用的//注意:在app.vue中声明的样式,所有子组件都可以直接使用
示例:
<style scoped>
/* scoped表示当前样式不在app.vue中进行汇总,只在当前组件中使用
*/.mycss {background: rgba(red, green, blue, 0.3);}
</style>//在app.vue中的<style>标签,不能声明scoped
5、props属性
作用:父组件向子组件传递值
子组件中的代码
<template><div class="mycss"><h1>学生姓名:{{stuname}}</h1><h1>学生成绩:{{score}}</h1></div>
</template><script>
export default {name: "MyStu",//在子组件中,声明要接受的参数//子组件接受到的参数就与在数据模型data中声明的参数效果是一样的props: ["stuname", "score"]
};
父组件中的代码
<template><!-- 此处用于指定html模板代码,只能有一个根元素 --><div>父组件<div class="mycss"><h1>学校名称:{{schoolname}}</h1><h1>学校地址:{{address}}</h1></div><hr />子组件<stu :stuname="'张三'" :score="90" /><stu :stuname="'李四'" :score="100" /></div>
</template><script>
//导入学生组件
import stu from "./stu";//对外暴露的js
export default {//给当前组件指定名称name: "MySchool",//在组件中声明数据模型,必须是函数形式data() {return {schoolname: "千硕教育",address: "珞喻路110号"};},components: {//注册组件stu}
};
</script>
1、子组件在接受父组件参数使用props的三种用法
用法1
最常用
props: ["stuname", "score"]
用法2
//指定参数的数据类型props:{name:String,score:Number,}
用法3
props:{name:{//指定数据类型type:String,//指定参数是必须要的required:true},score:{//指定数据类型type:Number,//指定参数可写可不写,默认值为0default:0},}
2、父组件向给组件传递参数的写法
写法1
//字符串不加:它就表示当前是一个String类型的数据<stu stuname="张三" score="90" /><stu stuname="李四" score="100" />//如果参数是一个字符串类型的数据,前面不加:stuname="张三"//字符串加:表示当前是动态取值<stu :stuname="'张三'" :score="90" /><stu :stuname="'李四'" :score="100" />//如果参数是一个数值类型,就加上::score="99" 它表示动态取到99这个值,赋值给score,系统会把99当成number使 用,两边不用写'':stuname="张三" 它表示动态取到张三这个值,由于张三是一个字符串类型,两边必 须要有''
写法2
如果要动态获取数据模型中的属性值,传递给子组件,必须加:<stu :stuname="stuname" :score="score" />data() {return {schoolname: "千硕教育",address: "珞喻路110号",stuname: "王五",score: "90"};
6、综合练习
实现待办事项的记录
设计知识点:1、vue组件化的使用2、父组件向子组件传递参数3、子组件向父组件传递参数功能:1、待办事项的显示2、待办事项的添加3、待办事项的删除4、待办事项的选择
父组件向子组件传递参数,子组件可以用props接受但是平级不能使用props接受传递过来的参数
实现头部功能
如果是多个组件都要操作的数据,一般可以在父组件app.vue中声明对app.vue中的数据模型操作的函数,也全部在父组件app.vue中声明
1、子组件向父组件传递参数
1、首先在子组件用props声明一个函数,用于接受父组件传递过来的函数2、在子组件触发事件,通过父组件传递过来的函数
2、在向todos数组中添加数据时,每一条数据的id是唯一标识
解决方案1:可以使用系统时间作为数据的id解决方案2、可以使用nanoid这个组件,它可以为每一条数据生成一个唯一标识1、安装nanoidnpm i nanoid2、在当前组件中引入nanoidimport {nanoid} from 'nanoid'3、在函数中使用nanoid给对象属性赋值var todo ={id:nanoid(),title:"xx",done:false}
实现底部数据显示
1、保存显示的所有数据todos数组是在app.vue中,我们需要将父组件的todos传递给myFotter.vue处理//父向子传递参数,我们可以在子组件中声明props属性来接收
当鼠标悬停某一行数据时显示删除按钮
app----------->mylid----------------->myitem(todos数组) (删除事件触发)解决方案:子组件向父组件传递参数,我们可以在父组件中定义事件,然后将这个时间传递给 子组件,子组件接受传递过来的事件后,通过这个事件即可向父组件传递参数首先app传递一个事件----->mylit--------->myitem
全选或者全取消
上同
第七章
localstorage数据本地存储
自定义事件
全局消息总线
消息的发布、订阅
1、localstorage存
localstorage:本地存储作用:用于在本地浏览器中存放用户数据
1、存放普通数据
localstorage.setItem('msg',"普通数据")
2、存放对象数据
//对象let obj={id:1,name:"jack",score:90};//对象不能直接存放到localstorage,必须要转换成字符串类型let msg=JSON.stringify(obj);//存放localstorage.setItem('msg',msg)
3、存放数组
//数组todos: [//任务编号 任务名称 标识是否完成{ id: "1", title: "干饭", done: true },{ id: "2", title: "学习", done: false },{ id: "3", title: "玩游戏", done: false }]//对象不能直接存放到localstorage,必须要转换成字符串类型let msg=JSON.stringify(todos);//存放localstorage.setItem('msg',msg)
2、localstorage取
1、取普通数据
//根据键取值
let msg=localstorage.getItem("msg");
2、取数组
var ary = JSON.parse(localStorage.getItem("todos"));ary.forEach(obj => {console.log(obj.id + "-" + obj.title + "-" + obj.done);});
3、取对象
//如果是对象,则需要解析var obj = JSON.parse(localStorage.getItem("todo"));console.log(obj.id + "-" + obj.title + "-" + obj.done);},
3、移除数据
移除一条数据
localStorage.removeItem("todos");
清空数据
localStorage.clear();
4、监听
//这种监听只能监听到数组中的数据改变,不能检测到数据中的属性
//比如勾中了,但一刷新就会又回到没有勾中状态
watch:{todos() {localStorage.setItem("todos", JSON.stringify(this.todos));}
}
开启深度监听
watch: {//可以监听数据,也能监听属性todos: {deep: true,//开启深度监听handler(todos) {localStorage.setItem("todos", JSON.stringify(todos));}}}
5、自定义事件
作用:通过自定义,可以从子组件向父组件传递参数以前传递参数:父组件需要先把函数传递给子组件,如何子组件调用函数现在传递参数:
1、在父组件中使用子组件,自定义事件名称<!-- 在子组件声明自定义事件 --><stu @aj="get()" />如果aj这个事件被触发了,当前组件就会调用get()这个方法2、在父组件methods中声明函数响应自定义事件,接受子组件传递的参数 、methods: {//子组件触发自定义事件,接受学生传过来的值get(stu) {alert(stu);}}
3、在子组件中触发自定义事件模板:xxx(){this.$emit("自定义事件名", 参数);} 示例:<button type="button" @click="shwoStu()">点击传递</button>methods: {shwoStu() {// 在子组件通过出发自定义事件(同时传递参数)this.$emit("aj", this.stu);}}
4、如果子组件要销毁自定义事件,可以通过下列方式销毁clear_aj() {//取消自定义事件this.$off("aj");}
6、全局消息总线
作用:一种组件间的通信方式,适用于‘任意组件间的通信’
使用步骤:
1、在main.js中安装消息总线new Vue({//将app组件,加载到容器中render: h => h(App),beforeCreate() {//安装全局消息总线,$bus就是当前应用vm,$bus是变量名,可以任意指定Vue.prototype.$bus=this;}}).$mount('#app')
2、组件通过消息总线接受数据哪一个组件要通过消息总线接受数据,就在哪一个组件中绑定自定义事件,并且通过事件的回调函数接受数据一般在mounted钩子函数中,向全局消息总线注册自定义事件,注册的语法是:mounted:(){this.$bus.$on('xxx自定义事件名',回调函数)}
需要注意的是,注册的自定义事件名不能重名,所以一般在当前组件被销毁的钩子函数中会取消,在消息总线中注册的自定义事件//当前组件释放时,也解绑注册的自定义事件名beforeDestroy(){this.$bus.$off("aj");}
3、组件通过消息总线发送数据stu.vue组件通过自定义事件,向school.vue提供数据子组件发送数据this.$bus.$emit("数据接收方注册的自定义事件","参数")示例:methods: {shwoStu() {// 在组件通过消息总线向其他组件传递数据//不论是父子组件,还是平级组件,或者是多级组件,都可以传递this.$bus.$emit("aj", this.stu);}}
组件间的传递参数
1、父向子传递参数:一般使用props接受即可2、子向父转到参数:一般使用自定义事件或者消息总线3、app--->mylist----->myitem :多级组件传递参数,一般建议使用消息总线4、平级组件传递参数:也可以使用消息总线
第八章
全局消息总线的使用
消息的发布与订阅
vue的代理配置
slot插槽
vuex
1、全局消息总线
修改备忘录memo练习
1、在main.js中安装消息总线beforeCreate() {//安装全局消息总线,$bus就是当前应用vm,$bus是变量名,可以任意指定Vue.prototype.$bus=this;}
2、在app.vue中注册事件//编写钩子函数,关联自定义事件,用于接受其他组件mounted() {//在总线中注册自定义事件,如果del触发了,就调用handleDel事件this.$bus.$on("del", this.handleDel);this.$bus.$on("state", this.handleState);}, //编写解绑注册的事件beforeDestroy() {this.$bus.$off("del");this.$bus.$off("state");}
3、在myitem.vue中触发事件<input type="checkbox" @click="changeState(todo.id)" />changeState(id) {//触发自定义事件,传递idthis.$bus.$emit("state", id);}
2、消息发布与订阅
作用:用于任意组件间的数据传递
1、使用步骤
1、在vscode中安装组件 pubsub-js插件npm i pubsub-js
接受消息
2、在需要接受消息的组件中导入 pubsub-jsa、import pubsub from "pubsub-js";b、在methods中编写函数,响应自定义事件getSchool("事件名称",传递过来的值){alter(值)}c、在mounted钩子函数中订阅一个自定义事件this.pid=pubsub.subscribe('自定义事件名称',回调函数)//pid--它是订阅的pid,我们通过pid取消订阅//回调函数是指在methods中声明的函数名称d、在组件关闭时,取消订阅beforeDestroy() {//取消订阅pubsub.unsubscribe(this.pid);}
发布消息
3、在消息发送的组件中,执行操作a、import pubsub from "pubsub-js";b、通过pubsub发送消息,所有订阅了自定义事件的组件,都可以接受到数据pubsub.publish('自定义事件名称',数据)
2、参数传递的方式
1、全局消总线2、消息的订阅与发布//全局消息总线更方便
3、vue服务器代理配置
要实现前后台交互,一般使用axios这个组件,在脚手架项目中一般通过npm在线安装即可1、安装npm i axios 2、在组件中引入 import axios from 'axios';3、通过axios发送请求到后台,加载数据axios.get('请求地址').then(res=>{log(res.data)})
跨域问题
access-Control-Allow-Origin:跨域问题Access to XMLHttpRequest at 'http://localhost:8080/ajax?method=init' from origin 'http://192.168.17.159:8081' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
解决方案:
1、在后台通过cors过滤器即可解决跨域问题(最简单)2、在前台vue.config.js文件中,配置代理服务器也可以解决跨域问题a、 修改配置文件devServer: {proxy: 'http://localhost:8099/'//proxy:代理//当前台程序访问vue脚手架的默认8080端口时,//代理服务器自动代理成8099的端口访问后台程序//http://localhost:8099---这个端口号是后台服务器的端口号}b、在axios发送请求时,请求vue的默认8080端口//此时,只需要请求vue默认的8080端口即可//因为8080端口会自动被代理成8099端口访问后台axios.get("http://localhost:8080/ajax", {params: { method: "init" }}).then(item => {//请求成功时,执行的回调函数this.list = item.data;})c、修改配置文件需要重新启动
备注
如果开启了前台代理服务器,那么请求地址就填前台默认8080端口如果开启了后台代理服务器,那么请求地址还是填后台服务器地址
4、slot插槽
slot插槽:其实就是一个组件中的占位符,通过插槽可以将内容放在指定的区域
1、默认插槽
a、 在子组件可以声明一个默认插槽<slot></slot>b、在父组件中使用子组件,在子组件两个标签之间的内容就是赋值给子组件默认插槽的内容<子组件>这里的内容,就是赋值给子组件默认插槽中的内容</子组件>
示例:
//在app.vue中,向同一个组件中放入不同的控件<slott title="美食"><img src="index.jpg" alt srcset /></slott><slott title="书籍" :books="books"><ul><li v-for="(item,index) in books" :key="index">{{item}}</li></ul></slott><slott title="电影"><video controls loop src="./assets/11.mp4"></video></slott>//在slott.vue中放入插槽<h3>{{title}}档口</h3><slot></slot>
问题
一个组件只能默认只能有一个插槽,如果需要使用多个插槽,我们可以使用“具名插槽”
2、具名插槽
【具名插槽】:在子组件声明插槽时,给每一个插槽之地名称。在父组件中使用子组件时,就明确指定是给子组件的哪一个插槽赋值a、在子组件中声明插槽<slot name=center></slot><slot name=footer></slot>b、在父组件中给子组件的指定插槽赋值<子组件><div slot="center">xxx</div><a slot="footer">xxx</a></子组件>
示例:
1、在slot.vuue中声明插槽的名字<div class="mydiv"><h3>{{title}}档口</h3><slot name="conter"></slot><slot name="footer"></slot></div>2、在app.vue中指定给哪一个插槽赋值<slott title="美食"><img slot="conter" src="index.jpg" alt srcset /><ul slot="footer"><li v-for="(item,index) in foods" :key="index"><a href="#">{{item}}</a></li></ul></slott><slott title="书籍"><ul slot="conter"><li v-for="(item,index) in books" :key="index">{{item}}</li></ul></slott><slott title="电影"><video slot="conter" controls loop src="718.mp4"></video><ul slot="footer"><li v-for="(item,index) in films" :key="index"><a href="#">{{item}}</a></li></ul></slott>
5、vuex
作用:是专门在vue中实现集中式数据(状态)管理的vue插件,对vue应用中多个组件的共享数据进行集中式的管理(读、写),也是一种组件间通信的方式,且适用任意组件间的通信
主要作用:将多个组件都要使用的数据,进行集中管理
使用场景:
1、多个组件都要使用同一条数据2、多个组件会修改同一条数据的状态当数据存储在vuex中,所有组件都可以直接访问这里面的数据,并且允许直接操作这些数据
第一个示例:
1、安装vuexnpm i vuex ---->vuex4.0--->vue3.0npm i vuex@3 --->vuex3.0---->vue2.02、main.js引入vuex//导入import vuex from 'vuex'//使用Vue.use(vuex)3、测试vuex是否成功a、在main.js中编写一个变量new Vue({render: h => h(App),store: "测试",//变量}}).$mount('#app')b、随便打开一个vue文件mounted() {console.log(this);//输出这个实例,如果有store这个变量即为成功}
第九章
vuex的使用
route路由的使用
阶段1:计数器的示例
通过一个计数器的示例,演示在vuex中可以包含哪些属性,以及如何直接操作vuex的数据v-model.number:指定绑定数据类型
步骤:
1、搭建计算器应用的基本结构,暂时与vuex没有关系目前:sum这个变量用于统计总和,它存在当前Counter组件中,只有Counter组件才能使用,其他组件无法直接使用2、在main.js文件导入vuex,并且使用vuex插件import Vuex from 'vuex'Vue.use(Vuex);3、在src目录下,创建一个store目录,在目录中包含一个index.js文件,该方法中包含vuex存放的内容4、在store目录下的index.js文件中需要包含下列三个配置:1、actions------------它用于包含vuex中的事件2、mutations----------它用于操作state中的数据3、state--------------它用于在vuex中指定全局共享数据//引Vueimport Vue from 'vue'//引入vueximport Vuex from 'vuex'//声明三个对象//它用于指定vuex中的所有事件,这些事件所有组件都可以直接访问const actions={};//mutations声明的函数,可以直接操作state存放的全局数据,所有组件可以直接访问这里的函数const mutations={//这里可以直接state中的数据};//state中声明的数据,所有组件都可以直接访问const state ={};//先使用Vuex,然后再通过它创建Store实例Vue.use(Vuex);//创建store实例,实例中包含的对象,所有组件都可以直接访问const store = new Vuex.Store({actions,mutations,state});//将store实例对外暴露 export default store;5、在main.js文件中导入store对象,并且将store存放到vuex中,即可所有组件全局共享//导入storeimport store from './store/index'new Vue({render: h => h(App),//将数据存放到vuex中store:store}).$mount('#app')6、使用vuex组件store目录下的index.js文件中可以包含三个对象actions--------用于指定所有组件共享的函数mutations------用于指定函数操作state对象中存放的数据state----------用于存放全局所有组件共享的数据如果希望所有组件都可以直接共享访问的数据放在store/index.js中的state部分即可a、访问 vuex中state对象中存放的数据,可以采用如下方式{{$store.state.属性名}}//当使用了vuex以后,每一个组件都存在一个$store实例,通过可以直接访问vuex中声明的函数,以及存放的数据b、在组件中要访问 index.js文件中actions声明的函数,需要通过如下访问this.$store.dispatch("actions中声明的函数名",要传递的参数);
注意:
@@@@@Actions中声明的函数不能直接操作state中的数据,需要通过Mutations的函数进行过渡组件--->actions--->mutations--->state在组件中通过下列方式可以直接访问actions中的函数 this.$store.dispatch("actions中的函数",参数);actions的函数中访问mutations中的函数//在actions中声明的函数名称,名称全部小写jia(context,参数){context.commit("mutations中的函数名",参数);}@@@@@@在mutations中只需要编写下列代码即可修改state中的数据const mutations={//这里可以直接修改state中的数据//在mutations中声明的函数名称,名称全部大写//参数1:即为state对象//参数2:即为传递进来的具体参数JIA(state,value){state.sum +=value;}};
1、标准流程:
组件—>actions—>mutations—>state
1、在counter.vue中调用index.js函数<h1>计算结果:{{ $store.state.sum }}</h1><button @click="add()">加【{{ n }}】</button>//触发add() {//+this.$store.dispatch("jia", this.n);}2、index.js中的流程a、进入到jia()事件---->actionsjia(context, val) {//测试事件//提交JIA()函数处理context.commit("JIA", val);}b、进到JIA()函数处理数据---->mutationsJIA(state, val) {state.sum += val;}c、state的数据发生改变const state = {sum: 0, //计算结果}
2、简化流程
组件—>mutations—>state
//组件不需要做逻辑判断,则可以直接访问函数来修改数据
//如果需要逻辑判断,则必须先进到逻辑判断中add(){直接访问JIA()函数this.$store.commit("JIA", this.n);}
3、获取语法
/在组件中从store对象中的state中获得属性值的标准语法{{$store.state.属性名}}/在组件中访问store中Actions对象的中的函数标准语法:this.$store.dispatch("函数名",参数);/在组件中访问store中mutations对象的中的函数标准语法:this.$store.commit("函数名",参数);
4、简化state中属性的方法
@@@1、每一次访问state中的属性,如果采用下列写法比较繁琐:{{$store.state.属性名}}
简化方式:我们可以将state中的属性,映射成当前组件的计算属性步骤:1、在组件中引入mapStatemapState的作用是将index.js中的state属性映射成计算属性import { mapState } from 'vuex';2、将index.js中的state属性映射成计算属性@@@@方式1computed:{...mapState({sum:'sum',id:'id',name:'name',score:'score'})}@@@@方式2computed:{...mapState(['sum','id','name','score'])}3、取值时使用别名即可编号:{{id}} <BR/>姓名:{{name}}<BR/>成绩:{{score}}<BR/>
5、简化Actions中事件的调用
之前在组件要调用actions中的函数,格式如下: this.$store.dispatch("evenAdd",this.n);简化步骤:1、在组件导入mapActionsimport { mapState,mapActions } from 'vuex';2、在methods中进行映射方式1:methods:{...mapActions({evenAdd:'evenAdd'})}方式2:methods:{...mapActions(['evenAdd'])}3、使用简化后事件<input type="button" value="当n的值为偶数再加" @click="evenAdd(n)">
6、简化Mutations中函数的调用
之前在组件要调用mutations中的函数,格式如下:this.$store.commit("JIA",this.n);简化步骤:
1、在组件导入mapMutationsimport { mapState,mapActions,mapMutations } from 'vuex';2、在methods中进行映射方式1:methods:{...mapMutations({JIA:'JIA',JIAN:'JIAN'}),}方式2:methods:{...mapMutations(['JIA','JIAN']),}3、使用简化后函数<input type="button" value="加" @click="JIA(n)"><input type="button" value="减" @click="JIAN(n)">
问题:
为了实现数据共享访问,我们使用了vuex,actions,mutations,state都在同一个文件中编写,当数据很多时,代码会变的比较混乱,为了解决该问题,我们可以在index.js文件中使用模块化的组件
阶段2:模块化+命名空间
@@@@@@模块化开发的目的:让代码更好维护
步骤:
1、在 index.js文件中,创建多个模块,一个模块对应的一个组件的配置@@@注意:每一个模块必须要指定:namespaced -------命名空间@@@每一个模块可以包含自己的 actions,mutations,state//新建模块 const counter = {namespaced: true,actions: {//如果n的值为偶数,才执行加法evenAdd(context, n) {if (n % 2 == 0) {context.commit("EVENADD", n);}}},mutations: {JIA(state, value) {state.sum += value;},JIAN(state, value) {state.sum -= value;},EVENADD(state, value) {state.sum += value;}},state: {sum: 5, //保存总和}};const person = {namespaced: true,state: {id: 1,//编号name: "张三",//姓名score: 99,//分数}};2、在index.js的store对象中加载模块//创建store实例,实例中包含的对象,所有组件都可以直接访问const store = new Vuex.Store({modules:{person,counter}});3、在组件中映射时,要分别指定:actions,mutations,state是从哪一个模块中加载
@@@@@@@@模块化开发,一个模块就是一个独立的 js文件
1、先创建counter.js,person.js2、在index.js文件中引入import counter from './counter'import person from './person'3、使用模块const store = new Vuex.Store({modules:{person,counter}});