vue2实践(延续更新)

纪录一些小技能和踩过的坑

由于本篇文章内容太多,致使SF编辑器有点卡,所以新拓荒了一篇 vue2实践(二),后续再这里更新。

1. props 带不带冒号的区分

 <child1 ref="child1" msg="{name:'bill'}"></child1>
 
 <child1 ref="child1" :msg="{name:'bill'}"></child1>

起首冒号是v-bind的缩写,不带冒号背面是字符串,带了冒号就是数据绑定,引号内里的内容是变量或许表达式,
组件内不能修正props的值,同时修正的值也不会同步到组件外层,即挪用组件方不知道组件内部当前的状况是什么

vue 组件props通报时,为何有时刻须要加冒号,有时刻不须要?
如安在Vue2中完成组件props双向绑定

2. computed属性,能够set,然则设置的是data返回的数据,不能设置本身。

假如盘算属性是对象的话,能够设置他的属性。

3. 组件的性命周期函数是在template标签里的数据发生变化时刻触发update

数据能够更新了,然则没有绑定到dom上面的话,不会挪用update钩子函数。

4. 给变data的第二季属性的值,data不会更新,致使组件不会更新

所以在这个时刻应当用Object.assign()从新天生新的对象。第一级属性值更新的话,data是更新的!

5. 动态绑定style的话,背面的款式值不能加分号

  style = {
              color: "rgb(66, 180, 232)"
       };
  //下面衬着不出来
    style = {
              color: "rgb(66, 180, 232)";
       };

6. filter 过滤器

vue2.0 的时刻把过滤器移除了,如今2.10又加了上去,

定义filter过滤器:
写在实例Vue内部的是部分过滤器,

new Vue({
  filters:{
  formatMoney: function (value){
      return "$"+value.toFixed(2);
   }
 }
})

写在外部的是全局过滤器

Vue.filter("money", function (vaule, type) {
    return "¥" + vaule.toFixed(2) + type;
})

组件内挪用:

<span v-text="message | wrap 'before' 'after'"></span>//1.x的写法,2直接wrap('before','after')挪用
Vue.filter('wrap', function (value, begin, end) {
  return begin + value + end
})

补充下:一个竖线 | 在js中是二进制运算

想问一下这个用竖线分离隔是什么意义

7. watch监测对象或许数组,不是替代对象或许数组,newVal和oldVal是统一个值。

注重:在变异(不是替代)对象或数组时,旧值将与新值雷同,由于它们的援用指向统一个对象/数组。Vue 不会保留变异之前值的副本。

vm.$watch

8. 为组件绑定原生事宜

有时刻,你能够想在某个组件的根元素上监听一个原生事宜。能够运用 .native 润饰 v-on 。比方:

<my-component v-on:click.native="doTheThing"></my-component>

9. 2.1.6computed在beforeMount前面实行的,vue2.2.1恰好相反

10. v-for和v-if在统一个标签运用的话,v-for的优先级高于v-if

假如在统一标签运用,v-if就是用来过滤v-for内里的数据的,先走if的话用template套在表面

本日并列运用的时刻碰到的巨坑:

<topic v-for="(topic,idx) in topics" :model="topic" :showIdx="false" :clickHandler="handleTopicClick"  v-if="mode==0"/>
<school-topic v-for="t in topics" :model="t" :style="showStyle(t)" :clickHandler="handleTopicClick" v-else />

结果topics只要三条数据,然则衬着出9条数据,官网说的很清晰:v-for with v-if

11.keep-alive 缓存组件在内存中,再次进入该页面不会从新衬着,用于保留页面的原始状况

<template>
    <div id="app">
        <keep-alive include="SelectTopics">
            <router-view></router-view>
        </keep-alive>
    </div>
</template>

纵然设置了keep-alive组件的beforeUpdateupdated钩子函数照样会挪用的。

activated和unactivated钩子是在keep-alive组件内里被挪用的,不是第一次进入keep-alive组件的话,挪用递次是:
beforeEach->beforeRouteEnter->activated->beforeUpdate->beforeRouteEnternext函数

也能够在脱离页面的时刻手动烧毁改组件:

 beforeRouteLeave(to, from, next) {
    if (to.path === "/examcentre") {
        this.$destroy();
    }
    next();
 }
//或许
  deactivated: function () {
    console.log(4)
    this.$destroy();
  },

有时刻依据需求(比方该组件是复用的)须要在再次进入该页面的时刻从新从背景猎取数据,那末能够在activated钩子函数中要求数据来update页面。

vue.js 可否设置某个组件不被keep-alive?
vue2.0 keep-alive最好实践
Vue怎样做到行进革新数据,退却不革新数据呢?
<keep-alive>组件缓存题目
Vue路由开启keep-alive时的注重点
vue.js+vue-router+webpack keep-alive用法

浏览器的行进回退并不会走dom绑定的行进退却的事宜

所以要想消灭vuex state内里的数据的话,能够放在beforeRouteLeave内里做处置惩罚。

 this.$store.commit("SET_PAPERATTRIBUTE", {}); 

弹窗组件

mint-ui 中的Toast MessageBox Indicator 挪用的体式格局是Toast('提醒信息');或许在全局引入mint-ui然后再组件里this.$toast("提醒信息"),这类体式格局和我们一般的引入组件的体式格局都差别,一般我们是在模板里直接将组件放到模板内里,这就意味着父组件在render的时刻,子组件也被render到了dom内里:

<template>
    <div class="my-set-attr-wrap">
        <set-attribute ref="setMyAttr" :style="setAttrStyle" :model="attributeModel" />
    </div>
</template>

this.$toast("提醒信息")这类是在函数中挪用,一定也是要render到dom内里的,改咋办呢?检察了mint-ui的完成体式格局:document.body.appendChild(instance.$el);
目次:

《vue2实践(延续更新)》

TopicDetailPopup.vue文件就是一般的vue写法,
index.js:

《vue2实践(延续更新)》

这里考虑到每次弹出层不能都去建立新的组件,我们只须要将组件内的数据更新就可以够了,dom也不须要删除,然后再建立,就用到了单例情势,这边的instance是在父组件没烧毁之前都是存在的,每次只是更新了组件的数据,为啥没被烧毁呢,这边形成了一个闭包:
《vue2实践(延续更新)》

挪用:

import TopicDetailPopup from '../topicDetailPopup/index.js'
TopicDetailPopup.open({
                            detail: res.data
                     });

然则这个处所涌现个题目this.$store如今为undefined,应当是由于这个组件是直接new实例化的,而不是经由过程根组件嵌套的,
main.js

new Vue({
    router: router,
    store,
    render: h => h(App)
}).$mount("#app");

store注册在根组件内里,而弹窗组件没有和根组件关联,所以拿不到store。

如果能将弹窗组件插进去其他组件题目就可以处理了,貌似如今API没有供应如许的接口,vue2动态增加组件的话能够用render函数,能够我如今的弹窗组件是模板的情势,也能够动态插进去到父组件,<component :is="componentId"></component>且须要在components内里援用,如许又回到了模板语法了。

弹窗的弊病:
vue-devtools 没法检测到组件,也没法检测到vuex,关于webapp来讲返回键没法运用,封闭不了当前的弹窗,形成上面的题目都是由于没用运用router。
关于安卓手机返回键没法运用能够采纳曲线救国的体式格局,禁用返回键,js没法直接操纵安卓返回键,然则能够运用beforeRouteLeave,使得返回键没有结果,

 beforeRouteLeave(to, from, next) {
        if (this.popupVisible) {//弹窗显现的话,路由没法跳转
            next(false);
        } else {
            next(true);
        }
 }

弹窗的优点:
在当前页面直接弹出,如许能够保留当前页面的数据和滚动条的位置,另有就是组件复用的话,直接封闭弹窗,不须要依据差别的页面去回退或许行进到特定的页面。

运用的是vue2.0,怎样动态增加组件。比方完成点击A按钮增加aTest组件,点击B按钮增加bTest组件。

:model和v-model的区分

v-model一般用于input的双向数据绑定 <input v-model="parentMsg">,也能够完成子组件到父组件数据的双向数据绑定:
起首说说v-model的用法:
model.vue

<template>
    <div>
        父:
        <input type="text"
               v-model="msg">
        <child v-model="msg"></child>
    </div>
</template>
<script>
import child from './modelChild.vue'
export default {
    name: "model",
    props: {

    },
    components: {
        child
    },
    data() {
        return {
            msg: "ppp"
        }
    },
    methods: {

    }
}
</script>
<style lang="less">

</style>

modelChild.vue

<template>
    <div>
        子:
        <input type="text"
               @input="handleInput"
               class="text"
               :value="value">
    </div>
</template>
<script>
export default {
    name: "modelChild",
    props: ["value"],
    methods: {
        handleInput(e) {
            this.$emit("input", e.target.value)
        }
    }
}
</script>
<style lang="less">
.text {
    height: 20px;
    width: 200px;
}
</style>

不管转变父组件照样子组件的输入框,value和msg的值都邑转变,两个输入框的值也就同时转变了。

:model和v-model的区分
:model是v-bind:model的缩写,<child :model="msg"></child>这类只是将父组件的数据通报到了子组件,并没有完成子组件和父组件数据的双向绑定。固然援用范例除外,子组件转变援用范例的数据的话,父组件也会转变的。

Vue.component注册全局组件

检察vue-router源码的时刻发明install.js内里两句:

Vue.component('router-view', View)
Vue.component('router-link', Link)

这两句就是全局注册了这两个组件,

import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)

《vue2实践(延续更新)》

《vue2实践(延续更新)》

这三步后,在组件里直接运用 <router-view></router-view>而不必先import再运用。

在mint-ui里也是雷同的做法:
src/index.js

const install = function(Vue) {
  if (install.installed) return;
  Vue.component(Header.name, Header);//注册全局组件
  Vue.component(Button.name, Button);
  Vue.use(InfiniteScroll);//运用指令插件
  Vue.use(Lazyload, {
    loading: require('./assets/loading-spin.svg'),
    try: 3
  });//运用指令插件或lazy-component
  Vue.$messagebox = Vue.prototype.$messagebox = MessageBox;
  Vue.$toast = Vue.prototype.$toast = Toast;
  Vue.$indicator = Vue.prototype.$indicator = Indicator;
};

背面的Vue.$toast = Vue.prototype.$toast = Toast;使得我们能够在组件中直接挪用this.$toast("提醒信息")

组件上写class

《vue2实践(延续更新)》

之前在写react的时刻是不能够这么做的,本日检察了popup.vue的时刻发明vue是能够这么干的,直接衬着到了组件的根元素上面。用在组件上

Boolean范例的props能够直接定义:

《vue2实践(延续更新)》

 props: {
    fixed: Boolean,
    value: {}
  }

数据更新页面没革新

本日在concat两个数组的时刻发明数据更新了,页面并没有革新,debug看了下数据,concat的数据没有get set属性接见器,致使厥后push的数据也没有属性接见器。之前没有细看文档。搜了下本来push是变异要领,concat不是。
处理办法有二:

  • 运用变异要领

  • 运用vue component的$set函数
    看一些小伙伴的回复是data的$set要领,最少vue2是没有的。详细可检察文档列表衬着

我的处理办法是:

Array.prototype.push.apply(arr, item);

render函数和模板语法只能二选一

本日在模板.vue文件里到场render函数发明并不会实行render函数,本来是vue-loader会将template转成render函数,所以只能二选一。.vue文件怎样运用render函数衬着组件

掌握input只能输入数字

<input type="number">在pc和手机端都能够完成只能输入数字,但是手机端弹出的软键盘内里没有完成或许搜刮按钮,搜了下,如今的HTML5 number的情况下并没有支撑搜刮按钮,type=’text’是有的。所以曲线救国,掌握表单只能输入数字。
早先的主意是先把在

<input type='text' @input="handleInput" :value="val"/>

handleInput(e){
this.val=e.target.value.replace(/[^\d]/g,'');
}

然则这类并不会及时革新表单的数据,下面就会起作用

e.target.value=e.target.value.replace(/[^\d]/g,'');

文雅点的写法,用自定义指令:

//<input type="text" v-number-only />
 directives: {
        numberOnly: {
            bind: function(el) {
                el.handler = function() {
                    el.value = el.value.replace(/\D+/, '')
                }
                el.addEventListener('input', el.handler)
            },
            unbind: function(el) {
                el.removeEventListener('input', el.handler)
            }
        }
    },

vue的input中,怎样限定只能输入number

弹出层弹出文本框猎取核心

由于弹出层是单例情势,所以翻开弹出层只会实行一次mounted钩子函数,我去监听

  visible(val) {
            if (val) {
                this.$refs.textbox.focus();//如许并不能使文本框猎取核心
            } else {
                this.detail = null;
                this.$refs.textbox.value = "";
            }
        }

处理办法也是运用自定义指令

  focus: {
            update(el) {
                el.focus();
            }
  }

vue怎样完成点击button 使input猎取核心

转变v-html剖析背景返回的HTML款式

日常平凡在写组件内里的款式加上scoped,防止款式的全局污染,而从背景返回的HTML无效的,处理办法就是在组件里再加一对style标签,将款式写到这里。

    原文作者:assassin_cike
    原文地址: https://segmentfault.com/a/1190000008688050
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞