专栏首页码客Vue基本语法

Vue基本语法

刷新时不显示模版

当vue需要加载数据多或者网络慢时,加载数据时候会先出现vue模板(例如item.name),用户体验特别不好

解决方法有如下几种:

1、可以通过VUE内置的指令v-cloak解决这个问题(推荐) 具体实现:

CSS中添加样式

[v-cloak] {
    display: none !important;
}

页面要渲染的额部分添加v-cloak

<ul v-cloak v-for="item in items">
    <li>{{ item.name }}</li>
</ul>

2、可以在需要编译的元素前后加上

<template></template>

关于<template> 详解

不推荐第二种 在IE中不支持

取值

文本

<span>Message: {{ msg }}</span>

表达式

{{ number + 1 }}
{{ ok ? 'YES' : 'NO' }}
{{ message.split('').reverse().join('') }}

html

双大括号会将数据解释为普通文本,而非 HTML 代码。为了输出真正的 HTML,你需要使用 v-html 指令:

<p>Using v-html directive: <span v-html="rawHtml"></span></p>

计算属性

data: {
    num1: 10,
    num2:2
},
computed: {
    sum: function () {
        return this.num1+this.num2;
    }
}

如上 计算属性sum的值就会为3

computed特点:

  1. computed计算的性能更高,它会把计算的值缓存起来,如果data中的属性不变,computed就不会再次计算,而methods中每次都要重新计算
  2. watch主要用于监控vue实例的变化,它监控的变量当然必须在data里面声明才可以,它可以监控一个变量,也可以是一个对象

取值处理

JS中:

var user_vue = new Vue({
    el: ".user",
    data: {
        loginuser: {username:"我的名称比较长"}
    },
    filters: {
        nameFilter(name) {
            if (name.length > 4) {
                name = name.substring(0, 4);
            }
            return name;
        }
    }
});

取值方式:

{{loginuser.username|nameFilter}}

样式

v-bind:class="{ unclickable: page == 1 }"

私有样式

<style type="text/css" scoped>
</style>

事件

<button type="button" v-on:click="loginAction()">登录</button>

判断

<div v-if="type === 'A'">
  A
</div>
<div v-else-if="type === 'B'">
  B
</div>
<div v-else-if="type === 'C'">
  C
</div>
<div v-else>
  Not A/B/C
</div>

循环

遍历数字

<li v-for="(item,index) in 10">{{item}}</li>

编历一个数字时item的值是从1 始的。 编历一个指定数字也就是相当编历一个从1到指定数字的数组。 所以上面这个例子的item是1-10,index是0-9

遍历对象数组

数据

data:{
    items:[
        {text:"第一组"},
        {text:"第二组"},
        {text:"第三组"},
    ]
}

页面

<li v-for="item in items">{{item.text}}</li>

<li v-for="(item, index) in items">
    {{ index }} - {{ item.text }}
</li>

组件化

示例

Vue.component('zj-page', {
    props: ["showpage", "currpage", "pages"],
    computed: {
        showPageArr: function () {
            var halfshow = parseInt(this.showpage / 2);
            var tempbegin = this.currpage - halfshow + 1;
            var tempend = this.currpage + halfshow;
            if (tempbegin < 1) {
                tempend = tempend - tempbegin + 1;
                tempbegin = 1;
                if (tempend > this.pages) {
                    tempend = this.pages;
                }
            } else if (tempend > this.pages) {
                tempbegin = this.pages - this.showpage + 1;
                tempend = this.pages;
                if (tempbegin < 1) {
                    tempbegin = 1;
                }
            }

            var arr = [];
            for (var i = tempbegin; i <= tempend; i++) {
                arr.push(i);
            }
            return arr;
        }
    },

    methods: {
        num_click: function (num) {
            this.$emit('gotopage', num, this.currpage);
        },
        last_click: function () {
            if (this.currpage > 1) {
                this.$emit('gotopage', this.currpage - 1, this.currpage);
            }
        },
        next_click: function () {
            if (this.currpage < this.pages) {
                this.$emit('gotopage', this.currpage + 1, this.currpage);
            }
        },
        begin_click: function () {
            this.$emit('gotopage', 1, this.currpage);
        },
        end_click: function () {
            this.$emit('gotopage', this.pages, this.currpage);
        }
    },
    template: `
    <div class="paging">
        <span class="first_page" v-bind:class="{ unclickable: currpage == 1 }" v-on:click="begin_click()">首页</span>
        <span class="prev_page" v-bind:class="{ unclickable: currpage == 1 }" v-on:click="last_click()">上一页</span>
        <span v-bind:class="{ pitch_on: item == currpage }" class="pagination" v-for="(item,index) in showPageArr" v-on:click="num_click(item)">{{ item }} </span>
        <span class="next_page" v-bind:class="{ unclickable: currpage == pages||pages == 0 }" v-on:click="next_click()">下一页</span>
        <span class="last_page" v-bind:class="{ unclickable: currpage == pages||pages == 0}" v-on:click="end_click()">末页</span>
    </div>
`
});

使用方法

<zj-page v-bind:showpage="showpage" v-bind:currpage="currpage" v-bind:pages="pages" v-on:gotopage="gotopage"></zj-page>

JS代码

new Vue({
    el: ".prepare_main",
    data: {
        showpage: 10,
        currpage: 1,
        pages: 20
    },
    methods: {
        gotopage: function (newpage, oldpage) {
            console.info("跳转到:" + newpage + " 原页:" + oldpage);
        }
    }
});

注意:在分页组件内部,点击页数后 并没有直接在自定义组件内修改当前页数,而是发送了一个事件,让父组件来更新页数, 是因为Vue的属性传递是单向

属性传递

子组件中定义

props: ["showpage", "currpage", "pages"]

父组件中传递

v-bind:showpage="showpage"

组件通讯

父子组件通讯

子组件中调用

this.$emit('gotopage', newValue, oldValue);

父组件中传递

v-on:gotopage="gotopage"

非父子组件的通信

事件定义

var event = new Vue()

发送事件

event.$emit('load_paper_detail',data);

接受事件

event.$on("load_paper_detail", function (data) {
	_this.load_paper_detail();
})

生命周期

beforeCreate

在实例初始化之后,数据观测(data observer) 和 event/watcher 事件配置之前被调用。

created

实例已经创建完成之后被调用。在这一步,实例已完成以下的配置:数据观测(data observer),属性和方法的运算, watch/event 事件回调。然而,挂载阶段还没开始,$el 属性目前不可见。

beforeMount

在挂载开始之前被调用:相关的 render 函数首次被调用。

mounted

el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子。 Ajax请求数据在此阶段

beforeUpdate

数据更新时调用,发生在虚拟 DOM 重新渲染和打补丁之前。 你可以在这个钩子中进一步地更改状态,这不会触发附加的重渲染过程。

updated

由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。 当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。然而在大多数情况下,你应该避免在此期间更改状态,因为这可能会导致更新无限循环。 该钩子在服务器端渲染期间不被调用。

beforeDestroy

实例销毁之前调用。在这一步,实例仍然完全可用。

destroyed

Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。 该钩子在服务器端渲染期间不被调用。

DOM渲染后事件

nextTick方法,意思是在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。

this.$nextTick(function(){
    
});

公共方法

扩展

Vue.prototype.common = {
    abc:function(){
        
    }
}

调用

this.common.abc();

公共过滤器

Vue.filter('capitalize', function (value) {
  if (!value) return ''
  value = value.toString()
  return value.charAt(0).toUpperCase() + value.slice(1)
})

调用

{{ message | capitalize }}

过滤器可以串联:

{{ message | filterA | filterB }}

引用自己的JS

utils.js

export const arrayContain = function (array, obj){
  for (var i = 0; i < array.length; i++){
    if (array[i] == obj){//如果要求数据类型也一致,这里可使用恒等号===
      return true;
    }
  }
  return false;
}

如果想引用这个方法,就通过import引入

import {arrayContain} from '../../js/utils';

引用自己的CSS

在vue文件中的<style>内填写需要引用的文件

如:

@import "./css/index.css";

VUEX

引用

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex);

export default new Vuex.Store({
    state: {
        count: 0
    },
    getters: {
        m_num: state => {
            return state.count+1;
        }
    },
    mutations: {
        increment (state) {
            state.count++
        }
    },
    actions: {
        increment (context) {
            context.commit('increment')
        }
    }
})

State

state 就类似于 data 用来保存状态的

Getter

加工处理状态的数据 返回新数据

Mutation

更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数:

store.commit('increment')

附带参数

mutations: {
  increment (state, n) {
    state.count += n
  }
}

调用方式

store.commit('increment', 10)

类似这样

mutations: {
  increment (state, payload) {
    state.count += payload.amount
  }
}

对象方式提交

store.commit({
  type: 'increment',
  amount: 10
})

Action

Action 类似于 mutation,不同在于:

  • Action 提交的是 mutation,而不是直接变更状态。
  • Action 可以包含任意异步操作。

Action 通过 store.dispatch 方法触发:

store.dispatch('increment')

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 关于最近react许可证的问题

    客观的说,个人是非常喜欢react的。有人说学习曲线陡峭,有人说太繁琐。。。但是当你真正开始接触的时候,你一定会被他的魅力所吸引。毫不夸张的说,React在推动...

    Nealyang
  • 「中高级前端面试」JavaScript手写代码无敌秘籍

    用来解析JSON字符串,构造由字符串描述的JavaScript值或对象。提供可选的reviver函数用以在返回之前对所得到的对象执行变换(操作)。

    Nealyang
  • electron桌面应用开发(一)

    关于electron,前两天一番写了一个开头,搭建开发环境。今天一番尝试去开发一个小的例子,做一些修改。

    efonfighting
  • uni app 零基础小白到项目实战-1

    uni-app是一个使用vue.js开发跨平台应用的前端框架。 开发者通过编写vue.js代码,uni-app将其编译到Ios,android,微信小程序等多...

    达达前端
  • Vue 3.0前的 TypeScript 最佳入门实践

    然鹅最近的一个项目中,是 TypeScript+ Vue,毛计喇,学之...…真香!

    Nealyang
  • 「多图警告」重学 TCP/IP 协议

    最近刚看完电影 「无敌破坏王2:大闹互联网」,觉得里面有些动画蛮有意思的,于是想起前不久看的《图解HTTP》和 TCP/IP相关的文章。嗯,是时候展示真正的技术...

    Nealyang
  • [Vue 牛刀小试]:第十七章 - 优化 Vue CLI 3 构建的前端项目模板(1)- 基础项目模板介绍

      在上一章中,我们开始通过 Vue CLI 去搭建属于自己的前端 Vue 项目模板,就像我们 .NET 程序员在使用 asp.net core 时一样,我们更...

    程序员宇说
  • 30 道 Vue 面试题,内含详细讲解(涵盖入门到精通,自测 Vue 掌握程度)

    本文以前端面试官的角度出发,对 Vue 框架中一些重要的特性、框架的原理以问题的形式进行整理汇总,意在帮助作者及读者自测下 Vue 掌握的程度。本文章节结构以从...

    Nealyang
  • 如何新建一个vue项目

    大家都知道国内直接使用npm 的官方镜像是非常慢的,这里推荐使用淘宝 NPM 镜像。

    用户4478423
  • Vue.js学习总结——1

    双大括号会将数据解释为普通文本,而非 HTML 代码。为了输出真正的 HTML,你需要使用 v-html 指令:

    用代码征服天下

扫码关注云+社区

领取腾讯云代金券