回答

收藏

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

技术问答 技术问答 175 人阅读 | 0 人回复 | 2023-09-11

文章目录: r' Y9 C) {( ~+ N/ o
0 E# D9 y/ x1 _4 x( ^7 j( W, e
前言
$ ?& g% u) \8 s一、ref属性的使用
$ J% ^2 d* K" L! |8 k) o! B二、props配置
& u8 j! M1 E2 l& F- z% }; [三、mixin混合语法
2 D  |: ~2 J3 W9 s" q/ l% u4 c. q9 a, y# E/ r  y' _
1.简介
3 O# B2 n* d5 `6 z2.使用方法% ]: {# {3 p2 M" V1 m+ g6 ]
3.注意点
) E) l3 P" q" y4.结合实例使用" h0 a+ V6 P; E5 D) L; g

- P8 v/ X" x8 P- {* v2 Y* K①全局混入6 E1 x7 ^$ v7 I; [
②局部混入
" q- G; X% F: F% C3 l1 }: e
   
9 |6 c2 n5 c1 n( Z9 V# I
   四、插件的使用$ {/ N! i; R8 Y6 v# q+ Z, |

% Z3 o' B6 j/ K; E8 |- n1.插件语法
8 T  M' c* L* g$ y8 L
7 h% `9 R9 |* i- w①定义插件
& h* k+ |6 Z$ V7 L②引入插件并使用
6 M5 ~8 d8 q( s% P6 f5 Q
    2.上手插件
! B3 x5 n. s  r5 Q& w8 v+ j5 m, T5 H
   五、样式混合问题
4 z' k* N0 W2 i5 ]. i7 w9 a

' k  p; J5 r2 k# G8 L 8 H4 H$ b$ K" H; q! c6 J/ s
前言
( S( c( w/ j# R1 \0 N/ d 4 v* `+ J) ~( U
在前面介绍到了Vue的一些基本概念与如何使用Vue,并通过node中的npm 使用vue脚手架(vue-cli)搭建了一个简单的Vue应用,其实所有的Vue项目搭建的时候都是换汤不换药。今天将会介绍几个Vue中常用的配置,他们的大致功能如下:
; [9 L, p. }/ B
5 s1 A  G8 ]  C# i) cref 作用是将dom元素选择出来,对普通标签来说与document.getElementById(“xxx”)是一回事,对自定义组件来说会将Vue Componentd对象选择出来,获取到VC对象也就可以获取到其中的dom元素了。$ E0 L1 F* ~/ V
props 作用是父组件向子组件传递数据(当父组件有更新的时候子组件也会有更新)
5 E, |% O7 e! Umixin 将组件公共部分提取出来,哪里用到就在哪里引用
# R( W$ J7 _7 S4 M0 q插件 别人写好的js文件,我们只需引入并use即可(这里要区分好组件与插件). f7 t' `5 C3 v. n1 P
样式混合 如果给组件的style不加scoped将会导致样式的混乱
1 e7 L; \2 l( X4 w
有了大概的预览之后就可以进行深一步的学习了,将会配合一些代码实例进行叙述。
' c/ \$ g8 _$ M& E8 L 1 `% c1 u* I, A1 P' r: Y1 @
一、ref属性的使用 7 Z* e6 z+ o# e+ `2 x, v3 D' G

8 h6 f8 _; t3 e4 i7 J 大家在学习css的时候学过各种选择器,也学过使用css选择器将dom元素选择出来,这个属性的话起到的作用就是将想要的dom元素选择出来,根据ref属性可以很轻松的找到dom元素。  H# v8 W0 d, o! @
* i" H" L( t3 N: J8 R
+ M7 X/ b) c1 J: j
[ol]被用来给元素或子组件注册引用信息(可以认为是id的替代者)
/ H, ?$ E2 _) i6 I! B' d- f标记在html标签上可以获取真实DOM元素& Y, D' H3 ^, T  ~1 n* V3 L
标记在组件标签上可以获取组件实例对象(vc)
# h( Q$ A$ w4 E7 Q* I( ^% E+ k一句实例对象可以进行自己想要的操作
" D. W$ w; _  K$ |' c使用方式: + r9 n7 t" D( T6 z
  [ol]给元素打标识:3 A, S+ E" I1 E0 j9 S
①. .....7 |$ o" b' t+ h% Q6 I+ N
②.
- r- I5 ^9 _- n% U: l" E; x ③. 获取元素:this.$refs.xxx[/ol] [/ol] ( F3 `) i- z" |6 I8 F% D
结合以下实例代码:( Y4 T- M! m& y
App.vue( J$ {' d1 S3 b- l1 J; c( X& L
' z# y' P. O+ ]0 u4 S) P

, C9 _1 D6 @0 ]. u" n0 p' |  
( B$ V# s4 v, z+ w      Hello World
2 x9 d5 U8 K7 |  g- K/ T, z      
; f' {$ o+ p6 s8 ?/ Q/ n      点我体验ref
4 k4 T+ ^" {  Y  
' n2 ^4 E6 n3 L/ z2 Z7 x
% m, Y1 b) ~$ Q$ W% E6 W7 C) H( u" \; `
( s; H5 L' w; B, D4 X- t3 Y
- N) f! e. t* D+ c& t4 g2 V8 @
Student.vue
# j6 I7 h) ?0 p! B( g" M: n ; N5 B  }; x! o/ ]* b1 D' x& v
  2 D& ?  X! B/ H$ Q9 Z3 \
      我的名字是:{{name}}1 G% `+ l! M4 o: d% }
      我的年龄是:{{age}}
! _% F4 O5 x; _6 [* s0 K      
7 W4 p, L6 q; W1 P+ T8 ?5 c3 V[img][/img]: Y( ~: C& C6 |) I
: {. _! \7 q1 c7 y0 N
  5 B+ H9 i. k5 k5 g$ I2 O0 A. [
( |, z( u6 D" q% [$ \
6 K( ~0 I0 o8 Q, H+ y2 Y4 B6 K4 k
.demo{
) Y+ {: p6 V* r0 q) l" a: i    background-color: rgb(173, 167, 167);* M( G: h& ?$ j& x- G: B
}
+ k+ J4 r" Z; M
1 e/ H: }' R" C+ H7 N5 U7 O3 N/ ]( @8 B' O! `! Z

7 K- r9 E5 q6 f  N0 t, W: ~( J, \* o+ s1 r  {4 A3 ]- z0 q
& `2 w  z) E# d5 V0 w: q' K; Q, Y
二、props配置
" M9 _6 _3 |  ]- b[ol]功能:让组件接收外部传过来的数据
# Z. j  d. w5 w1 @/ |' k6 D0 Q传递数据:# e+ O5 H* X- P/ B+ J7 `
接收数据: 6 }' E4 Q) a$ \
  [ol]第一种方式(只接收):props:['name']
/ W, g6 E3 h/ T; ?. Q1 F, O0 ?第二种方式(限制类型):props:{name:String}. ^. E% f( W' z! j* I- g4 b6 J
第三种方式(限制类型、限制必要性、指定默认值):props:{# d8 ]  n# K" \) x4 @! j6 Q
        name:{
9 ?/ X; ^# a/ V        type:String, //类型
2 U4 ^0 K. \9 n! H        required:true, //必要性
2 j6 L2 x& d) ~$ `$ S2 c- Q( o) x        default:'老王' //默认值
# y- E! ]( I' C: Z  \        }6 w' e, r; j. ^: A6 F0 K. M% r+ m: N
}
; w% R8 C8 S9 O. I [/ol] # W2 q! U" l* e& J3 P& f
   ! ^- \& G6 l$ g/ ~' z
   注意:props是只读的,Vue底层会监测你对props的修改,如果进行了修改,就会发出警告,若业务需求确实需要修改,那么请复制(将数据复制到其他对象内)props的内容到data中一份,然后去修改data中的数据。props接收到的对象被替换掉会有waring 但是props对象内部的属性被替换掉编译器不会发现,但是我们一般不这么做。因为存在隐患。/ b' r; [* B, Z  @8 D( }

4 Y6 S& z; W$ \2 P  P2 N. M5 u2 o& b  
[/ol]
  t1 U/ F; @3 L3 J. [! S当父组件中传给子组件的属性发生改变时,会触发模板的重新解析,如图所示。改变的是父组件传过去的name,会引起子组件接受到的属性发生改变。3 G- t% S- ^$ o" E. a& O. R% h. G

2 B  O' q9 A. m6 ~" j0 r8 t
1 w4 ]$ v3 ~, o4 N 代码如下:
4 N8 {5 F9 e3 C. E: [6 X5 {+ K ! c" m1 S- @: R2 O
App.vue% j/ k8 q: h# R2 X  [

/ q2 @9 ]5 w2 \# p+ `; X7 M, g  
" s6 v# }0 `0 c6 L5 l      
  X' w0 l9 ]) g/ q) Q7 l      点我改变传过去的props2 Y* @! ?$ h% a3 d" `0 ]/ {; ?/ g7 f
  
8 d6 [* H* _7 V+ X# O$ w
4 L, K1 R, Q! @1 j! V" z" X/ _$ X' F/ e3 p
: v3 m3 E0 M) r; E0 x
3 x6 W, R- G: Z- h) t3 R
Student.vue
. s& F$ f0 H4 ?2 t
! A4 ~7 G! y9 [* V2 Q( [/ A" r& `    # b2 D) Z. s5 @3 ]+ L2 _
        我的名字是:{{name}}        
; @$ F' k: n8 a% X$ [        我的名字是:{{newAge}}岁了* [; }- Q" ?8 e) I0 w: R, B" B' y, q
        点击我进行年龄加1        
! H0 A5 d: `; Q( o    4 K- B) H) l' u! H# R$ i/ F+ C

7 G+ Y, z) R) q* R
2 B2 S; N  _' K) Y  [.data{
) N  L% c) ^) y$ W: s# k8 c! e    background-color: rgb(202, 190, 190);
& U  D7 ?# y+ q6 U! S}
; Y, g4 ~" Z9 W% B( ]/ O1 ` 3 ]: h' O, Y0 j1 s& E3 W% v9 l
三、mixin混合语法
) ]6 m' P  E9 G) z9 H& Y5 c3 v1.简介 1 @0 y' G0 V' s  d  L* K
& [1 j: B* V/ ^% ~; u
mixin可以大大的提升代码的利用率,把多个组件需要的功能提出到一个文件内
) M" a) S! l5 s5 F6 B% Y 如果mixin限定在main.js上,那么这个程序所有组件都会有* J+ o7 J6 t; @, ^) R* g% ]9 l4 Z
3 X) D  B# X& e, @9 o+ B: ]

4 w: `) c  W+ b0 ~( x3 o2.使用方法   m/ X  Z( {$ g# C6 K
[ol]在mixin.js中定义要混合的代码,组件中引入,并显示调用mixin属性mixins:[]其中mixin后面跟的必须是一个数组( h" }- R+ E0 b7 @3 W
在main.js中开启全局配置[/ol]
; d9 K. [+ y* u2 o' g& d* k3 @3.注意点
5 n. f! A. T% `+ v+ Y' M. H如果你的组件中定义了与mixin中相关的代码,脚手架会以你定义的代码为基础(也就是组件中定义的代码优先级大)
3 S1 z% \4 c- E. M! N但是一些特殊函数例外,比如mounted挂载函数。声明周期函数会先执行混入代码再执行自定义的代码+ F4 ^" N6 V# y+ p3 r3 P
8 d+ D% _; g1 y7 R2 J) l
4.结合实例使用 0 j; e; ?2 W1 K+ Q3 i" o; l. i
混入的生命周期函数会先执行,然后执行组件内定义的生命周期函数,普通函数是以组件内定义的为基础,如果组件内没有定义会以混入的函数为基础,如果两个地方都没定义就会抛出异常。, i# u" t$ H( l1 w5 {" i
5 n' P1 U6 u! j( {& j
- x: Y' X3 S& }
# L; ^& J3 Y% \# t
①全局混入
0 ?- K) {! {- p% a! N( ?" Z全局混入通常在main.js中进行定义,然后在所有的组件中均可以使用(不需要再定义属性mixin)" ^3 |. @6 P# k4 I2 H
语法如下:+ s2 t7 E4 Y1 {+ `# N2 Z& t
main.js! R0 d) ^+ K" U

) X3 y  ~4 S1 _/ T: U7 w// 导入即将混合的代码
0 o2 l4 U* v# S; c9 d  [% K- Pimport {mixin1,mixin2} from "./mixin"5 Y. n, r8 i9 D" `. x! B
// 开启全局的混入(合)
: S. J- I" {5 ]" ?3 B3 {7 I& u+ WVue.mixin(mixin1)
0 C& w) j, j/ }/ J2 S- TVue.mixin(mixin2)
$ W" D/ Y5 Z  q) E% Y2 ?8 E
% p: \0 u% j, @* k0 d②局部混入 7 }, C% `' U. N! u. s, N
局部混入的代码需要先进行mixin的引入,然后将其写进Vue Component对象的属性内也就是前面使用方法中介绍到的mixins:[xxx,xxxx]。* _; l0 z) g: i
下面是App.vue中的一部分代码:  d( D% s" s2 a4 r" I  ^. R3 R4 \
7 c' U: _: r7 D; ?
import {mixin1,mixin2} from "./mixin"
! ^  s+ [0 V& M" gexport default {; ^9 X5 {( ~( S5 I$ L
    name:"App",, S# n7 U: [" M+ U  l& H! ]
    components:{0 q! I5 T( F1 i
        Student,
4 t2 r3 D* E) }& u9 v        School# U$ c. k5 f& R/ G, y+ l* ^  s
    },3 l: p) Q; q. s* d
    mixins:[mixin1,mixin2]
0 T: ^' r- K9 k9 |) K3 e- U# {}, l3 M: m  Y" S( L) e$ E1 L
, q) r0 ?/ f( B/ K, C5 ]: d
当然在体验局部混入跟全局混入的区别时,也可以通过以下一个实例:
% y; e( P4 K6 q' J+ ^ 当打开全局混入时,不必使用mixins,即使使用了mixins,普通函数会以你定义的代码为基础。
: f7 u  M6 m) a' x: P6 m  E test.html+ k9 t( y3 `; w: J6 f9 c0 \: l5 s
, f* n+ X- g0 o5 N9 Y! j0 l% [

$ X; A  y, ]- L
) C* h, U* ^4 R9 e( ^& kVue 测试实例 - 菜鸟教程(runoob.com)
: l' l2 F; k! }! V+ T+ w
/ o8 f0 c' a' N9 l/ ?! i1 O5 I+ A. X: N; ^3 p; V

( H3 B- g5 M. n6 D; F- _8 M  t6 u四、插件的使用
- w$ a) i$ t1 ^对vue的一种增强,包含一个install方法的对象,install方法第一个参数是vue,第二个以后的参数是使用者传递的参数9 `" _* Z: |) F7 K
* X# O: W; t9 [1 y2 s. m
1.插件语法
, y  T0 P/ P5 y- E! g! {3 x! j①定义插件 8 z4 o" ?; Y% k& X- G' _9 y! X6 O
```js- u" c( W5 w2 h+ I+ e0 R2 W
const plugins={
% x  ~' V% T' i+ R, [3 P; I        // 这里install其实是一个属性
  {2 H) S8 I6 S( P- u2 u% S        install(vue,x,y,z){6 C$ x5 C$ n* R: A! d
                ....
: I% {0 L. t9 t' G. e, X' J        }0 d* x: O- G$ u" s" z+ l
}0 [5 L1 n, i# x0 t" X3 u$ Z
export plugins
6 b3 `) @9 s5 z/ _```
! A" k: P7 R+ d/ F& p4 c
( S" a( [2 H  g+ S②引入插件并使用
! y# \: y& Y) |$ y9 H3 I. vimport ... from ....
" c1 d5 ?" [0 I* B. nVue.use(...,参数1,参数2....)
% p/ D# R! G' y! O; ]' `8 w
7 |9 [7 w( R, s5 s/ G2.上手插件 # I5 Y, ?7 d/ O; E4 s& I( V2 {
自定义插件一般放在plugins目录下,网络上也有许多大牛定义的插件,只需引入使用即可;接下来带大家自定义一个插件,并导入Vue项目进行使用。8 r4 M! A. U( w+ A8 s

% z1 c$ b6 i) z# T# vplugins.js
8 ^, T, S& H  {: C: Z2 t4 r 5 ]8 i' Q' F/ |, N5 G$ y1 L9 c
const plugins={
4 n# p0 v* d' U! i- l    install(Vue,x=0,y=0,z=0){3 [2 {. }" P( X3 k
                console.log(x,y,z)
' U! g% ?+ @3 Q+ ~0 ?) W) o                //全局过滤器0 `- e6 m  b. b
                // 使用到这个过滤器的地方将会只显示列表中的前四个元素. q5 }! P; r, g6 ?- w, B: Y3 H* |
                Vue.filter('mySlice',function(value){+ \6 H3 u8 o, W" }/ [
                        return value.slice(0,4)
$ o- p/ F0 ?, }                })% A+ X( e& y7 @! s. f) E
                //定义全局指令9 r, I& D2 {2 W9 Q" o. l
                Vue.directive('fbind',{
3 t; H: z7 ^  U/ y9 E                        //指令与元素成功绑定时(一上来)/ {" P+ `- c1 M0 A: C$ }
                        bind(element,binding){% }9 r% [! f5 G' s9 m9 `# e
                                element.value = binding.value
/ x* p3 l* G8 L  n7 e. j# A+ G                        },0 R7 i0 t* \' d- a
                        //指令所在元素被插入页面时( K! K: N3 r3 Z+ @! |; S
                        inserted(element){* `3 ^* C5 w! T! [+ p5 b
                                element.focus()
4 x* N; S: j% `& ~: U2 \  v                        },
5 p( n( E: }! j2 A: @0 O  h  v  Z                        //指令所在的模板被重新解析时
" D4 {& \; z% `8 O                        update(element,binding){
: ]5 |" a1 ?% f) s4 x2 r, v3 }9 c                                element.value = binding.value, Q3 A" m5 J% K" L4 q# i
                        }0 G% `! K3 k  r: w8 S
                })
0 G9 {) D) J- @, |$ a+ a! K                //定义混入5 M, {, X9 O' M+ A- Q
                Vue.mixin({
+ u4 w% O4 p( v6 ?3 |7 d( b) u7 G                        data() {
' f6 }1 f* M3 L  u                                return {
# }, a4 l5 `- ]+ s3 G" P                                        x:100,
# @: ]; {* ]# t7 n& Z                                        y:200
' _; y, N8 E$ R9 x8 a                                }
' n$ [: |. {* D* Y                        },, k0 Q5 F# I0 b2 r4 j
                })
2 u) L% k+ q8 k% i3 ]                //给Vue原型上添加一个方法(vm和vc就都能用了)
8 g- k0 L6 T1 D. j                Vue.prototype.Hello = ()=>{alert('你好啊')}
; c0 c/ V+ p" Y7 y3 L        }) P" x: @' L9 H  g" Z3 t# A! k( A
}7 x# U+ p+ T" I; S# s
//暴露出去( D' L4 b: [6 z: u' B
export default plugins6 p  p( ]0 u4 b% o6 j
: W; Z) P6 _1 {
引入并使用插件1 k; Q8 z1 T/ ]* y: v, ~
main.js" |8 V* y' y0 S6 n( z* m

. a  p: }, m" F" L0 v1 _* T+ ]import App from "./App.vue"  _, e  j, ?8 y/ S/ J
import Vue from "vue"( h4 B1 C$ M$ a* {7 C( j/ ?
//导入插件
4 a* x4 |1 r9 }9 a# h/ J4 Timport plugins from "./plugins"
; r6 b" R* u% m, Q% Y//注册插件/ [6 q. B4 _, e# p* t
Vue.use(plugins)4 p7 q& F1 e; u" g+ N
new Vue({
) ?% U# v1 e) n% `    el:"#App",
$ W" d* d. O* T/ R3 i# |5 D    render:h=>h(App)
0 j  P0 l/ a9 F; e) S})
$ {2 f; t6 W4 Q! c4 a  k3 G
: ?+ d3 F3 p0 V使用插件中的自定义指令5 o& ^. c3 p9 @) C7 `* G6 T' r

' F4 G! s5 V" B7 f  * N1 T0 r8 O, w! f2 z" ~! e
      姓名:{{name}}
% O( t+ Q4 X% N& x. U6 d. u      年龄:{{age}}
6 A* g9 G$ s% ?1 b; v      <i>
* L9 y( ^# t6 Z  `- u" ]7 [  $ d2 a3 g: h4 d* ]! r* z! K2 x
' u2 x* w: w2 }# g

9 K) Y- @* e9 j: ]5 Y' {  d7 F: d3 Y4 G1 A, d$ i

1 q& ^2 s$ F6 T; E+ e; O  V! S+ q# S五、样式混合问题 5 ?" X) W/ D- j. c6 ^% A, p
描述:不同组件中如果使用相同的class,会导致出现样式覆盖的问题,覆盖规则是父组件覆盖子组件子组件根据导入顺序,新的覆盖旧的。可以使用不同的类名进行区分解决问题,也可以使用scoped属性,对style属性我们还可以使用lang进行指定,我们是用Less还是用css
/ Q! k4 O. Z4 @9 s 原理:scoped会根据经纬度、时间、使用电脑型号等生成一个唯一id,然后将这个id插入到对应的标签内
8 u; Y' i0 C5 W( G" ?0 s& U 再将相应的样式转换为标签属性选择器,进行样式语言的限定。默认选择css样式语言% N* D. P5 J0 H0 Z/ X
: Q! P& A5 u% ]8 G6 ]. M% j( E
.demo{6 d- s  f( P/ a9 k
    background-color: red;1 U# B: q: ^5 `; s
}
' n# U1 C: ~% n+ A
# Y; O% q2 s0 H4 m: ^" M7 s% _
  V' T/ W1 r- W# ]* \! X/ q: F至此这几种属性或者使用语法就介绍完了,大家有啥疑问或者好的想法欢迎评论区留言。% u, s& b8 I- F' v0 D0 L
8 ]- z0 c/ a5 t9 Z6 |" h$ a2 H
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则