13.Vue - ref属性、props配置、mixin混入、插件、scoped样式

目录

一、ref 属性

1.1 之前获取DOM

1.2 Vue获取DOM

1.3 组件元素添加ref属性

1.4 总结

二、props 配置

2.1 传递数据

2.2 接收数据

2.2.1 简单接收

2.2.2 限制类型

2.2.3 限制类型+限制必要性+指定默认值

2.3 案例

2.3.1 Student.vue

2.3.2 App.vue

三、mixin 混入

3.1 mixin.js文件

3.2 局部混入

3.3 全局混入

四、plugin.js 插件

4.1 语法

4.1.1 plugin.js 文件

4.1.2 应用插件

4.2 应用

五、scoped 样式


一、ref 属性

1.1 之前获取DOM

<template>
  <div>
    <h1 v-text="msg" id="title"></h1>
    <button @click="showDOM">点我输出上方的DOM元素</button>
    <School></School>
    <School></School>
  </div>
</template>

下面是原生的方式调用DOM

  methods: {
    showDOM() {
      console.log("@@");
      //拿到h1标签并输出
      console.log(document.getElementById('title'))
    },
  },

输出结果

image-20231211151352153

1.2 Vue获取DOM

<template>
  <div>
    <h1 v-text="msg" ref="title"></h1>
    <button @click="showDOM">点我输出上方的DOM元素</button>
    <School></School>
    <School></School>
  </div>
</template>

采用ref属性获取DOM元素

  methods: {
    showDOM() {
      console.log("@@");
      //拿到h1标签并输出
      // console.log(document.getElementById('title'))
      //因为我们此vue文件是一个组件,此this代表着vc实例对象  
      console.log(this.$refs.title)
    },
  },

vc组件实例对象上有一个$refs属性

image-20231211151939390

1.3 组件元素添加ref属性

<template>
  <div>
    <h1 v-text="msg" ref="title"></h1>
    <button @click="showDOM">点我输出上方的DOM元素</button>
    <School ref="sch"></School>
  </div>
</template>

  methods: {
    showDOM() {
      console.log("@@");
      //拿到h1标签并输出
      //因为我们此vue文件是一个组件,此this代表着vc实例对象  
      console.log(this.$refs.sch)
    },
  },

控制台输出结果

输出School组件的vc实例对象

image-20231211152250577

1.4 总结

  • 用来给HTML元素或子组件注册引用信息(id的替代者)

  • 应用在html标签上获取的是真实DOM元素,应用在组件标签上获取的是组件实例对象(vc)

  • 使用

<h1 ref="xxx"> ....</h1> 

或者

 <School ref="xxx"></School>

获取DOM元素

this.$refs.xxx

二、props 配置

功能:让组件接受外部传过来的数据

备注props是只读的,Vue底层会监测你对props的修改,如果进行了修改,就会发出警告,

若业务需求确实需要修改,name请复制props的内容到data中一份,然后去修改data中的数据,具体做法查看下面的案例

2.1 传递数据

普通传递

   <demo name="xxx" sex="xxx" age="xxx">

传递的数据组件要接收,否则会报错,下面就是在接收数据的时候没接收"age"数据

image-20231211170142481

传递number数据

此时传递的age字段是数字类型, 冒号代表v-bind,含义是传递的值必须是引号中JS表达式执行的结果

 <demo name="xxx" sex="xxx" :age="xxx">

2.2 接收数据

2.2.1 简单接收

props:['name','sex','age']  

也确实存在于vc实例中,并且下面三个字段都是靠props来的

image-20231211165826448

2.2.2 限制类型

限制接收的字段的类型

让接收的字段是某个类型时才进行接收

props:{
    name: String,
    age:Number,
    sex:String
}

假如说不一致的话可能会出现下面的错误

image-20231211170823654

2.2.3 限制类型+限制必要性+指定默认值

  props:{
                name:{
                    type:String,
                    // 必须传入值
                    required:true
                },
                age:{
                    type:Number,
                    // 如果不传入值的话,会有一个默认值
                    default:99
                },
                sex:{
                    type:String,
                    required:true
                }
            }

2.3 案例

2.3.1 Student.vue

<template>
<!-- <template>标签不参与编译,在页面展现的是下面的一段结构 -->
     <!-- 组件结构 -->
     <div class="demo">
        <h2> 学生名称:{{name}}</h2>
        <h2> 学生年龄:{{age}}</h2>
        <h2> 学生性别:{{sex}}</h2>
        <button @click="showName">点我提示学生名</button>
     </div>
</template>
 
 <script>
        export default {
            name:'Student',
            data(){
                
                return{
                //  name:'张三',
                //  sex:'男',
                //  age:18
 
                //this.name是外部传进来的   this在这里值得vc
                // 这样也说明了props的优先级更高,要不然这里不能调用 
                MyName:this.name
                }
            },
            methods: {
                showName(){
                    alert(this.name)
                }
            },
            // 顺序不一定要对上
            // 接收外部传入数据
            // props:['name','sex','age']    //最简单的写法,但是不能限制传进来的数据
 
            // 接收的同时对数据进行类型限制
            // props:{
            //     name: String,
            //     age:Number,
            //     sex:String
            // }
 
            // 接收的同时对数据进行类型限制+默认值的指定+必要性的限制
            props:{
                name:{
                    type:String,
                    // 必须传入值
                    required:true
                },
                age:{
                    type:Number,
                    // 如果不传入值的话,会有一个默认值
                    default:99
                },
                sex:{
                    type:String,
                    required:true
                }
            }
        }  
</script>
 
<style>
     /* 组件的样式 */
    .demo{
        background-color:orange
     }
 
</style>

2.3.2 App.vue

<template>
  <div>
    <!-- 在组件标签中还可以传入值 :age确保传入的值是数字,单向绑定,要传入双引号内表达式运行的结果
         双引号内的表达式就是18 运行结果也是18数字,故可以-->
    <Student name="李四" sex="女" :age="18"></Student>
  </div>
 
</template>
 
<script>
// 引入组件
 
     import Student from './components/Student'
 
     export default {
       name:'App',
      //  注册组件
       components:{
         Student
       }
      }
</script>
 
<style>
 
</style>

img

三、mixin 混入

两个组件共享一个配置

我们Student.vue组件和School.vue组件中有一部分的代码是相同的,这个时候我们可以把相同的配置提取出来

image-20231211173930854

假如组件中data和methods配置与mixin混入中的配置冲突了,以什么配置为准

以组件中的配置为准

但是有特殊情况:假如组件A中有生命周期函数mounted,minxin配置中也有mounted配置,怎么办

都会执行,有先后顺序。先执行minxin配置中的mounted,再执行组件A中的mounted函数

生命周期中的钩子函数不以任何一个组件为主,都会执行,来者不拒

3.1 mixin.js文件

创建mixin.js文件

这个文件名随便定义

export const mixin={
    methods:{
        showName(){
            alert(this.name)
        }
    }
}

3.2 局部混入

Student.vue组件

<template>
  <div>
    <h2 @click="showName">学生姓名:{{ name }}</h2>
    <h2>学生性别:{{ sex }}</h2>
  </div>
</template>
​
<script>
//引入混合
import { mixin } from "../mixin.js";
​
export default {
  //组件名称
  name: "Student",
  data() {
    return {
      name: "张三",
      sex: "男",
    };
  },
  //应用混合
  mixins: [mixin],
};
</script>
​
<style scoped>
</style>

School.vue组件

<template>
  <div>
    <h2 @click="showName">学校名称:{{ name }}</h2>
    <h2>学校地址:{{ address }}</h2>
  </div>
</template>
​
<script>
//引入混合
import { mixin } from "../mixin.js";
​
export default {
  //组件名称
  name: "School",
  data() {
    return {
      name: "齐工大",
      address: "济南",
    };
  },
  //应用混合
  mixins: [mixin],
};
</script>
​
<style scoped>
</style>

3.3 全局混入

mixin不在组件中引入

在main.js中进行配置

// 该文件是整个项目的入口文件
 
// 引入vue,这个vue不能解析template配置项
import Vue from 'vue'
// 下面这个是引入完整版的vue。这个vue能解析template配置项
// import Vue from 'vue/dis/vue'
 
// 引入APP组件,它是所有组件的父组件
import App from './App.vue'
 
// 引入混合
import {mixin} from './mixin'
Vue.mixin(mixin)   //这样一来所有的vc和vm都会得到这个混合
// Vue.mixin(mixin2)  有几个,就写一个这样的语句
 
// 关闭vue的生产提示
Vue.config.productionTip = false
 
// 创建vue实例对象---vm
new Vue({
  el:'#app',
  render: h => h(App),
})

其他组件就不需要配置了,直接使用即可

image-20231211190337914

四、plugin.js 插件

功能:合理合法增强Vue

插件本质:包含install方法的一个对象,install的第一个参数是vue,第二个以后的参数是插件使用者传递数据

Vue会帮我们调用install函数

4.1 语法

4.1.1 plugin.js 文件

编写插件

export default{
    install(){
        console.log('@@@install')
    }
}

插件还可以收到参数

接收的第一个参数a是Vue

export default{
    install(a,b,c){
        console.log('@@@install',a,b,c)
    }
}

4.1.2 应用插件

一定要在创建Vue之前应用插件

//引入Vue
import Vue from 'vue'
//引入所有组件的外壳组件
import App from './App.vue'
​
//关闭Vue生产提示
Vue.config.productionTip = false
​
//引入插件
import plugins from './plugins'
//应用插件
Vue.use(plugins)
​
//创建vm
new Vue({
  render: h => h(App),
}).$mount('#app')
​

配置完成后刷新页面,观察控制台

自动执行了插件中的install方法

image-20231211194510848

还可以传递参数

//引入Vue
import Vue from 'vue'
//引入所有组件的外壳组件
import App from './App.vue'
​
//关闭Vue生产提示
Vue.config.productionTip = false
​
//引入插件
import plugins from './plugins'
//应用插件
Vue.use(plugins,10000000,2000000)
​
//创建vm
new Vue({
  render: h => h(App),
}).$mount('#app')
​

image-20231211232525267

4.2 应用

插件到底可以做什么呢? 如下所示

export default {
    install(Vue) {
        //1. 全局过滤器
        Vue.filter('mySlice', function (value) {
            return value.slice(0, 4)
        })
​
        //2. 全局自定义指令
        Vue.directive('fbind', {
            //指令与元素成功绑定时(初始时)
            bind(element, binding) {
                element.value = binding.value
            },
            //指令所在元素被插入页面时
            inserted(element, binding) {
                element.focus()
            },
            //指令所在的模板被重新解析时
            update(element, binding) {
                element.value = binding.value
            },
​
        })
​
        //3. 定义混入
        Vue.mixin({
            data() {
                return {
                    x: 100,
                    y: 200
                }
            }
        })
        //4. 向Vue原型上存放hello方法(vm和vc就都可以使用了)
        Vue.prototype.hello = () => { alert('你好啊') }
    }
}
​
​
​

五、scoped 样式

作用:让样式在局部生效,防止冲突

组件A中编写的样式和在组件B中编写的样式其实最终会汇总到一起,但是汇总到一起后会出现类名冲突

假如冲突了会以哪个结果为准

关键是看在App.vue文件中后引入的是谁,以后引入的组件的样式为准,后来者居上

为了防止样式冲突,我们可以在样式上标注scoped 属性

<style scoped>
.demo {
  background: skyblue;
}
</style>

这是怎么实现的呢

其实是给最外侧的div加了一个特殊的标签属性,而且data-v后面的值都是随机生成的,每次运行的时候都会不一样

image-20231211235825756

但是App.vue组件不适合用scoped属性

一般来说如果App.vue组件写样式的话,就是许多组件都在使用

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我爱布朗熊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值