81回答

0收藏

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

 

技术问答 技术问答 6985 人阅读 | 81 人回复 | 2022-12-12

文章目录: |  ~8 h8 w0 u8 ~3 C7 H# {& Q
  • 前言
  • 一、ref属性的使用
  • 二、props配置
  • 三、mixin混合语法
  • 1.简介
  • 2.使用方法
  • 3.注意点
  • 4.结合实例使用
  • ①全局混入
  • ②局部混入& r% B: v: u) E7 p* @% n
       
    % a4 o, A( ?6 P. [- z
       
  • 四、插件的使用
  • 1.插件语法
  • ①定义插件
  • ②引入插件并使用! n8 ]/ }  X8 L4 U, @
       
  • 2.上手插件  ?: m/ b# n; z# Z& _
       
  • 五、样式混合问题# Y( l1 z/ H9 J# k  H- F

    * u* E& w# u& S) t 2 \" @2 a, U6 F( {: `% K' |' o( W
    前言
    1 r: r5 m* |: s( l( \3 b5 [8 y
    ' S/ C* p, d) Z* W在前面介绍到了Vue的一些基本概念与如何使用Vue,并通过node中的npm 使用vue脚手架(vue-cli)搭建了一个简单的Vue应用,其实所有的Vue项目搭建的时候都是换汤不换药。今天将会介绍几个Vue中常用的配置,他们的大致功能如下:1 _* F, R1 c5 l! Z9 q# t. J+ G) M

    ! L# G! d+ q' c1 o0 k' F- t% G6 z
  • ref 作用是将dom元素选择出来,对普通标签来说与document.getElementById(“xxx”)是一回事,对自定义组件来说会将Vue Componentd对象选择出来,获取到VC对象也就可以获取到其中的dom元素了。
  • props 作用是父组件向子组件传递数据(当父组件有更新的时候子组件也会有更新)
  • mixin 将组件公共部分提取出来,哪里用到就在哪里引用
  • 插件 别人写好的js文件,我们只需引入并use即可(这里要区分好组件与插件)
  • 样式混合 如果给组件的style不加scoped将会导致样式的混乱 5 o4 Q( X+ i0 W3 w( n
    有了大概的预览之后就可以进行深一步的学习了,将会配合一些代码实例进行叙述。) Y: v: Z" a2 i' m* u0 R8 A: c
    1 z! A+ v: \0 ^. O2 D" G0 u/ J
    一、ref属性的使用
    ' l0 v/ N  G9 |; i. b ' U& r( V$ F2 |
    大家在学习css的时候学过各种选择器,也学过使用css选择器将dom元素选择出来,这个属性的话起到的作用就是将想要的dom元素选择出来,根据ref属性可以很轻松的找到dom元素。/ s1 h, l7 t! T' z
    2 X! q3 J! o7 O

    * J" J% o" ]9 f8 S[ol]
  • 被用来给元素或子组件注册引用信息(可以认为是id的替代者)
  • 标记在html标签上可以获取真实DOM元素
  • 标记在组件标签上可以获取组件实例对象(vc)
  • 一句实例对象可以进行自己想要的操作
  • 使用方式:
    ( S. @" o# O* `  [ol]
  • 给元素打标识:
    & [7 _7 l0 G! s* v  V; o+ e ①. .....- L5 A! ?) e2 E
    ②. 6 G+ i- e. f% r6 @
    ③.
  • 获取元素:this.$refs.xxx[/ol] [/ol]
    6 R; u* z" H; C6 ]0 t2 }% a结合以下实例代码:" ^- m; T0 ^. g0 V8 \/ @
    App.vue
    3 y: _3 v0 w8 P- V* s& P0 ~( _ 3 @  L! @6 B+ B3 q' D# k5 g

    $ A6 K$ e* t2 u1 ?  ! o' D- t6 @9 B3 z
          Hello World
    , T0 o& z% b) C( M/ N1 v0 c1 X8 g      
    / N  C% a$ g/ s      点我体验ref# j0 e; |  H+ a* u1 Z- C" u9 R& k
      
    6 G: I3 v" X3 f  T3 W; R1 L2 a( u$ \8 l
    7 L. T  F  L; `( h. h) f
    : ]) v3 D$ ?1 z: Y1 e
      L2 y4 w, ?' j; g4 D
    Student.vue
    ( ?+ b$ P- |1 o
    % }5 d( ?; _  H  y9 S  
    % k! @/ k* m4 S# k6 o( M" n* ?      我的名字是:{{name}}8 c1 a2 y! L4 n5 r
          我的年龄是:{{age}}
    : h0 Z2 n9 y* L" L; S. U( B- _$ A      2 Q* s4 K5 _  z
    [img][/img]
    # G* Y, r% p# L, z! ~1 e$ d* @5 d: X/ T) w* n# t
      
    . \! v8 j4 _$ W1 M1 _/ V3 p1 g
    0 g$ ]; H: p7 p( p
    9 U* o" g8 d5 w) i: p6 ~$ `.demo{
    * P; ~) l: D6 s7 G( p# b0 i0 ~    background-color: rgb(173, 167, 167);. e1 s6 }. j# N  R4 q  }
    }
    6 }# E7 r, I+ w+ q9 D% X8 X2 ]
    $ c1 t- j1 ~: |# W: P. p

    20221246.png

    20221246.png

    5 Q* L; q+ H% R9 } $ T6 F. J7 B  i9 T

    20221247.png

    20221247.png
    " w9 I+ ?% L6 E0 `

    3 q* M- y7 s5 i* a二、props配置 5 T$ \+ o& F" Q
    [ol]
  • 功能:让组件接收外部传过来的数据
  • 传递数据:
  • 接收数据:
    8 c3 V6 G) t5 r0 s8 M  l. q  [ol]
  • 第一种方式(只接收):props:['name']
  • 第二种方式(限制类型):props:{name:String}
  • 第三种方式(限制类型、限制必要性、指定默认值):props:{8 j+ a% ^- _/ z
            name:{1 W, c) [9 T8 g. j
            type:String, //类型
    0 \8 e- M- r; A: b0 o        required:true, //必要性. C: l- P, f7 n" s* O
            default:'老王' //默认值
    . M. `) S, `! b% \        }$ L1 v6 u, l" n5 N3 N% e
    }) W* P  v9 S. x0 ^: u+ Y
    [/ol]
    ) `% C. T6 a4 h  
    1 C" I$ ?' u) W   注意:props是只读的,Vue底层会监测你对props的修改,如果进行了修改,就会发出警告,若业务需求确实需要修改,那么请复制(将数据复制到其他对象内)props的内容到data中一份,然后去修改data中的数据。props接收到的对象被替换掉会有waring 但是props对象内部的属性被替换掉编译器不会发现,但是我们一般不这么做。因为存在隐患。
    , u9 I" d# L+ ^0 F6 a. y5 C* U
    8 U7 C) g3 x3 x  
    [/ol] / {( D1 O2 K3 C
    当父组件中传给子组件的属性发生改变时,会触发模板的重新解析,如图所示。改变的是父组件传过去的name,会引起子组件接受到的属性发生改变。3 x9 h& j% G, l1 j

    6 e( c9 R0 l0 y# O% ?; V; L* s

    20221248.gif

    20221248.gif

    + F1 d9 p* h2 d( u 代码如下:
    / S+ V  q, z5 i% e
    0 \5 @4 e+ D2 @1 EApp.vue$ j4 K3 W, R, g/ j, H
    # t! M& t+ o, B+ ~
      
    * T% S# y9 f! l: t( ~2 ]1 F; o6 @! }      
    & F  h, x1 @  @  O! P3 d! i      点我改变传过去的props. ^) t8 f3 S" W# R& @7 t1 ?: ?
      % R2 l- q7 u( I' E: K  t# S

    7 L" Z* W3 |4 j) i7 `/ F8 I2 I' Z2 k6 s+ X+ d% [

    % B% b9 V- W. Y4 q9 m. _( Q
    3 \2 `7 T. d6 c9 j  [Student.vue
    & \+ P; X5 [0 s8 Y
    ; Y2 R) }, ^6 M% ~   
    2 L4 N8 k+ k/ y  L7 Q; k: ~9 R& a        我的名字是:{{name}}        * W- y$ ?5 {: D5 V* U$ K8 k, ^
            我的名字是:{{newAge}}岁了; y1 P0 |' n# i; L# G* y
            点击我进行年龄加1        * t5 d; h+ M- R1 n$ i  U  h8 q
       
    ; W% @' i3 \* F  Q3 e# |6 _7 x+ Q3 G0 Y" F! W* H( i7 e4 |8 q

    7 r) ?5 @; m8 u3 l$ v7 r.data{# e' L1 h1 T9 v4 L' {3 A
        background-color: rgb(202, 190, 190);: S4 }0 u8 q0 O9 u5 m  V: i7 G% F
    }
      ?0 l# l8 v9 r+ W
    / |) w, ?# M3 h+ M0 j, S三、mixin混合语法
    ' p" x5 j% ]/ B/ R/ D- W$ }1.简介
    # h3 E# a! a( H
      W. o7 ?1 M& t" G0 ~; | mixin可以大大的提升代码的利用率,把多个组件需要的功能提出到一个文件内" h5 K' i; g, L) M3 K: }4 ^0 s/ k; ~
    如果mixin限定在main.js上,那么这个程序所有组件都会有$ h8 K2 o) [, N5 D6 @
    $ }$ }# Y6 w0 y

    " ]. h; E- k+ B1 ?0 {# h2 _# ^1 M2.使用方法 ( n' v  W% t4 i
    [ol]
  • 在mixin.js中定义要混合的代码,组件中引入,并显示调用mixin属性mixins:[]其中mixin后面跟的必须是一个数组
  • 在main.js中开启全局配置[/ol] ' J" [: h1 S( U3 y2 s
    3.注意点 4 t$ U" m. }, \' H/ V1 E/ w* @% j
    如果你的组件中定义了与mixin中相关的代码,脚手架会以你定义的代码为基础(也就是组件中定义的代码优先级大)5 m& p2 J# u1 k3 x& ?- ?
    但是一些特殊函数例外,比如mounted挂载函数。声明周期函数会先执行混入代码再执行自定义的代码
    1 _  l; F% N" I+ o4 T& f4 P! x9 v) f
    7 c0 N: l6 Q- s8 S& C- ]* ~4.结合实例使用
    / o9 L% ~7 o% i, r混入的生命周期函数会先执行,然后执行组件内定义的生命周期函数,普通函数是以组件内定义的为基础,如果组件内没有定义会以混入的函数为基础,如果两个地方都没定义就会抛出异常。
    ) x0 i; R1 d8 }$ M: U, }5 D
    6 H/ {) M' F! |% I. U

    20221249.png

    20221249.png

    % g8 G/ [; S4 p& D9 J' k" H* h3 T
      D3 ]( _0 n: R①全局混入 ! Y% X% k7 g7 Z0 ^1 y
    全局混入通常在main.js中进行定义,然后在所有的组件中均可以使用(不需要再定义属性mixin)2 b1 ^4 t/ X+ ]
    语法如下:
    / C9 V) ?% y4 l! P6 B( F! Q main.js" J1 ^; v  X. ?8 Z* K, B
      J; m, [5 W# f$ p( V/ a
    // 导入即将混合的代码
    4 g/ ?7 `9 T) t) t9 u$ X6 ]import {mixin1,mixin2} from "./mixin"
    ) E* o# {, ~4 a2 Z// 开启全局的混入(合)
    ' h. w$ R  J. V/ @$ t8 _Vue.mixin(mixin1)
    : H: E0 S& d3 K1 S1 {: o' S9 F7 B' NVue.mixin(mixin2)! ]/ b; U! x/ q* M0 L5 Q6 S! P

      A; |, N  p# L5 e$ X3 I1 m②局部混入
    ' W8 v$ N/ x1 n/ M" z" I) I9 y局部混入的代码需要先进行mixin的引入,然后将其写进Vue Component对象的属性内也就是前面使用方法中介绍到的mixins:[xxx,xxxx]。: _2 S% [: F& M% K
    下面是App.vue中的一部分代码:- A# c: d5 ]' ]7 A' K8 }

    3 B) W6 a3 t7 R4 _. W. ~9 qimport {mixin1,mixin2} from "./mixin"
    , ?3 d% y0 Z7 }% l4 L  hexport default {. C: \7 }, n& K# O  e
        name:"App",' |4 b$ f$ [3 n: i
        components:{2 Z  [6 [- r) F% n9 J* Q
            Student,
    ; p- s; c1 d, D/ }/ d        School
    ; P+ q8 b7 D. o! m) N3 r+ q4 j    },
    0 P( P* z4 S1 x    mixins:[mixin1,mixin2]( [0 T( W/ I  p8 l
    }- E$ L0 ]7 a) C2 o* m8 L

    # j+ |: Z2 m9 _' F9 b当然在体验局部混入跟全局混入的区别时,也可以通过以下一个实例:
    . u, r3 s4 h: R( n. Z$ c! J% o+ ^ 当打开全局混入时,不必使用mixins,即使使用了mixins,普通函数会以你定义的代码为基础。
    5 |& L) h8 t' V1 U- t4 j" T test.html: S  t( D6 L0 t: V! B
      \  Q4 o6 D  u2 Z, \, z; r

    , X& c# D) o5 d
    / C4 h9 g# N  U. m5 ~, lVue 测试实例 - 菜鸟教程(runoob.com)
    5 T+ ]' q7 l6 y7 a6 m9 Z& E
    % J$ p+ h. L( h, D5 Z0 h+ ], v
    ; u  J0 Z& d- ?; ?7 C7 @# }; d8 T* @1 c: Y8 V

    * o8 z8 E4 |. o7 F+ n  y
    # j; y3 I% S5 O8 W四、插件的使用
    4 F7 g# q4 y$ x6 f( [7 V+ ~对vue的一种增强,包含一个install方法的对象,install方法第一个参数是vue,第二个以后的参数是使用者传递的参数7 f' b* ~5 B, e1 ]
    , z5 x  m5 @- t: S- z
    1.插件语法
    , e/ S3 r' N* l% \/ W4 P①定义插件 & s, @/ }. g/ t  x0 ^6 t" b- E3 a
    ```js
    / J2 p  P/ j2 ]) cconst plugins={  A) E" L' v4 ]( O# |
            // 这里install其实是一个属性1 s$ i( U0 D  ^
            install(vue,x,y,z){
    8 [# H+ \" Y) D" a                ....& X9 e8 M8 m+ M5 Z  F
            }2 D, g+ h; B5 u
    }
    ' o9 ?4 a0 d' Dexport plugins
    / Z1 Q- Q. }3 q& P7 j2 Q```
    7 Z. P5 g& Y. }$ w + ?+ W" U) {" w. d
    ②引入插件并使用
    6 R' }8 c- k! F( d" G% M: ?import ... from ....) I1 M, K( ~0 X# ], k3 w
    Vue.use(...,参数1,参数2....)" k% u. L- u2 F  w2 ~

    ' j. H! v8 h. _( W0 E2.上手插件 5 R8 b. |: L+ ~) {5 R
    自定义插件一般放在plugins目录下,网络上也有许多大牛定义的插件,只需引入使用即可;接下来带大家自定义一个插件,并导入Vue项目进行使用。
    6 z: P0 d! O1 h( R$ `   s' W+ C( g: o$ p/ `$ L  B0 R- a
    plugins.js- k  L! I" n* q
    , \0 o  q3 o4 |9 z$ Q+ r
    const plugins={8 `8 i1 R# P3 K0 u* Y- X1 s
        install(Vue,x=0,y=0,z=0){" z3 l5 Y4 |( |+ i! {/ |: ?
                    console.log(x,y,z)
    * h0 b. X4 i4 ?                //全局过滤器
    . q6 W7 h- D5 m; V                // 使用到这个过滤器的地方将会只显示列表中的前四个元素
    ; f8 H2 y+ j( g' C+ k2 @* S                Vue.filter('mySlice',function(value){
    5 j" \+ j1 c: Q                        return value.slice(0,4)* M4 e+ u. a8 Y
                    })
    9 `0 t- ^7 D5 d                //定义全局指令
    - _* j% X6 F6 K- h                Vue.directive('fbind',{
    $ F7 T& X- s7 ?; C* [9 ?                        //指令与元素成功绑定时(一上来)% A6 r0 e/ W! I. ?& d$ r% s
                            bind(element,binding){. u$ v7 t& t% n! j; i
                                    element.value = binding.value1 s1 f1 n$ Z2 w* O
                            },
    ) ~" K) g  d! n: H1 Q& F" z% n                        //指令所在元素被插入页面时9 X$ W5 n( v4 N. i
                            inserted(element){0 J7 Z# g0 U' A( X1 z) @, x  o2 I
                                    element.focus()
      S  r1 b3 |+ V& ^! g, y: l, H# G" k  Q                        },
    * q% a( B2 g" i) K2 Q5 _) ]6 G                        //指令所在的模板被重新解析时
    # c% I2 h( W8 w7 b) c                        update(element,binding){
    2 _  T" v' ^' a8 F! ?, v; O                                element.value = binding.value
    ; d) Z2 V! w" o% g. m                        }
    ' G$ R$ s! d% v3 f                })
    & c. V. j2 u4 N: A- L                //定义混入
    " ^8 F: U/ _5 r. M+ _/ z% g# M                Vue.mixin({8 K5 s3 H$ }9 n8 D7 C8 I; H
                            data() {
    1 L, P1 @2 j2 P% i5 y                                return {
    ) f/ j: ^5 B- w( P/ H0 x/ F                                        x:100,
    ( k3 H6 Z4 Q  S. E, S4 `* Z, r                                        y:200
    0 e# t: N* t' p+ M! |3 ~                                }9 {5 e; D- @9 d' ]1 V! B2 ?9 s
                            },
    1 P0 b' |, Y$ |4 N3 U                }); M6 [. |7 V( m3 _  `. V
                    //给Vue原型上添加一个方法(vm和vc就都能用了)( v1 D$ n! r( u2 F3 S
                    Vue.prototype.Hello = ()=>{alert('你好啊')}
    ! Q  @6 M; T/ H  t$ D  @3 Q9 ?        }& I% Y; o: N. G9 g/ s
    }% p) G# `- j5 T8 r* Y
    //暴露出去
      a! L+ X( A$ \$ S: U2 M* Dexport default plugins
    4 X3 f1 i6 w+ E0 K' b
    ' v! u! _  w. m% n* R引入并使用插件! [4 ^$ ^, P. @5 }$ g( o
    main.js
    7 y8 f- P+ n* o$ q) h6 d% l
    4 m) w7 ]1 c1 j" `6 Qimport App from "./App.vue"6 k! o, T8 ^) F3 o! i4 W% x
    import Vue from "vue"4 M; I% t- i# x5 @
    //导入插件2 V: _' {% z+ B& \+ N
    import plugins from "./plugins") H$ x+ x# I9 ^5 p; V: a$ t
    //注册插件
      |9 y1 Z; I1 _Vue.use(plugins)4 L7 ^# @5 S4 {+ s
    new Vue({
    5 B. m- s/ m: r6 }6 X    el:"#App",7 u, [  }. x, M1 I+ e- r* V" B
        render:h=>h(App)) a, }) l0 X5 O' v  n
    })
    ( `: A% R( [$ x, W; x. @0 h1 e 5 ^6 k# X" Q1 |& d- ^
    使用插件中的自定义指令- A& h" C2 W* ~

    , i9 [- y1 @* |4 w. F) q4 P3 B3 J4 J  
    * l! M0 }! W+ _. i+ j1 `& @      姓名:{{name}}
    ) Y& _! X" R3 W: V      年龄:{{age}}
    % T4 q) E/ Y3 L7 k# j' m      " m% T+ [4 a" _3 q
      
    % R1 h7 g, t  O3 x
    / n- C' ^' _  q' c- Y
    * \% L! _( i) v
    ( Y/ @! M) c5 [0 y' D% P- E% P
    4 C6 b3 t2 U3 a4 u! b& I. n' T0 G8 P五、样式混合问题
    # ^8 R% @& v* B8 }( e+ c2 v! U5 B描述:不同组件中如果使用相同的class,会导致出现样式覆盖的问题,覆盖规则是父组件覆盖子组件子组件根据导入顺序,新的覆盖旧的。可以使用不同的类名进行区分解决问题,也可以使用scoped属性,对style属性我们还可以使用lang进行指定,我们是用Less还是用css, I4 `" H/ t! q9 z4 i
    原理:scoped会根据经纬度、时间、使用电脑型号等生成一个唯一id,然后将这个id插入到对应的标签内
    4 N( E9 F# w! Q* a2 ^ 再将相应的样式转换为标签属性选择器,进行样式语言的限定。默认选择css样式语言
    4 n( o# x- _/ O2 E8 B   b+ b9 B# }  N' a3 u% V2 v
    .demo{* n8 z: I* Z0 o
        background-color: red;" _$ i7 P/ v( S# E8 y
    }- z  t& C# `2 O' O

    9 h7 T3 l3 K7 M4 q' B . C$ \8 C" F' m/ V
    至此这几种属性或者使用语法就介绍完了,大家有啥疑问或者好的想法欢迎评论区留言。
    $ z# |- q9 Q* o. T. W
    5 l! a, A$ S! E3 R

    20221250.gif

    20221250.gif
  • 分享到:
    回复

    使用道具 举报

    回答|共 81 个

    我可爱的太阳

    发表于 2022-12-12 17:59:48 | 显示全部楼层

    在撸一遍。。。
    回复

    使用道具 举报

    邵奇微

    发表于 2022-12-12 18:02:44 | 显示全部楼层

    向楼主学习
    回复

    使用道具 举报

    其明

    发表于 2022-12-12 18:05:25 | 显示全部楼层

    路过
    回复

    使用道具 举报

    就一句

    发表于 2022-12-12 18:08:40 | 显示全部楼层

    学习IT中
    回复

    使用道具 举报

    思恋的风

    发表于 2022-12-12 18:10:24 | 显示全部楼层

    看起来好像不错的样子
    回复

    使用道具 举报

    真实的自我

    发表于 2022-12-12 18:12:38 | 显示全部楼层

    佩服佩服!
    回复

    使用道具 举报

    韩潮

    发表于 2022-12-12 18:16:07 | 显示全部楼层

    非常好,顶一下
    回复

    使用道具 举报

    晨曦余痕

    发表于 2022-12-12 18:19:06 | 显示全部楼层

    前排支持下了哦~
    回复

    使用道具 举报

    李三三

    发表于 2022-12-12 18:20:31 | 显示全部楼层

    非常好,顶一下
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    49 积分
    13 主题
    热门推荐