【Vue 2.x】学习vue之二组件

news2024/11/23 5:00:46

在这里插入图片描述

文章目录

  • 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代码)进行模块化

image-20230516200318145

2、模块化与组件化
在vue应用中,一个页面可能是由多个区域构成,每一个区域可以封装成一个单独的组件

每一个组件中就可以包含该区域要使用的html,js,css

然后将这些组件组合在一起就可以形成完整的页面

如果页面上某一个区域的内容要发生改变,只需要将对应的组件进行替换即可

3、组件的分类
1、非单文件组件
特点:非单文件组件:一个文件包含n个组件
	  所有代码写在一文件中,它的文件名不是vue结尾

缺点:	1、模板编写没有提示
	  2、没有构建过程,无法将es6转换成es5
	  3、不支持组件的css
	  4、真正开发中几乎不用
非单文件三步骤
创建组件:    
	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、在父组件注册子组件
        //创建父组件:school
        const 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、它的后缀是.vue
	 2、它可以将一个区域的内容封装成一个vue组件,该组件包含有:js css html
	 3、将这些组件组合在一起,就可以形成完整的程序

在讲解单文件组件之前,我们首先要学习es6文件的导入、导出语法

vue单文件组件的使用
.vue文件就是一个单文件组件
	该方法中只能包含三个部分的内容:
		template:------用于指定模板,该组件的所有html代码都要包含在该区域
		srcipt:--------用于指定js代码
		style:---------用于指定组件的所有样式代码

安装插件–>vuter

vue脚手架:Vue CLI

脚手架创建项目
1、创建一个目录(该目录用于保存脚手架创建的项目)

2、用cmd命令进入该目录

3、执行命令使用脚手架创建项目
	vue  create	  项目名称
	vue  create   arjun
	
4、当工程创建成功后,使用命令进入项目中
	cd arjun

5、通过npm启动项目
	npm run serve

6、通过返回的地址即可访问vue程序

image-20230517174220127

main.js---------它是vue的入口js文件,vue的实例是在此文件中创建的,要导入各种插件,也需要在改文件中导入

image-20230517175621085

app.vue是一个入口组件,其他组件都要通过它进行加载

image-20230517180340211

image-20230517180509165

重点关注文件
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、脚手架

image-20230518163857299

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,
			//指定参数可写可不写,默认值为0
			default: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、待办事项的选择	

image-20230518221005902

在这里插入图片描述

父组件向子组件传递参数,子组件可以用props接受

但是平级不能使用props接受传递过来的参数
实现头部功能

image-20230518230945734

如果是多个组件都要操作的数据,一般可以在父组件app.vue中声明

对app.vue中的数据模型操作的函数,也全部在父组件app.vue中声明
1、子组件向父组件传递参数
1、首先在子组件用props声明一个函数,用于接受父组件传递过来的函数

2、在子组件触发事件,通过父组件传递过来的函数
2、在向todos数组中添加数据时,每一条数据的id是唯一标识
解决方案1:可以使用系统时间作为数据的id

解决方案2、可以使用nanoid这个组件,它可以为每一条数据生成一个唯一标识
	
		1、安装nanoid
				npm i nanoid
		2、在当前组件中引入nanoid
				import {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) {
	//触发自定义事件,传递id
      this.$bus.$emit("state", id);
    }

2、消息发布与订阅

作用:用于任意组件间的数据传递
1、使用步骤
1、在vscode中安装组件 pubsub-js插件
		npm i  pubsub-js

接受消息

2、在需要接受消息的组件中导入  pubsub-js
		a、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中,所有组件都可以直接访问这里面的数据,并且允许直接操作这些数据

image-20230522185348801

第一个示例:
1、安装vuex
	npm i vuex ---->vuex4.0--->vue3.0
	
	npm i  vuex@3 --->vuex3.0---->vue2.0

2、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这个变量即为成功
      }

image-20230522192133138

第九章

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中指定全局共享数据



	//引Vue
	import Vue from 'vue'

	//引入vuex
	import 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中,即可所有组件全局共享

	//导入store
	import 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()事件---->actions
         jia(context, val) {//测试事件
            //提交JIA()函数处理
            context.commit("JIA", val);
         }
    b、进到JIA()函数处理数据---->mutations
    	    JIA(state, val) {
                state.sum += val;
            }
    c、state的数据发生改变
    		const state = {
                sum: 0, //计算结果
            }

image-20230523104354730

image-20230523105534825

2、简化流程

​ 组件—>mutations—>state

//组件不需要做逻辑判断,则可以直接访问函数来修改数据
//如果需要逻辑判断,则必须先进到逻辑判断中
	add(){
		直接访问JIA()函数
		  this.$store.commit("JIA", this.n);
	}

image-20230523110618282

3、获取语法
/在组件中从store对象中的state中获得属性值的标准语法
	{{$store.state.属性名}}

/在组件中访问store中Actions对象的中的函数标准语法:
	this.$store.dispatch("函数名",参数);

/在组件中访问store中mutations对象的中的函数标准语法:
	this.$store.commit("函数名",参数);

4、简化state中属性的方法
@@@1、每一次访问state中的属性,如果采用下列写法比较繁琐:{{$store.state.属性名}}
简化方式:我们可以将state中的属性,映射成当前组件的计算属性

步骤:
	1、在组件中引入mapState
		mapState的作用是将index.js中的state属性映射成计算属性
		import { mapState } from 'vuex';

	2、将index.js中的state属性映射成计算属性
	    @@@@方式1
	    computed:{
		...mapState({sum:'sum',id:'id',name:'name',score:'score'})
	    }
	    @@@@方式2
	    computed:{
		...mapState(['sum','id','name','score'])
	    }

	3、取值时使用别名即可
		编号:{{id}} <BR/>
		姓名:{{name}}<BR/>
		成绩:{{score}}<BR/>
5、简化Actions中事件的调用
之前在组件要调用actions中的函数,格式如下: this.$store.dispatch("evenAdd",this.n);

简化步骤:

1、在组件导入mapActions
	import { mapState,mapActions } from 'vuex';

2、在methods中进行映射
	方式1methods:{
			...mapActions({evenAdd:'evenAdd'})
		}
	方式2methods:{
			...mapActions(['evenAdd'])
		}

3、使用简化后事件
	<input type="button" value="当n的值为偶数再加" @click="evenAdd(n)">
6、简化Mutations中函数的调用
之前在组件要调用mutations中的函数,格式如下:
	this.$store.commit("JIA",this.n);


简化步骤:
1、在组件导入mapMutations
	import { mapState,mapActions,mapMutations } from 'vuex';

2、在methods中进行映射

	方式1methods:{
			...mapMutations({JIA:'JIA',JIAN:'JIAN'}),
		}
	方式2methods:{
			...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.js

2、在index.js文件中引入

	import counter from './counter'
	import person from './person'

3、使用模块
	const store = new Vuex.Store({
	    modules:{
		person,counter
	    }
	});

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1638431.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

(学习日记)2024.05.09:UCOSIII第六十三节:常用的结构体(os.h文件)第二部分

之前的章节都是针对某个或某些知识点进行的专项讲解&#xff0c;重点在功能和代码解释。 回到最初开始学μC/OS-III系统时&#xff0c;当时就定下了一个目标&#xff0c;不仅要读懂&#xff0c;还要读透&#xff0c;改造成更适合中国宝宝体质的使用方式。在学完野火的教程后&a…

【JavaEE】线程的概念

文章目录 1、什么是线程2、进程和线程的区别3、多线程的概述4、在Java中实现多线程的方法1.继承Thread类2.实现Runnable接口3.使用匿名内部类来继承Thread类&#xff0c;实现run方法4.使用匿名内部类来实现Runnable接口&#xff0c;实现run方法5.使用 lambda表达式 1、什么是线…

018、Python+fastapi,第一个Python项目走向第18步:ubuntu24.04 安装cuda和pytorch环境

一、说明 我们安装了pytorch环境之后&#xff0c;会用yolo v9 来测试一下&#xff0c;看8g 显存能不能跑下来&#xff0c;上次用无影云电脑&#xff0c;4cpu8g内存直接爆了&#xff0c;云电脑也死机了&#xff0c;提示一直占用内存不释放&#xff0c;我自己的云电脑不能占用内…

基于alpha shapes的边缘点提取(matlab)

1、原理介绍 由Edelsbrunner H提出的alpha shapes算法是一种简单、有效的快速提取边界点算法。其克服了点云边界点形状影响的缺点&#xff0c;可快速准确提取边界点。如下图所示&#xff0c;对于任意形状的平面点云&#xff0c;若一个半径为a的圆&#xff0c;绕其进行滚动&…

类加载子系统之类的生命周期(待完善)

0、前言 文中大量图片来源于 B站 黑马程序员 0.1、类加载子系统在 JVM 中的位置 类加载器负责的事情是&#xff1a;加载、链接、解析 0.2、与类的生命周期相关的虚拟机参数 参数描述-XX:TraceClassLoading打印出加载且初始化的类 1、类的生命周期 堆上的变量在分配空间的时…

如何基于nginx搭建https网站

华子目录 使用nginx的http_ssl模块建立加密传输的网站查看配置文件ssl配置文件的主要参数实验&#xff1a;搭建nginxssl加密认证的web服务器 使用nginx的http_ssl模块建立加密传输的网站 查看 [rootserver ~]# nginx -V #查看是否有--with-http_ssl_module模块&#xff0c;如…

2024五一杯:煤矿深部开采冲击地压危险预测 (详细完整思路,已修改)

背景 了解即可 煤炭是中国的主要能源和重要的工业原料。然而&#xff0c;随着开采深度的增加&#xff0c;地应力增大&#xff0c;井下煤岩动力灾害风险越来越大&#xff0c;严重影响着煤矿的安全高效开采。在各类深部煤岩动力灾害事故中&#xff0c;冲击地压已成为威胁中国煤矿…

BigKey的危害

1.2.1、BigKey的危害 网络阻塞 对BigKey执行读请求时&#xff0c;少量的QPS就可能导致带宽使用率被占满&#xff0c;导致Redis实例&#xff0c;乃至所在物理机变慢 数据倾斜 BigKey所在的Redis实例内存使用率远超其他实例&#xff0c;无法使数据分片的内存资源达到均衡 Redis阻…

Vue---router实现路由跳转

Vue—router实现路由跳转 目录 Vue---router实现路由跳转基本使用路由跳转html实现路由跳转JS实现路由跳转 基本使用 所谓路由&#xff0c;就是将一个个组件映射到不同的路由url中 首先要将App内的内容换成router-view // App.vue <template><div id"app"…

商务谈判技巧与口才训练方法(3篇)

商务谈判技巧与口才训练方法&#xff08;3篇&#xff09; 商务谈判技巧与口才训练方法&#xff08;**篇&#xff09;&#xff1a;技巧篇 一、商务谈判技巧 明确目标&#xff1a;在谈判前&#xff0c;明确自己的谈判目标&#xff0c;并设定好底线和期望的谈判结果。 知己知彼…

AIGC技术:现状剖析与未来趋势展望

AIGC技术&#xff1a;现状剖析与未来趋势展望 随着科技的飞速进步&#xff0c;人工智能已经逐渐渗透到我们生活的方方面面。其中&#xff0c;AIGC&#xff08;人工智能生成内容&#xff09;技术更是以其独特的魅力和巨大的潜力&#xff0c;引起了业界的广泛关注。本文将深入探…

vue处理查询框清除后无法查询问题,举例为日期选择

例如 在对应的查询方法添加 //我这里获取的是date&#xff0c;如果是其他参数改为其他的即可 if (query.date && query.date.length > 2) {conditions.noedate query.date[0] || conditions.noedate;//获取开始时间conditions.twodate query.date[1] || conditi…

IDEA 开发找到 java-web 发布到 tomcat 的路径

使用 IDEA 开发 java web 应用&#xff0c;有没有遇到需要找到 tomcat 路径的问题 为什么要找 tomcat 路径呢&#xff1f; 拿我的项目来举例&#xff0c;有统一的线上线下 logback.xml 配置&#xff0c;配置时业务、框架日志输出到 file&#xff0c;少量的启动日志输出到 con…

Java进阶-Java Stream API详解与使用

本文全面介绍了 Java Stream API 的概念、功能以及如何在 Java 中有效地使用它进行集合和数据流的处理。通过详细解释和示例&#xff0c;文章展示了 Java Stream API 在简化代码、提高效率以及支持函数式编程方面的优势。文中还比较了 Java Stream API 与其他集合处理库的异同&…

分类预测 | MATLAB实现LSSVM最小二乘支持向量机多分类预测

分类预测 | MATLAB实现LSSVM最小二乘支持向量机多分类预测 目录 分类预测 | MATLAB实现LSSVM最小二乘支持向量机多分类预测分类效果基本介绍程序设计参考资料分类效果 基本介绍 MATLAB实现LSSVM最小二乘支持向量机多分类预测。最小二乘支持向量机(Least Squares Support Vecto…

数据结构学习/复习1--时间复杂度计算/异或的几个实际用途

一、什么是数据结构和算法 1注&#xff1a;在内存中的存储管理数据 2注&#xff1a;解决问题的方法 二、时间复杂度 1.算法的效率 2.时间复杂度的概念 计算时间复杂度案例1&#xff1a; 计算时间复杂度案例2&#xff1a; 计算时间复杂度案例3&#xff1a; 计算…

如何将本地Android studio项目上传到GitHub

操作步骤&#xff1a; 1、在GitHub上创建账户 2、在androd studio中添加上述创建的GitHub账号 3、在android studio上找到"share project on GitHub"&#xff0c;点击此选项上传当前项目到GitHub 上传成功后&#xff0c;会在GitHub上创建默认仓库repository 注&a…

【R语言数据分析】基本运算与数据导入速查

R语言中命名可以包含英文字母&#xff0c;下划线&#xff0c;数字&#xff0c;点&#xff0c;下划线和数字不能作为名字的开头&#xff0c;点可以开头&#xff0c;但是点开头后面不能跟数字。一般的命名就是只使用英文和下划线就够了。 四则运算 R语言的除法是即使给的两个数…

常用算法代码模板 (2) :数据结构

AcWing算法基础课笔记与常用算法模板 (2) ——数据结构 常用算法代码模板 (1) &#xff1a;基础算法 常用算法代码模板 (2) &#xff1a;数据结构 常用算法代码模板 (3) &#xff1a;搜索与图论 常用算法代码模板 (4) &#xff1a;数学知识 算法基础课 动态规划模板题笔记 算法…

857.雇佣K名工人的最低成本

题目说的其实是有点乱的,所以我们可能抓不住重点,甚至都不太清楚规则,比如 eg. quality[3,1,10,10,1] wage[4,8,200,200,7] 这里是选下标0,1,4 ->单价为8 但是想清楚其实就很easy. 就是 贪心(sort) 优先队列 梳理下我们发现其实要让每个人得到最低期望,就要按照当前最贵…