zl程序教程

您现在的位置是:首页 >  前端

当前栏目

【Vue 快速入门系列】ref、props、mixin、插件使用、样式混合解决方案合集

Vue入门插件解决方案 快速 系列 样式 混合
2023-09-27 14:20:14 时间

前言


在前面介绍到了Vue的一些基本概念与如何使用Vue,并通过node中的npm 使用vue脚手架(vue-cli)搭建了一个简单的Vue应用,其实所有的Vue项目搭建的时候都是换汤不换药。今天将会介绍几个Vue中常用的配置,他们的大致功能如下:

  • ref 作用是将dom元素选择出来,对普通标签来说与document.getElementById(“xxx”)是一回事,对自定义组件来说会将Vue Componentd对象选择出来,获取到VC对象也就可以获取到其中的dom元素了。
  • props 作用是父组件向子组件传递数据(当父组件有更新的时候子组件也会有更新)
  • mixin 将组件公共部分提取出来,哪里用到就在哪里引用
  • 插件 别人写好的js文件,我们只需引入并use即可(这里要区分好组件与插件)
  • 样式混合 如果给组件的style不加scoped将会导致样式的混乱

有了大概的预览之后就可以进行深一步的学习了,将会配合一些代码实例进行叙述。

一、ref属性的使用

大家在学习css的时候学过各种选择器,也学过使用css选择器将dom元素选择出来,这个属性的话起到的作用就是将想要的dom元素选择出来,根据ref属性可以很轻松的找到dom元素。

  1. 被用来给元素或子组件注册引用信息(可以认为是id的替代者)
  2. 标记在html标签上可以获取真实DOM元素
  3. 标记在组件标签上可以获取组件实例对象(vc)
  4. 一句实例对象可以进行自己想要的操作
  5. 使用方式:
    1. 给元素打标识:
      ①. <h1 ref="xxx">.....</h1>
      ②. <School ref="xxx"></School>
      ③. <School :ref="xxx"></School>
    2. 获取元素:this.$refs.xxx

结合以下实例代码:
App.vue

<template>
<template>
  <div>
      <h2 ref="title">Hello World</h2>
      <Student ref="stu"></Student>
      <button @click="showInfo">点我体验ref</button>
  </div>
</template>

<script>
import Student from "./components/Student.vue"
export default {
    name:"App",
    components:{
        Student
    },
    methods:{
        showInfo(){
            // 打印这个vc对象中的模板中的ref有几个
            // {title: h2, stu: VueComponent}
            console.log(this.$refs)
            // 打印一下ref中的h2  title是什么样的
            // <h2>Hello World</h2>
            console.log(this.$refs.title)
            // 打印一下ref中的vc是什么样的
            // 直接将School组件对象实例打印了出来
            console.log(this.$refs.stu)
            //修改ref.title中的内容
            this.$refs.title.innerHTML="hehehe"
        }
    }
}
</script>

<style>

</style>

Student.vue

<template>
  <div class="demo">
      <h2 >我的名字是:{{name}}</h2>
      <h2>我的年龄是:{{age}}</h2>
      <img src="../assets/logo.png">

  </div>
</template>

<script>
export default {
    // eslint-disable-next-line vue/multi-word-component-names
    name:"Student",
    data(){
        return {
            name:"张三",
            age:18
        }
    }
}
</script>

<style>
.demo{
    background-color: rgb(173, 167, 167);
}
</style>

在这里插入图片描述
在这里插入图片描述

二、props配置

  1. 功能:让组件接收外部传过来的数据
  2. 传递数据:<Demo name="xxx"/>
  3. 接收数据:
    1. 第一种方式(只接收):props:['name']
    2. 第二种方式(限制类型):props:{name:String}
    3. 第三种方式(限制类型、限制必要性、指定默认值):
      props:{
      	name:{
      	type:String, //类型
      	required:true, //必要性
      	default:'老王' //默认值
      	}
      }
      

    注意:props是只读的,Vue底层会监测你对props的修改,如果进行了修改,就会发出警告,若业务需求确实需要修改,那么请复制(将数据复制到其他对象内)props的内容到data中一份,然后去修改data中的数据。props接收到的对象被替换掉会有waring 但是props对象内部的属性被替换掉编译器不会发现,但是我们一般不这么做。因为存在隐患。

当父组件中传给子组件的属性发生改变时,会触发模板的重新解析,如图所示。改变的是父组件传过去的name,会引起子组件接受到的属性发生改变。
在这里插入图片描述
代码如下:

App.vue

<template>
  <div>
      <Student :name="name" ></Student>
      <button @click="alert">点我改变传过去的props</button>
  </div>
</template>

<script>
import Student from "./components/Student.vue"
export default {
    name:"App",
    components:{
        Student
    },
    data(){
        return{
            name:"张三"
        }
    },
    methods:{
        alert(){
            this.name="我改变了"
        }
    }
}
</script>

<style>

</style>

Student.vue

<template>
    <div class="demo">
        <h2>我的名字是:{{name}}</h2>        
        <h2>我的名字是:{{newAge}}岁了</h2>
        <button @click="showInfo">点击我进行年龄加1</button>        
    </div>
</template>

<script>
export default {
    // eslint-disable-next-line vue/multi-word-component-names
    name:"Student",
    data(){
        return {
            // 支持直接将props中传递过来的属性直接使用
            newAge:this.age
        }
    },
    // 第一种简单的绑定
        // 不加限定语句的传递
        // props:["name","age"],
    // 第二种带有类型限制的绑定
        /*
        props:{
            name:String,
            // age要么为Nuber要么将age改为限制为String类型
            // 要么在传进来的时候使用编程小技巧进行数据绑定传进来一个数值
            // :age="18"
            age:Number
        },
        */
    //第三种带有详细限制的props(可以设置类型、是否必须、默认值)
    props:{
        // 一般来说默认值与是否必须只选择一个即可,如果选必须,那么就不需要默认值
        // 如果选默认值,那么这个属性就不是必须要传过来的。
        "name":{
            type:String,
            required:true
        },
        "age":{
            type:Number,
            default:28
        }
    },
    methods:{
        showInfo(){
            this.newAge++
            // 以下语句报错
            // this.age++
        }
    }
}
</script>

<style>
.data{
    background-color: rgb(202, 190, 190);
}
</style>

三、mixin混合语法

1.简介

mixin可以大大的提升代码的利用率,把多个组件需要的功能提出到一个文件内
如果mixin限定在main.js上,那么这个程序所有组件都会有

2.使用方法

  1. 在mixin.js中定义要混合的代码,组件中引入,并显示调用mixin属性mixins:[]其中mixin后面跟的必须是一个数组
  2. 在main.js中开启全局配置

3.注意点

如果你的组件中定义了与mixin中相关的代码,脚手架会以你定义的代码为基础(也就是组件中定义的代码优先级大)
但是一些特殊函数例外,比如mounted挂载函数。声明周期函数会先执行混入代码再执行自定义的代码

4.结合实例使用

混入的生命周期函数会先执行,然后执行组件内定义的生命周期函数,普通函数是以组件内定义的为基础,如果组件内没有定义会以混入的函数为基础,如果两个地方都没定义就会抛出异常。
在这里插入图片描述

①全局混入

全局混入通常在main.js中进行定义,然后在所有的组件中均可以使用(不需要再定义属性mixin)
语法如下:
main.js

// 导入即将混合的代码
import {mixin1,mixin2} from "./mixin"
// 开启全局的混入(合)
Vue.mixin(mixin1)
Vue.mixin(mixin2)

②局部混入

局部混入的代码需要先进行mixin的引入,然后将其写进Vue Component对象的属性内也就是前面使用方法中介绍到的mixins:[xxx,xxxx]。
下面是App.vue中的一部分代码:

import {mixin1,mixin2} from "./mixin"
export default {
    name:"App",
    components:{
        Student,
        School
    },
    mixins:[mixin1,mixin2]
}

当然在体验局部混入跟全局混入的区别时,也可以通过以下一个实例:
当打开全局混入时,不必使用mixins,即使使用了mixins,普通函数会以你定义的代码为基础。
test.html

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>
<script src="https://cdn.staticfile.org/vue/2.4.2/vue.min.js"></script>
</head>
<body>
<div id = "databinding"></div>
<script type = "text/javascript">
var mixin = {
	methods: {
		hellworld: function () {
			document.write('HelloWorld 方法' + '<br>');
		},
		samemethod: function () {
			document.write('Mixin:相同方法名' + '<br>');
		}
	}
};
//全局混入
Vue.mixin(mixin)
var vm = new Vue({
	//mixins: [mixin],
	methods: {
		start: function () {
			document.write('start 方法' + '<br>');
		},
		samemethod: function () {
			document.write('Main:相同方法名' + '<br>');
		}
	}
});
vm.hellworld();
vm.start();
vm.samemethod();
</script>
</body>
</html>

四、插件的使用

对vue的一种增强,包含一个install方法的对象,install方法第一个参数是vue,第二个以后的参数是使用者传递的参数

1.插件语法

①定义插件

```js
const plugins={
	// 这里install其实是一个属性
	install(vue,x,y,z){
		....
	}
}
export plugins
```

②引入插件并使用

import ... from ....
Vue.use(...,参数1,参数2....)

2.上手插件

自定义插件一般放在plugins目录下,网络上也有许多大牛定义的插件,只需引入使用即可;接下来带大家自定义一个插件,并导入Vue项目进行使用。

plugins.js

const plugins={
    install(Vue,x=0,y=0,z=0){
		console.log(x,y,z)
		//全局过滤器
		// 使用到这个过滤器的地方将会只显示列表中的前四个元素
		Vue.filter('mySlice',function(value){
			return value.slice(0,4)
		})

		//定义全局指令
		Vue.directive('fbind',{
			//指令与元素成功绑定时(一上来)
			bind(element,binding){
				element.value = binding.value
			},
			//指令所在元素被插入页面时
			inserted(element){
				element.focus()
			},
			//指令所在的模板被重新解析时
			update(element,binding){
				element.value = binding.value
			}
		})

		//定义混入
		Vue.mixin({
			data() {
				return {
					x:100,
					y:200
				}
			},
		})

		//给Vue原型上添加一个方法(vm和vc就都能用了)
		Vue.prototype.Hello = ()=>{alert('你好啊')}
	}
}
//暴露出去
export default plugins

引入并使用插件
main.js

import App from "./App.vue"
import Vue from "vue"
//导入插件
import plugins from "./plugins"
//注册插件
Vue.use(plugins)
new Vue({
    el:"#App",
    render:h=>h(App)
})

使用插件中的自定义指令

<template>
  <div>
      <h2>姓名:{{name}}</h2>
      <h2>年龄:{{age}}</h2>
      <input v-fbind:value="name">
  </div>
</template>

<script>
export default {
    // eslint-disable-next-line vue/multi-word-component-names
    name:"Student",
    data(){
        return {
            name:"张三",
            age:18
        }
    }
}
</script>

<style>

</style>

五、样式混合问题

描述:不同组件中如果使用相同的class,会导致出现样式覆盖的问题,覆盖规则是父组件覆盖子组件子组件根据导入顺序,新的覆盖旧的。可以使用不同的类名进行区分解决问题,也可以使用scoped属性,对style属性我们还可以使用lang进行指定,我们是用Less还是用css
原理:scoped会根据经纬度、时间、使用电脑型号等生成一个唯一id,然后将这个id插入到对应的标签内
再将相应的样式转换为标签属性选择器,进行样式语言的限定。默认选择css样式语言

<style scoped>
.demo{
    background-color: red;
}
</style>

至此这几种属性或者使用语法就介绍完了,大家有啥疑问或者好的想法欢迎评论区留言。

在这里插入图片描述