美文网首页
Vue项目经验

Vue项目经验

作者: 风之化身呀 | 来源:发表于2017-10-14 23:19 被阅读303次

1、动态添加class或style

有时候希望根据某个状态值来决定是否添加某个类,可以这样:

// 数组语法
<div :class="['a',value==true?'b':'']">             //类a总是存在,当value为真时类b存在
// 对象语法
<div :class="{'a':true,'b':value}">            //类a,b都由value控制
<div :style="{background:'url('+value.url+')'}">    //对于style,最好用对象语法,属性值取自当前vue实例

<div className={style.root} style={{ background: `url(${graduateCelebrate}) center center/ 100% 100% no-repeat content-box` }}>

2、绑定事件函数

有两种方式:

// 方式1
<div @click='handle'></div>         //handle函数的this指向当前vue实例,并且会将event对象传入handle作第一个参数,通常可用event.target获取被点击的DOM元素
// 方式2
<div @click='handle("param1",$event)'></div>         //handle函数的this指向当前实例,也可将$event传入handle,作用同上,一般用来获取被点击的DOM元素

3、关于箭头函数

vue的一些配置项,如mounted,beforeRouteEnter,beforeRouteLeave等,本身是一个函数,若使用箭头函数语法,则其内的this对象不是当前vue实例。因此这三个配置项不要用箭头函数,其它的配置项,如methods,computed,watch等接受对象作为配置的,其内的函数最好用箭头函数,另外setTimeout(fn,time)中的fn最好也用箭头函数。

4、数据传递

1、父子组件(prop down,event up)

  • 一般而言,父组件通过prop传递数值给子组件,子组件事先需定义props属性,如果没有定义props,那这个传递过来的值会自动添加到子组件的根元素上;
  • 子组件中一般通过触发某种自定义事件向父元素通信,因此一般在父元素中使用子组件的地方监听该事件名,该事件名是自定义的,因此要与子组件的一致。
<div id="counter-event-example">
  <p>{{ total }}</p>
  <button-counter v-on:increment="incrementTotal"></button-counter>
  <button-counter v-on:increment="incrementTotal"></button-counter>
</div>
Vue.component('button-counter', {
  template: '<button v-on:click="incrementCounter">{{ counter }}</button>',
  data: function () {
    return {
      counter: 0
    }
  },
  methods: {
    incrementCounter: function () {
      this.counter += 1
      this.$emit('increment')
    }
  },
})
new Vue({
  el: '#counter-event-example',
  data: {
    total: 0
  },
  methods: {
    incrementTotal: function () {
      this.total += 1
    }
  }
})
  • 如果要在父元素中使用子组件的地方监听原生事件,可用@click.native
  • 普通html标签上用@click是原生事件,自定义组件中用@click是自定义事件

2、非父子组件
有时候,非父子关系的两个组件之间也需要通信。在简单的场景下,可以使用一个空的 Vue 实例作为事件总线:

var bus = new Vue()
// 触发组件 A 中的事件
bus.$emit('id-selected', 1)
/ 在组件 B 创建的钩子中监听事件
bus.$on('id-selected', function (id) {
  // ...
}.bind(this))//绑定作用域

5、不能触发视图更新的操作

  • 数组
// 无法触发
vm.items[indexOfItem] = newValue
vm.items.length = newLength
// 可以触发
Vue.set(example1.items, indexOfItem, newValue)
example1.items.splice(newLength)
  • 对象
var vm = new Vue({
  data: {
    a: 1
  }
})
// `vm.a` 现在是响应式的
vm.b = 2
// `vm.b` 不是响应式的
var vm = new Vue({
  data: {
    userProfile: {
      name: 'Anika'
    }
  }
})
Vue.set(vm.userProfile, 'age', 27) //响应式

3、watch对象变化:

              'messages': {   // messages是一个数组,监听数组或对象的变化
            handler: function(newValue, old) {
                if (newValue.length == 0) {
                    setTimeout(() => {
                        history.back();
                    }, 1000)
                }
            },
            deep: true
        }

6、关于beforeRouteEnter和beforeRouteLeave

  • beforeRouteEnter(to,from,next) 无法访问当前vue实例,一般用于从localStorage中读取数据恢复页面,比如从页面a到b,在从b回到a,若a有数据变化(ajax拉取)就更新页面,否则不更新;或者还原当前滚动条位置
  • beforeRouteLeave(to,from,next) 可访问当前vue实例,一般用于页面离开时将某些状态保存在localStorage中,例如当前滚动条位置
  • 二者都必须显示调用next函数

7、keep-alive和router-view混合使用

// 这是目前用的比较多的方式
<keep-alive>
    <router-view v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive"></router-view>

... 
  routes: [
    { path: '/', redirect: '/index',  component: Index, meta: { keepAlive: true }},
    {
      path: '/common',
      component: TestParent,
      children: [
        { path: '/test2', component: Test2, meta: { keepAlive: true } } 
      ]
    }
    ....
    // 表示index和test2都使用keep-alive

若有三个页面A->B->C,希望A->B时B拉新数据;C返回B时B不拉新数据,且保存B到C之前的位置,该如何做?
1、给B设置keepAlive:true;
2、在B的beforeRouteEnter中做获取数据的操作,该钩子的三个参数可以判断B的上一个页面,从而决定是否拉数据;
在B的beforeRouteLeave里用localStorage记录位置,并清除和页面展现相关的数据状态;
3、在接口回调里最好用EventCenter这种观察者模式来触发数据获取成功的事件
4、在B的mounted钩子里接受数据获取成功的事件,就可以拿到数据
5、在B的activated钩子里取localStorage里的位置

8、router-link常用方式

<!-- 命名的路由 -->
<router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link>
<!-- 带查询参数,下面的结果为 /register?plan=private -->
<router-link :to="{ path: 'register', query: { plan: 'private' }}">Register</router-link>

//对应js
this.$route.params.userId
this.$route.query.plan

9、过度动画

  • 单元素过渡
    transition包一个含有v-if或v-show指令的元素就行


    动画过程
  • 多元素过渡
    transition下只能有一个根元素,所以多元素时必须用v-if,v-else来保证只有一个,此外,多个相同标签时,最好给每个标签设置key
  • 多组件过渡
    用动态组件即可
  • 列表过渡
    需用transition-group组件包裹,被包裹元素必须设置key,其他和单元素一样

10、数据拉取

  • 数据获取操作最早可以放在每个组件的beforeRouteEnter里,然后利用观察者模式把数据传到beforeMount钩子函数里做逻辑操作
     beforeRouteEnter(to, from, next) {
        let feed_id = to.params.id;
        if (from.name != 'CommentDetail' && feed_id) {
            getArticleDetail({
                feed_id: feed_id
            }).then(res => EventCenter.$emit('renderArticle', res));

            getComment({
                feed_id: feed_id
            }).then(res => EventCenter.$emit('renderComment', res));
        }
        next();
      }

     beforeMount(){
           // 1、渲染文章详情
       EventCenter.$on('renderArticle', res => {
            
       });
       // 2、渲染文章评论
       EventCenter.$on('renderComment', res => {
            
       })
      }  

11、插件 or 组件

对于全局使用频率较高的最好写成插件,而不是组件。例如loading,toast之类,若写成组件,则需要在每个父组件中引入该组件,比较麻烦,写成插件就可以直接调用

import $ from 'n-zepto';
import Vue from 'vue';
export default {
    install() {
        var timer = null;
        Vue.prototype.$alerTip = function(text, delay, options) {
            var defaultCssObject = {
                position: 'fixed',
                display: 'flex',
                alignItems: 'center',
                justifyContent: 'center',
                zIndex: 10000,
                minWidth: '1.5rem',
                margin: '0 auto',
                left: 'calc((100% - 1.5rem) / 2)',
                bottom: '1.4rem',
                borderRadius: '.1rem',
                height: '.5rem',
                lineHeight: '.5rem',
                background: '#000',
                opacity: 0.85,
                color: 'white',
            };
            var cssObject = options || defaultCssObject;
            var temp = `<div class="v-toast">${text}</div>`;
            var $div = $(temp);
            $div.css(cssObject);
            $('body').append($div);
            clearTimeout(timer);
            timer = setTimeout(() => {
                $('.v-toast').remove();
                timer = null;
            }, delay);
        }
    }
}

12、vue父子组件生命周期执行顺序问题

父子组件钩子执行顺序:
father created
father before mounted
son created
son before mount
son mounted
father mounted
所以,你在父组件 beforeMounted 中已初始化的值一定可以通过props下发到子组件

13、vue-router切换页面滚动条位置问题

注意:scrollBehavior只有在history.pushState可用时才有效,而该方法仅兼容到IE10(移动端可放心使用)

const router = new VueRouter({
    routes,
    scrollBehavior (to, from, savedPosition) {
        if (savedPosition) {
            return savedPosition
        } else {
            if (from.meta.keepAlive) {       // 通过meta属性精细控制
                from.meta.savedPosition = document.body.scrollTop;
            }
            return { x: 0, y: to.meta.savedPosition || 0 }
        }
    }
})

14、vue库的引入问题

vue提供众多版本库文件,在使用*.vue单文件组件的开发模式时,只需引入vue.runtime.min.js即可,该库体积最小,不过要注意初始化vue实例时,不能用template选项,而应该换为render

                new Vue({
            el: '#app',
            router,
            render: h => h(App)
        })
              // webpack对应修改:
                alias: {
            'vue$': 'vue/dist/vue.runtime.min.js'
        }

相关文章

  • Vue项目经验

    1、动态添加class或style 有时候希望根据某个状态值来决定是否添加某个类,可以这样: 2、绑定事件函数 有...

  • springboot + mybatis + mysql + V

    项目总结经验 1.项目框架 SpringBoot + Mybatis + Mysql + Vue 数据库采用阿里云...

  • @vue/cli 搭建项目 vue+ts

    最近接手了一个新的项目,@vue/cli vue+ts项目,总结下经验。搭建开发环境。主要参考官方文档。http...

  • vue-cli3.0基本配置项

    最近我们的vue项目搭建框架升级到了vue-cli3.0,此文记录一下我们搭建项目时的经验,大牛请见谅; 初始化 ...

  • 面试中如何简短精干的描述vue生命周期

    出去面试,面试官看到你的简历上的项目经验写着使用Vue + Vue-router + Vuex。我相信,写上这些会...

  • 越写悦快乐之Vue项目如何集成EventBus

    今天的越写悦快乐之系列文章为大家带来Vue项目如何集成EventBus。有过Vue开发经验的小伙们都知道,多个组件...

  • linux部署Vue项目血泪经验

    前言 来啦老铁! 笔者近期在团队开发个小工具,后端语言python,对应框架为flask,前端框架vue,笔者对v...

  • 14 -vue 打包图片路径错误解决

    一、构建 VUE 项目 直接用官网的方式建立vue 项目 二、打包 VUE 项目 2.1 打包项目介绍 会在项目...

  • Vue 3.0组件的渲染流程

    Vue简单易上手,只需要简单的文档说明就能上手开发。虽然本人也有一直使用Vue 2.0的项目开发经验,以前也只了解...

  • vue-cli

    vue init webpack 项目名称 //vue-cli2 创建项目的方式vue create 项目名...

网友评论

      本文标题:Vue项目经验

      本文链接:https://www.haomeiwen.com/subject/ygifuxtx.html