vue和mpvue

一、mixins的理解

    vue中提供了一种混合机制--mixins,用来更高效的实现组件内容的复用。最开始我一度认为这个和组件好像没啥区别。。后来发现错了。下面我们来看看mixins和普通情况下引入组件有什么区别?
     组件在引用之后相当于在父组件内开辟了一块单独的空间,来根据父组件props过来的值进行相应的操作,单本质上两者还是泾渭分明,相对独立。
     而mixins则是在引入组件之后,则是将组件内部的内容如data等方法、method等属性与父组件相应内容进行合并。相当于在引入后,父组件的各种属性方法都被扩充了。
     单纯组件引用:
          父组件 + 子组件 >>> 父组件 + 子组件
     mixins:
          父组件 + 子组件 >>> new父组件
 
     值得注意的是,在使用mixins时,父组件和子组件同时拥有着子组件内的各种属性方法,但这并不意味着他们同时共享、同时处理这些变量,两者之间除了合并,是不会进行任何通信的。
// App.vue
<template>
    <!-- ... -->
</template>
<script>
    import {mixin} from "./base.js";    // 导入混合对象

    export default {
        mixins: [mixin],    // 记得一定要添加 mixins 属性,要求赋值一个数组,意味着可以使用多个混合对象
        // ...
        created:function(){
            console.log('组件钩子被调用')
            this.foo();
            this.conflicting();
        },
        method: {
            conflicting(){
                console.log("from self");
            }
        }
    }
</script>   

    混合 (mixins) 是一种分发 Vue 组件中可复用功能的非常灵活的方式。 
  混合对象可以包含任意组件选项。 
  当组件使用混合对象时,所有混合对象的选项将被混入该组件本身的选项。

  混合对象的使用主要是在项目中提取出常用的公共方法,提高代码的重用率。

//可以把小程序分享代码抽离出来 vue组件中import引入 mixins声明
export default {
  onShareAppMessage () {
    return {
      title: '小程序分享',
      path: '/pages/index/main'
    }
  }
}

二、Vue的计算属性:computed

1.在computed属性对象中定义计算属性的方法,在页面中使用{{方法名}}来显示计算的结果。

2.通过getter\setter实现对属性数据的显示和监视,计算属性存在缓存,多次读取只执行一次getter计算。

<div id="demo">
        姓:<input type="text" placeholder="firstName" v-model="firstName"><br>
        名:<input type="text" placeholder="lastName" v-model="lastName"><br>
        姓名1(单向):<input type="text" placeholder="FullName1" v-model="fullName1"><br>
        姓名2(双向):<input type="text" placeholder="FullName2" v-model="fullName2"><br>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    const demo = new Vue({
        el : '#demo',
        data : {
            firstName : 'A',
            lastName : 'B',
            fullName2 : 'A B'
        },
        computed : {//计算属性相当于data里的属性
            //什么时候执行:初始化显示/ 相关的data属性发生变化
            fullName1(){//计算属性中的get方法,方法的返回值就是属性值
                return this.firstName + ' ' + this.lastName
            },
 
            fullName3 : {
                get(){//回调函数 当需要读取当前属性值是执行,根据相关数据计算并返回当前属性的值
                    return this.firstName + ' ' + this.lastName
                },
                set(val){//监视当前属性值的变化,当属性值发生变化时执行,更新相关的属性数据
                    //val就是fullName3的最新属性值
                    console.log(val)
                    const names = val.split(' ');
                    console.log(names)
                    this.firstName = names[0];
                    this.lastName = names[1];
                }
            }
        }
 
    })
 
 
</script>

改变姓和名时,对应的姓名1和姓名2会发生改变。

改变姓名1时,姓和名、姓名2都不会改变。

改变姓名2时,对应的姓和名,以及姓名1也会改变。

三、关于 $emit 的用法

1、父组件可以使用 props 把数据传给子组件。
2、子组件可以使用 $emit 触发父组件的自定义事件。

vm.$emit( event, arg ) //触发当前实例上的事件

vm.$on( event, fn );//监听event事件后运行 fn; 

例如:子组件:

<template>
  <div class="train-city">
    <h3>父组件传给子组件的toCity:{{sendData}}</h3> 
    <br/><button @click='select(`大连`)'>点击此处将‘大连’发射给父组件</button>
  </div>
</template>
<script>
  export default {
    name:'trainCity',
    props:['sendData'], // 用来接收父组件传给子组件的数据
    methods:{
      select(val) {
        let data = {
          cityname: val
        };
        this.$emit('showCityName',data);//select事件触发后,自动触发showCityName事件
      }
    }
  }
</script>

父组件:

<template>
    <div>
        <div>父组件的toCity{{toCity}}</div>
        <train-city @showCityName="updateCity" :sendData="toCity"></train-city>
    </div>
<template>
<script>
  import TrainCity from "./train-city";
  export default {
    name:'index',
    components: {TrainCity},
    data () {
      return {
        toCity:"北京"
      }
    },
    methods:{
      updateCity(data){//触发子组件城市选择-选择城市的事件
        this.toCity = data.cityname;//改变了父组件的值
        console.log('toCity:'+this.toCity)
      }
    }
  }
</script>

四、在使用vux这个ui库的时候,有许多自定义组件Flexbox、FlexboxItem。。。。。,在纯弹窗类组件比如 Alert Popup XDialog 等组件上使用 v-transfer-dom 实现自动移动到 body 下

https://doc.vux.li/zh-CN/directives/v-transfer-dom.html

//注册局部指令
import { TransferDom } from 'vux'

export default {
  directives: {
    TransferDom
  }
}



//注册全局指令
import { TransferDom } from 'vux'

Vue.directive('transfer-dom', TransferDom)


//在模板中使用
<div v-transfer-dom>
  <popup v-model="show"></popup> <div>

五、mounted和methods的区别

首先讲一下vue的生命周期

beforecreate : 举个栗子:可以在这加个loading事件 

created :在这结束loading,还做一些初始化,实现函数自执行   (data数据已经初始化 但是 dom结构渲染完成 组件没有加载)

mounted : 在这发起后端请求,拿回数据,配合路由钩子做一些事情  (dom渲染完成 组件挂载完成 )

beforeDestroy: 你确认删除XX吗?(简单来说  就是组件还存在)

 destroyed :当前组件已被删除,清空相关内容  (组件已经销毁 )

所以说  mounted 是生命周期方法之一,会在对应生命周期时执行。

而   methods 是Vue实例对象上绑定的方法,供当前Vue组件作用域内使用,未调用不会执行。

六、vue中永远不要把 v-if 和 v-for 同时用在同一个元素上

一般我们在两种常见的情况下会倾向于这样做:

  • 为了过滤一个列表中的项目 (比如 v-for="user in users" v-if="user.isActive")。在这种情形下,请将 users替换为一个计算属性 (比如 activeUsers),让其返回过滤后的列表。

  • 为了避免渲染本应该被隐藏的列表 (比如 v-for="user in users" v-if="shouldShowUsers")。这种情形下,请将 v-if 移动至容器元素上 (比如 ulol)。

//错的栗子
<ul>
  <li
    v-for="user in users"
    v-if="user.isActive"
    :key="user.id"
  >
    {{ user.name }}
  </li>
</ul>


//正确的,使用计算属性
computed: {
  activeUsers: function () {
    return this.users.filter(function (user) {
      return user.isActive
    })
  }
}

<ul>
  <li
    v-for="user in activeUsers"
    :key="user.id"
  >
    {{ user.name }}
  </li>
</ul>

我们将会获得如下好处:

  • 过滤后的列表会在 users 数组发生相关变化时才被重新运算,过滤更高效。
  • 使用 v-for="user in activeUsers" 之后,我们在渲染的时候遍历活跃用户,渲染更高效。
  • 解藕渲染层的逻辑,可维护性 (对逻辑的更改和扩展) 更强。

同理:

<ul>
  <li
    v-for="user in users"
    v-if="shouldShowUsers"
    :key="user.id"
  >
    {{ user.name }}
  </li>
</ul>

//更新为

<ul v-if="shouldShowUsers">
  <li
    v-for="user in users"
    :key="user.id"
  >
    {{ user.name }}
  </li>
</ul>

通过将 v-if 移动到容器元素,我们不会再对列表中的每个用户检查 shouldShowUsers。取而代之的是,我们只检查它一次,且不会在 shouldShowUsers 为否的时候运算 v-for

猜你喜欢

转载自www.cnblogs.com/gavinjay/p/10677794.html