Vue组件学习相关

蔚落 2023-02-26 09:27 50阅读 0赞

组件相关知识
①组件注册:变量名大小写不敏感,全局注册共有三种方式:
Ⅰ:camelCase (驼峰命名法) 的 prop 名需要使用其等价的 kebab-case (短横线分隔命名)

  1. Vue.component('mycom1', {
  2. props: ['myCom'], // 在 JavaScript 中是 驼峰
  3. template: '<h3>第一种方式</h3>'
  4. })
  5. <!-- HTML 中是 短横线-->
  6. <mycom1 my-com="hello!"></mycom1>

Ⅱ:在外部template标签定义组件并引用id:

  1. //定义
  2. <template id="tmp1"></template>
  3. Vue.component('mycom2',{
  4. template:'#tmp1',
  5. })
  6. //使用
  7. <mycom2></mycom2>

Ⅲ:使用Vue.extend注册

  1. //定义
  2. Vue.component("mycom3",Vue.extend({
  3. template:'<h3>这是第三种方式</h3>'
  4. }));
  5. //使用
  6. <mycom3></mycom3>

②传递prop:
⑴除了传递字符串格式,其他对象数组数字等都需要用v-bind:作为表达式传递。
⑵传入一个对象的所有属性,可使用无参数无引号的v-bind来传递。
如:<blog-post v-bind="post"></blog-post>
⑶单向下行绑定,父级 prop 的更新会向下流动到子组件,应当防止子组件修改父级prop。可在子组件中定义初始值接受prop,再进行操作。
☆对象和数组是通过引用传入的,所以对于一个数组或对象类型的 prop 来说,在子组件中改变变更这个对象或数组本身将会影响到父组件的状态。
(4)子组件向父组件传参:通过v-on(@)监听事件的方式带参数过去。

  1. //子组件methods方法中触发父组件函数textChange
  2. <button @click="handleClick"></button>
  3. methods:{
  4. handleClick(){
  5. this.$emit("textChange","要传递的参数")//可通过emit的第二个参数往父组件传值
  6. }
  7. }
  8. //父:
  9. <ul-com :list="list" @textChange="handleTextChange"></ul-com>

(5)父组件传参给子组件:数据用prop和v-bind。方法用v-on/@。

  1. //父组件:
  2. <List-Item :list="list">
  3. //子组件:
  4. props:{
  5. list:Array
  6. }

③pros的type类型值:String Number Boolean Array Object Date Function Symbol

④prop 验证:

  1. Vue.component('my-component', {
  2. props: {
  3. propA: Number,// 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证
  4. propB: [String, Number], // 多个可能的类型
  5. propC: {
  6. type: String,
  7. required: true,// 必填的字符串
  8. },
  9. propD: {
  10. type: Number,
  11. default: 100, // 带有默认值的数字
  12. },
  13. propE: { // 带有默认值的对象
  14. type: Object,
  15. // 对象或数组默认值必须从一个工厂函数获取
  16. default: function () {
  17. return { message: 'hello' }
  18. }
  19. },
  20. propF: { // 自定义验证函数
  21. validator: function (value) {
  22. // 这个值必须匹配下列字符串中的一个
  23. return ['success', 'warning', 'danger'].indexOf(value) !== -1
  24. }
  25. }
  26. }
  27. })

⑤组件可以接收未定义prop的任意变量,且会自动添加到根元素上。
⑥父级提供给组件的值会替换掉组件内部设置好的值,而classstyle属性会合并传入的值和原有设定的值。
⑦禁用变量继承:inheritAttrs: false
⑧组件切换使用标签component :is="name",name是组件的名称。

自定义组件相关知识
①子组件可以使用 $emit 触发父组件的自定义事件。
②事件名会自动转换为小写。
③自定义组件的 v-model:

  1. Vue.component('base-checkbox', {
  2. model: {
  3. prop: 'checked',
  4. event: 'change'
  5. },
  6. props: {
  7. checked: Boolean
  8. },
  9. template: ` <input type="checkbox" v-bind:checked="checked" v-on:change="$emit('change', $event.target.checked)" > `
  10. })
  11. 使用:<base-checkbox v-model="lovingVue"></base-checkbox>

④将原生事件绑定到组件,可以使用 v-on.native 修饰符,
即:<base-input v-on:focus.native="onFocus"></base-input>
.sync 修饰符是update:myPropName的缩写,可实现安全的双向绑定。用法:

  1. <text-document
  2. v-bind:title="doc.title"
  3. v-on:update:title="doc.title = $event"
  4. ></text-document>
  5. //两者相等
  6. <text-document v-bind:title.sync="doc.title"></text-document>

<slot>插槽相关知识
①在组件中写入<slot></slot>,则在引用该组件时,可以包含任何模板代码:

  1. <navigation-link url="/profile">
  2. <!-- 添加一个 Font Awesome 图标 -->
  3. <span class="fa fa-user"></span>
  4. Your Profile
  5. </navigation-link>

②具名插槽,即在引用绑定多个<slot></slot>的组件时,使用v-slot的参数形式提供其名称达到一个个插的效果。★ v-slot 只能添加在 <template> 上。

  1. //base-layout组件
  2. <div class="container">
  3. <header>
  4. <slot name="header"></slot>
  5. </header>
  6. <main>
  7. <slot></slot>
  8. </main>
  9. <footer>
  10. <slot name="footer"></slot>
  11. </footer>
  12. </div>
  13. //v-slot写法
  14. <base-layout>
  15. <template v-slot:header>
  16. <h1>Here might be a page title</h1>
  17. </template>
  18. <template v-slot:default>
  19. <p>A paragraph for the main content.</p>
  20. <p>And another one.</p>
  21. </template>
  22. <template v-slot:footer>
  23. <p>Here's some contact info</p>
  24. </template>
  25. </base-layout>

③作用域插槽,可让父级读取子组件中的user数据。

  1. //current-user组件
  2. <span>
  3. <slot v-bind:user="user">
  4. { { user.lastName }}
  5. </slot>
  6. </span>
  7. //插槽prop
  8. <current-user>
  9. <template v-slot:default="slotProps">
  10. { { slotProps.user.firstName }}
  11. </template>
  12. </current-user>

⑴默认插槽可去掉<template>采用在<current-user>上写v-slot的缩写形式,但有具名插槽时必须如上分别写出来。
⑵解构插槽prop且重命名:

  1. <current-user v-slot="{ user: person }">
  2. { { person.firstName }}
  3. </current-user>

④具名插槽的缩写:v-slot用##后必须接参数,如#default#header等。

动态组件
使用<keep-alive>包裹的组件实例能在第一次创建时缓存下来。

  1. <keep-alive>
  2. <component v-bind:is="currentTabComponent"></component>
  3. </keep-alive>

边界问题
$root可以访问所有vue实例中的属性和方法。
$parent可以用来从一个子组件访问父组件的实例。

ref相关知识 ref获取到的是原生js的dom元素或者组件本身
①ref绑定在相关组件上如:<uni-popup ref="auth"></uni-popup>,在引入该组件的页面通过this.$refs.auth.clickLogin调用对应的方法。最常用。
②ref 需要在dom渲染完成后才会有,在使用的时候确保dom已经渲染完成。比如在生命周期 mounted(){} 钩子中调用,或者在 this.$nextTick(()=>{}) 中调用。

路由vue-router
①创造路由,传递一个配置对象:使用前需导入vue-router.js

  1. //组件的模板对象
  2. var login = {
  3. template:'<h1>登录组件</h1>'
  4. };
  5. var routerObj = new VueRouter({
  6. //routes表示路由的匹配规则
  7. routes:[//component表示显示path路径匹配到的组件的模板对象
  8. { path:'/',redirect:'/login'},
  9. { path:'/login',component:login}
  10. ],
  11. linkActiveClass:'myactive'
  12. })
  13. var vm = new Vue({
  14. el:'#app',
  15. data:{ },
  16. methods:{ },
  17. router:routerObj //路由规则对象注册到vm实例上,监听url地址的变化
  18. })
  19. <div id="app">
  20. //必须在html中定义router-view,作为组件显示的占位符
  21. <router-view></router-view>
  22. //<a href = '#/login'>登录</a>
  23. <router-link to="/login" tag="span"></router-link> //默认渲染a标签,tag可以改变渲染的标签
  24. </div>
  25. //给选中的组件变化样式
  26. //active-class可以在router-link标签上添加属性,默认值由路由的构造选项linkActiveClass来配置
  27. <style>
  28. .router-link-active{
  29. color:red;
  30. font-weight:800;
  31. font-style:italic;
  32. }
  33. .myactive{ ...}
  34. </style>

②给组件切换添加过渡效果:组件外可直接加transition标签设置切换动画效果。mode="out-in"常用。

  1. <transition mode="out-in">
  2. <router-view></router-view>
  3. </transition>
  4. <style>
  5. .v-enter,v-leave-to{
  6. opacity:0;
  7. transform:translateX(140px);
  8. }
  9. .v-enter-active,v-leave-active{
  10. transition:all 0.5s ease;
  11. }
  12. </style>

③路由规则中定义参数:

  1. var login = {
  2. template:'<h1>登录组件</h1>',
  3. create(){ //组件生命周期钩子
  4. console.log(this.$route.query) //query获取
  5. }
  6. };
  7. var register = {
  8. template:'<h1>注册组件</h1>',
  9. create(){ //组件生命周期钩子
  10. console.log(this.$route.query) //query获取
  11. console.log(this.$route.params)//params获取
  12. }
  13. };
  14. var routerObj = new VueRouter({
  15. routes:[
  16. { path:'/',redirect:'/login'},
  17. { path:'/login',component:login},
  18. { path:'/register/:id/:name',component:register},//id和name都是key的键名
  19. ]
  20. })
  21. var vm = new Vue({
  22. el:'#app',
  23. data:{ },
  24. methods:{ },
  25. router:routerObj
  26. })
  27. <div id="app">
  28. <router-view></router-view>
  29. <router-link to="/login?id=122"></router-link>//query方式传参
  30. <router-link to="/login/12/张三"></router-link>//params方式传参
  31. </div>

③使用children属性实现路由嵌套:

  1. <template id='tmp1'>
  2. <div>
  3. <h1>这是account组件</h1>
  4. <router-link to="/account/login"></router-link>
  5. </div>
  6. </template>
  7. var account = {
  8. template:'#tmp1',
  9. };
  10. var login= {
  11. template:'<h3>登录</h3>',
  12. };
  13. var routerObj = new VueRouter({
  14. routes:[
  15. {
  16. path:'/account',
  17. component:account,
  18. children:[
  19. { path:'login',component:login}//children的path不以/开头,否则永远以跟路径开头
  20. ]
  21. },
  22. //{path:'/account/login',component:login},子路由不能这么写
  23. ]
  24. })
  25. var vm = new Vue({
  26. el:'#app',
  27. data:{ },
  28. methods:{ },
  29. router:routerObj
  30. })
  31. <div id="app">
  32. <router-view></router-view>
  33. <router-link to="/account"></router-link>
  34. </div>

④使用命名路由视图:

  1. <template id='tmp1'>
  2. <div>
  3. <h1>这是header组件</h1>
  4. </div>
  5. </template>
  6. var header= {
  7. template:'#tmp1',
  8. };
  9. var main = {
  10. template:'<h3>中央</h3>',
  11. };
  12. var routerObj = new VueRouter({
  13. routes:[
  14. {
  15. path:'/',
  16. components:{
  17. 'default':header,
  18. 'main':main,
  19. },
  20. },
  21. ]
  22. })
  23. var vm = new Vue({
  24. el:'#app',
  25. data:{ },
  26. methods:{ },
  27. router:routerObj
  28. })
  29. <div id="app">
  30. <router-view></router-view>
  31. <router-view name="main"></router-view> //这是一个值
  32. </div>

常用属性
①input标签立定义@keyup来监听输入事件的改变。
②vm实例中使用watch:{}属性耶可以监视data数据的改变,出发watch中对应的function处理函数。

  1. var vm = new Vue({
  2. el:'#app',
  3. data:{
  4. firstname:'',
  5. },
  6. methods:{ },
  7. watch:{
  8. 'firstname':function(newVal,oldVal){
  9. console.log('监听到fistname的变化。')
  10. },
  11. '$router.path':function(newVal,oldVal){
  12. console.log('监听到路由路径的的变化。')
  13. }
  14. }
  15. })

③vm实例的computed:{}可以定义计算属性,计算属性本质是一个方法,但调用时把他当成属性在相应的html里调用。

  1. var vm = new Vue({
  2. el:'#app',
  3. data:{
  4. firstname:'',
  5. },
  6. methods:{ },
  7. computed:{
  8. 'fullname':function(){ //function内部涉及的任何data数据发生变化都会重新计算该计算属性的值
  9. return firstname + '-';
  10. }
  11. },
  12. })

watch:{}methods:{}computed:{}的对比:
(1)watch是一个对象,键是需要观察的表达式,值是回调函数,里面使用赋值方式;而computed里面的计算属性必须return一个值。
(2)computed只适合简单的数据操作,不需要做大量的业务逻辑;业务逻辑交给methodswatch
(3)computed的结果会被缓存,主要当成属性使用。

发表评论

表情:
评论列表 (有 0 条评论,50人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Vue学习相关

    组件相关知识 ①组件注册:变量名大小写不敏感,全局注册共有三种方式: Ⅰ:camelCase (驼峰命名法) 的 prop 名需要使用其等价的 kebab-case (

    相关 Vue相关引用

    Vue组件 可以理解为将多个小的东西封装成一个大的东西,然后可以直接对大的东西来进行操作,组件的核心是`VirtualDOM`(虚拟DOM) 组件在注册也分为全局组件与

    相关 Com相关学习

    一、C++和C\中COM组件的调用和使用问题       前一阵在工作中做项目的时候,遇到了COM组件的调用和使用问题,当时研究和好一阵,才把中间的环节打通,现在写出

    相关 Vue

    Vue组件 1. 什么是组件 1. 组件的概念:组件即自定义控件,是Vue.js最强大的功能之一 2. 组件的用途:组件能够封装可重用代码,扩展html标签功能