• 04 Vue属性配置


    1、ref属性

     App.vue代码:

    1. <script>
    2. import School from "@/components/School";
    3. export default {
    4. name: "App",
    5. components: {School},
    6. data() {
    7. return { msg: "学习vue"}
    8. },
    9. methods: {
    10. showDom() {
    11. //通过ref绑定可以获得dom或者vue组件实例对象
    12. console.log(this)
    13. console.log(this.$refs)
    14. console.log(this.$refs.myTitle) //html标签,获得真实dom元素,
    15. console.log(this.$refs.school) //ref绑定组件,获得子组件的实例对象
    16. console.log(document.getElementById('sch')) //如果给绑定ID,通过document可以获取完整的dom对象
    17. }
    18. }
    19. }
    20. script>

    样式:

     通过控制台输出: 可以看到通过ref属性:可以非常方便的获得vue组件中子组件的实例对象,这个在后面组件之间通信非常重要;

    2、props配置

    一个组件被多次使用的时候,vue实例的数据不一致,实例化的时候传入数据

    2.1 数组方式定义props 

     定义 Student.vue 组件

    1. <script>
    2. export default {
    3. // eslint-disable-next-line vue/multi-word-component-names
    4. name: "Student",
    5. data () {
    6. return {
    7. msg:"我在学习vue",
    8. }
    9. },
    10. props: ["name","age","sex"]
    11. }
    12. script>

    初始化组件实例的时候

    效果:

     查看vue实例

     数组方式接受的只能是字符串的类型:

    age=”18+1“ 这种方式传递的也是字符串,不做运算。 

    如果通过`` 方式传递,就会出现计算的结果;

    2.2 限制类型接受参数

    1. <script>
    2. export default {
    3. // eslint-disable-next-line vue/multi-word-component-names
    4. name: "Student",
    5. data () {
    6. console.log(this)
    7. return {
    8. msg:"我在学习vue",
    9. }
    10. },
    11. // props: ["name","age","sex"]
    12. props: {
    13. name: String,
    14. age: Number,
    15. sex: String,
    16. }
    17. }
    18. script>

     标准的写法:

    1. //进行类型和默认值,是否必须的配置
    2. props: {
    3. name: {
    4. type:String,
    5. required: true,
    6. },
    7. age: {
    8. type: Number,
    9. default:18
    10. },
    11. sex: {
    12. type: String,
    13. required: true
    14. },
    15. }

    外部接受的prop中参数是不建议更改的:

    1. methods: {
    2. changeAge() {
    3. // eslint-disable-next-line vue/no-mutating-props
    4. this.age = 30
    5. }
    6. }

    增加点击事件修改: 刷新界面修改可以成功,但是控制台会报错,所以不建议修改props传入的值,可能会造成vue其他的一些位置问题。

     如果业务需求就是要改: 点击年龄增加,需求: 重新定一个新的变量,接受传入的值,对新定义的值做修改,就是可以实现修改传入的值。

    注意事项:

    1、如果data中定义的属性名字和props中定义的一样,props中的会优先,覆盖data中定义的值,

    2、props中定义的属性不能是key,ref等被vue使用的作为节点标识的属性,

    Student.vue

    1. <script>
    2. export default {
    3. // eslint-disable-next-line vue/multi-word-component-names
    4. name: "Student",
    5. data () {
    6. console.log(this)
    7. return {
    8. msg:"我在学习vue",
    9. myage: this.age
    10. }
    11. },
    12. // props: ["name","age","sex"]
    13. // props: {
    14. // name: String,
    15. // age: Number,
    16. // sex: String,
    17. // }
    18. //进行类型和默认值,是否必须的配置
    19. props: {
    20. name: {
    21. type:String,
    22. required: true,
    23. },
    24. age: {
    25. type: Number,
    26. default:18
    27. },
    28. sex: {
    29. type: String,
    30. required: true
    31. },
    32. },
    33. methods: {
    34. changeAge() {
    35. // eslint-disable-next-line vue/no-mutating-props
    36. this.myage++
    37. }
    38. }
    39. }
    40. script>

    3、mixin混入

    3.1 局部混合

    两个组件中的方法一样,可以优化提取为一个,分别引用;

    可以定义个公共的js文件

    在组件中引入:

     刷新界面: 测试两个组件的绑定方法都正常的:

    混合中可以写很多内容:  组件定义的中的都可以被混合

    1. export const common ={
    2. methods: {
    3. showName() {
    4. alert(this.name)
    5. }
    6. },
    7. mounted() {
    8. console.log("你好啊!")
    9. },
    10. }
    11. export const common2 = {
    12. data() {
    13. return {
    14. x:20,
    15. y:"yyy"
    16. }
    17. }
    18. }

    导入混合

     刷新界面可以看到: common2 中定义的 x,y属性与原来的data中的属性进行了合并:定义的钩子函数也被两个组件引用了。 

    如果混合定义了x,组件中data也有x, 有冲突情况下:以组件中定义的x为准,混合中定义的x被丢弃; 方法和data是这个标准,

    但是如果混合中有生命周期钩子函数,钩子函数都会被执行。组件中定义的后执行,混合中定义的先执行。

    3.2全局混合

    在组件中不做任何引入混合,在main.js中引入

    1. import Vue from "vue";
    2. import App from "@/App";
    3. Vue.config.productionTip = false
    4. import {common,common2} from "@/common";
    5. Vue.mixin(common)
    6. Vue.mixin(common2)
    7. new Vue({
    8. render: h=> h(App),
    9. }).$mount("#app")

    会让所有的组件都引入混合,刷新界面看到你好啊执行四次:为什么是四次呢?看vue

    一共有四个组件实例,root上也绑定了,x,y属性

    全局混合实际上有很多弊端,范围太大了,实际上最多使用的还是局部混合。

    4、Vue插件

    插件可以增强Vue,插件实际上就是对象。

    定义插件

     在main.js 中应用

    1. import Vue from "vue";
    2. import App from "@/App";
    3. //导入插件
    4. import plugin from "@/plugin";
    5. Vue.config.productionTip = false
    6. //应用插件
    7. Vue.use(plugin)
    8. new Vue({
    9. render: h=> h(App),
    10. }).$mount("#app")

     在插件中传递参数

    1. export default {
    2. install(vue) {
    3. console.log("@@@install:",vue)
    4. }
    5. }

    运行发现: 这个默认的参数vue是,vm的构造函数

     

     在vm的构造函数中可以做很多事;

    1. export default {
    2. install(Vue) {
    3. console.log("@@@install:",Vue)
    4. //配置全局过滤器
    5. Vue.filter('myFilter',function (val) {
    6. return val.slice(0,4)
    7. })
    8. //定义全局指令
    9. Vue.directive('fbind', {
    10. bind(element, binding) {
    11. console.log('bind')
    12. element.value = binding.value
    13. },
    14. // eslint-disable-next-line no-unused-vars
    15. inserted(element, binding) {
    16. console.log('insert')
    17. element.focus()
    18. },
    19. update(element, binding) {
    20. console.log('update')
    21. element.value = binding.value
    22. }
    23. })
    24. //混入
    25. Vue.mixin({
    26. data() {
    27. return {
    28. x:20,
    29. y:"yyy"
    30. }
    31. }
    32. })
    33. //给Vue原型上添加一个方法,vm和vc都可以使用
    34. Vue.prototype.hello = ()=> {alert("你好啊! 哈哈")}
    35. }
    36. }

    验证:

    1. # 组件中可以使用全局添加的过滤器
    2. 学校名字: {{name | myFilter }}

    3. # 组件中可以使用自定义的全局绑定
    4. "text" v-fbind:value="name">
    5. # 组件中使用hello方法
    6. test() {
    7. this.hello()
    8. }

     混合检查

     外部定义的插件,可以定义很多过滤器或者很多优秀的方法,可以直接使用。应用插件可以传递多个参数 Vue.use(plugin,x1,x2,x3) 都会被定义的 plugin.js 接收到

     5、scoped样式

    vue组件中的样式,最终会汇总到一起,class名字定义有可能冲突,谁后导入就是用谁的。

    解决问题,style样式要加入scoped,就会不会冲突。

    app组件中定义的style样式有可能不需要加scoped,app组件中定义的样式有可能是全局的样式。

    lang指定默认是: css,可以指定为:less, less 编译需要报错。

    安装:webpack 版本适配less-loader版本

    需要安装 npm install less-loader

    1. <style scoped lang="less">
    2. .student{
    3. background-color: orange;
    4. .name-style {
    5. font-size: 40px;
    6. }
    7. }
    8. style>

    效果:

    6、案例:todolist

     github仓库:后面添加

    7、组件的自定义事件

    7.1  自定义事件的创建和绑定

    子组件向父组件的传递数据

    1、通过父亲组件定义一个方法,通过props传递给子组件,子组件调用传递的方法,可以将数据传递给父组件

    2、父组件给子组件绑定一个自定义事件,在子组件通过 ths.$emit("自定义事件名",参数) , 触发父组件的事件回调绑定的方法,将子组件的数据传递给父组件

    1. # 1、绑定事件
    2. <Student v-on:getStudentName="getStudentName"/>
    3. # 简写 <Student v-on:getStudentName="getStudentName"/>
    4. # 2、定义事件方法
    5. methods: {
    6. getStudentName(name) {
    7. console.log("studentName",name)
    8. }
    9. }
    10. # 3、在子组件触发事件this.$emit('事件名')
    11. methods: {
    12. sendStudentName() {
    13. this.$emit("getStudentName",this.name)
    14. }
    15. }

    另一种更加灵活的绑定事件的方式:可以给绑定事件的时候做一些其他事。

    1. # 1、将子组件通过ref属性命名
    2. <Student ref="student">Student>
    3. # 2、在父组件通过 mounted 钩子函数给绑定
    4. mounted() {
    5. setTimeout(()=> {
    6. this.$refs.student.$on('getStudentName',this.getStudentName)
    7. },3000)
    8. }
    9. # 3、在子组件中触发
    10. methods: {
    11. sendStudentName() {
    12. this.$emit("getStudentName",this.name)
    13. }
    14. }

    如果是事件单次触发:v-on:getStudentName.once或者this.$refs.student.$once('getStudentName',this.getStudentName)

    7.2  自定义事件解绑

    解绑自定义事件:

    1. //解绑一个自定义事件
    2. this.$off('getStudentName')
    3. //解绑一个多个自定义事件
    4. this.$off(['getStudentName','demoEvent'])
    5. //解绑所有自定义事件
    6. this.$off()
    7. //销毁组件实例,组件及其子组件绑定的所有自定义事件也会解绑

    自定义事件注意点:

    1、ref 属性绑定的时候,mounted中的  this.$refs.xxx.$on('getStudentName',回调函数)

     回调需要写成箭头函数,或者直接写在methods,如果直接写 function 函数名,函数名中的this代表子组件。

    3、绑定事件为原生事件的时候需要加.native

  • 相关阅读:
    国内软件测试岗,可以卷到什么程度?
    springboot2整合nacos云服务,配置基本类型和json类型
    制作macOS Ventura U盘启动盘教程
    Selenium教程:自动化浏览器测试工具
    Qt中文件夹的操作
    【每日一题】同积元组
    python-opencv 培训课程作业
    面试中的常问的C++ STL 概念和函数
    图机器学习(GML)&图神经网络(GNN)原理和代码实现(前置学习系列二)
    F28069教程3-中断 PIE
  • 原文地址:https://blog.csdn.net/LoveG_G/article/details/127681526