标签 vue 下的文章

由于 v-if 在条件为 false 时,会销毁它内部的所有内容,当条件为 true 时,重新渲染内部的内容,所以 v-if 可以用作刷新某些区域用。

例子1

例如,input[type=file] 控件,如果你选择的文件跟上次选择的是同一个,它就不会触发 changeinput 事件,除非你选择一个新的文件。即使大多数情况下,这种情形并不需要特殊处理,因为用户不可能老是选择同一个文件,但总是会遇到特殊的时候。这个时候就可以用 v-if 来销毁原来的 file 控件,并渲染一个新 file,这个新的 file 上面绑定的数据、事件都跟原来一模一样:

<input type="file" v-if="someCondition" @change="onChange">

/* Data */
data(){
    return {
        someCondition: true
    }
}

/* Methods */
//file的change事件:
onChange(e){
    //想办法让someCondition经历 false - true 的转换
    this.someCondition = false;
    ...some code
    this.someCondition = true
}

现在,input[type=file] 已经是一个全新的了,即使你选择同一个文件,它也会响应 change 事件。

例子2

element-uitree 控件不是很完善,不提供刷新方法(也许是我没有发现)。如果你修改了某一个子项,然后想要重新加载整个树,就可以使用 v-if 来达到目的。用法跟上面是一样的。

End

Vuex 方便了管理状态,但也使开发流程更加复杂。为了提高开发速度,“让你少按几次键”,Vuex 提供了诸如mapState方法,但其实帮助不大。如果你在 methods 中看到调用了一个陌生的方法,那十有八九是 Vuex 中的 Action 或者 Mutation。

要是你想使用 v-model 绑定 state 中的字段,享受双向绑定的便捷,那在享受之前,你要好好忍受一下折磨,因为要实现这个功能是很麻烦的:在定义了 state 后,还要定义对应的 mutation;导入到组件的 computed 时,不能使用 mapState,还要给导入的 state 设置 setter,在 setter 中 commit mutation。这是至关重要的一步,否则 v-model 不会正常工作,而是会警告你缺少 setter:

Computed property "xxxx" was assigned to but it has no setter

这实在是很麻烦,必须找到更快捷的方法,更愉快地使用 v-model。这里提供一个简单的方法,应该会提高一点点开发速度。

1、定义通用的 mutation

如果给每一个 state 都定义相应的 mutation,那代码就要写到天荒地老。不妨定义一个通用的 mutation,只需传入需要修改的 state 的字段名和新值:

updateState(state, payload){
    state[payload.key] = payload.val;
}

这样就方便多了。至于一些需要特殊处理的 state,再单独给它们定义 mutation。

2、生成带 setter 的 computed

能用程序生成的,怎么能复制粘贴修改呢?computed 是一个对象,咱们就生成一个对象,再用...操作符合并到组件的 computed 中。

首先在你喜欢的地方新建一个 .js 文件。因为提交 mutation 需要用到 store 实例,store 实例又在 Vue 实例上,咱们就从 main.js 或任何你能想到的地方导出 Vue 实例,在刚才新建的 .js 文件中导入:

import vm from '@/main'

接着,定义一个数组,元素是 state 的字段名:

let stateKeys = ['name', 'age', 'sex'];

接着,循环这个数组,生成计算属性:

let _state = {};
stateKeys.map(key =>{
    _state[key] = {
        get(){
            //如果你的state在模块中,记得在`state`后加上.模块名,下同
            return vm.$store.state[key];
        },
        set(val){
            vm.$store.commit('updateState', {
                key,
                val
            });
        }
    }
})

export const state = _state;

之后,在组件中引入刚刚的 state:
import state from '刚刚的js路径和名称'
最后,在组件的 computed 属性中导入 state:

computed: {
    ...state
}

现在,就能在模板中正常使用 state 了:

<input v-model="name">

最后

一个人不喜欢刷碗不一定是个懒人,他可能只是不喜欢干类似的活。程序员一般都不喜欢干复制粘贴这样的重复性工作 :)

End

我是菜鸟,今天才发现这个问题。

Vue计算属性看似是一个函数,但实际上跟 data 更像。如果计算属性返回的是一个对象,并且在模板中读取了这个对象的属性,那就要保证开始时这个对象的属性一定要存在,下面是有问题的代码:

<header>{{ pageInfo.title }}</header>

...
computed: {
    pageInfo(){
        const mapPageInfo = {
            'index': {
                title: 'index page',
                subTitle: 'index subtitle'
            },
            'list': {
                title: 'list page',
                subTitle: 'list subtitle'
            }
        };

        return mapPageInfo[this.$route.path]
    }
}
....

上面的代码看起来没有问题,运行起来也是正常的,但实际上在控制台报错了:
cannot read property title of undefined...
原因就是 pageInfo 在刚开始的时候没有组件中读取的 title 属性。下面是正确的做法:

...
pageInfo(){
    //**保证属性一定是存在的**
    let pageInfo = {
        title: '',
        subTitle: ''
    };
    const mapPageInfo = {
        ...
    }
    ....
    return Object.assign(pageInfo, mapPageInfo[this.$route.path]);
}
...

End

一、基本使用

Swiper是一个非常好用的滑动插件,可以用来实现轮播图、代替浏览器默认的滚动条。中文主页:

https://www.swiper.com.cn/

在Vue中,Swiper对应的是Vue-Awesome-Swiper,NPM的地址:

https://www.npmjs.com/package/vue-awesome-swiper

基本的使用比较简单,首先安装Vue-Awesome-Swiper

npm install vue-awesome-swiper --save

- 阅读剩余部分 -

大部分时间,Vue都用来开发单页面应用程序(single page web application,SPA),但有时也需要开发多页面应用,这就要配置Vue CLI。有两种方式来配置Vue CLI,一是在项目的package.json中添加一个vue字段,在这个字段中配置相关的功能,二是在项目根目录新建一个vue.config.js,这个文件会被Vue CLI合并到webpack的配置中。这里以vue.config.js为例,来配置一个多页面的应用。

- 阅读剩余部分 -

Vue官方文档:https://cn.vuejs.org/v2/guide/custom-directive.html

什么是Vue自定义指令?

Vue自定义指令用起来就像Vue内置的v-modelv-on...之类,只不过实现了一些自己想要的功能。因为Vue自定义指令的钩子函数会传入一个el,它是自定义指令绑定到的那个DOM元素,所以Vue自定义指令可以用来直接和DOM打交道。

如何注册一个指令?

自定义指令分为全局和组件内的局部指令。全局自定义指令注册方法:

Vue.directive('myDirective', {
    // inserted是内置的钩子函数
    inserted: function (el) {
        // 一些操作...
    },
    // 指令的其他内容和钩子函数,如果需要的话...
})

- 阅读剩余部分 -