vue(学习笔记三)——vue知识点汇总

Vue简介

2014年诞生,2013年react,09年angularjs

作者: 尤雨溪

核心概念: 组件化 双向数据流(基于ES5中的defineProperty来实现的),IE9才支持

angular核心: 模块化 双向数据绑定(脏检测:一个数组($watch),性能弱)

开发一个登陆模块,登陆需要显示的头部、底部、中部

组件:组合起来的一个部件(头部、底部、中部)

细分代码

头部: 页面、样式、动态效果

代码: templete style script

数据流

1向:js内存属性发生改变,影响页面的改变

1向:页面的改变影响js内存属性的改变

Vue实例对象

// 构造函数

var my = new Vue({

el: '#app', // 挂载点 (设置vue对象装载到页面位置)

template: '<div> {{ fruit }} </div>', // 模板

data: { // 数据

    fruit: 'apple'

}

});

data中的属性会被代理到 my 对象中,可以使用 my.fruit 来获取属性值

vue常用指令

v-text

v-html

v-if

v-show

v-model

v-bind

代码

<template>

<!-- 只能有一个根节点 -->

  <div>

    <pre>

         * v-text 是元素的innerText 只能在双标签元素中使用

        * v-html 是元素的innerHTML 不能包含<!-- {{ xxx }} -->

        * v-if  元素是否移出或插入

        * v-show 元素是否隐藏或显示

        * v-model双向数据绑定

        * v-bind 单向数据绑定(内存js改变影响页面,页面改变不影响内存js)

    </pre>

    v-text:

    <span v-text="text"></span>

    <hr />

    v-html:

    <span v-html="html"></span>

    <hr />

    v-if:

    <div v-if="isShow" style="height: 100px; background-color:red;"></div>

    <hr />

    v-show:

    <div v-show="isShow" style="height: 100px; background-color:green;"></div>

    <hr />

    v-model:

    <input type="text" name="username" v-model="username" />

    {{ username }}<br/>

    <!--给下面的input value赋值 用 v-bind:value="username" -->

    <input type="text" name="" v-bind:value="username"  />

    <hr />

  </div>

</template>

<script>

export default {

    data(){

        return {

            text: '我是v-text内容',

            html: `

                <ul>

                    <li>哈哈</li>

                    <li>呵呵</li>

                </ul>

            `,

            isShow: false,

            username: 'admin'

        }

    }

}

</script>

<style>

</style>

class结合v-bind使用

需要根据可变的表达式的结果来给class赋值,就需要用到v-bind:class=”xxx”

v-bind:属性名=”表达式”,最终表达式运算结束的结果赋值给该属性 

简化的写法: :属性名="表达式"

class: 结果的分类

一个样式: 返回字符串(三元表达式和 key和样式的对象清单)

多个样式: 返回对象(样式做key,true或false做值)

<template>

  <div>

    <div v-bind:class="isRed? 'red' : 'green'">单个class样式</div>

    <ul>

        <!-- 当stu.score = A 时 匹配red,当stu.score= B 时匹配green  -->

        <li v-for="stu in stus" :class="{'A': 'red', 'B': 'green'}[stu.score]"> {{ stu.name }}</li>

    </ul>

    <div :class="{'red': true, 'big': true}">多个class样式</div>

  </div>

</template>

<script>

export default {

    data(){

        return {

            isRed: false,

            stus: [

                {

                    name: 'jack',

                    score: 'A'

                },

                {

                    name: 'lucy',

                    score: 'B'

                },

            ]

        }

    }

}

</script>

<style>

.red{

    background-color: red;

}

.green{

    background-color: green;

}

.big{

    font-size: 30px;

}

</style>

methods 和 v-on的使用

绑定事件的方法 

        v-on:事件名="表达式||函数名"

        简写:@事件名="表达式||函数名"

函数名如果没有参数,可以省略() 只给一个函数名称

函数的声明需要在export default 这个对象的根属性加上 methods 属性中

凡是在template中使用函数或变量,不需要使用this

v-on高级用法

修饰符:

.stop - 调用 event.stopPropagation()。

.prevent - 调用 event.preventDefault()。

.capture - 添加事件侦听器时使用 capture 模式。

.self - 只当事件是从侦听器绑定的元素本身触发时才触发回调。

.{keyCode | keyAlias} - 只当事件是从特定键触发时才触发回调。

.native - 监听组件根元素的原生事件。

.once - 只触发一次回调。

.left - (2.2.0) 只当点击鼠标左键时触发。

.right - (2.2.0) 只当点击鼠标右键时触发。

.middle - (2.2.0) 只当点击鼠标中键时触发。

.passive - (2.3.0) 以 { passive: true } 模式添加侦听器

用法:

绑定事件监听器。事件类型由参数指定。表达式可以是一个方法的名字或一个内联语句,如果没有修饰符也可以省略。

从 2.4.0 开始,v-on 同样支持不带参数绑定一个事件/监听器键值对的对象。注意当使用对象语法时,是不支持任何修饰器的。

用在普通元素上时,只能监听 原生 DOM 事件。用在自定义元素组件上时,也可以监听子组件触发的自定义事件。

在监听原生 DOM 事件时,方法以事件为唯一的参数。如果使用内联语句,语句可以访问一个 event属性:v−on:click="handle(′ok′,event属性:v−on:click="handle(′ok′,event)”。

<!-- 对象语法 (2.4.0+) -->

<button v-on="{ mousedown: doThis, mouseup: doThat }"></button>

<!-- 内联语句 -->

<button v-on:click="doThat('hello', $event)"></button>

<!-- 缩写 -->

<button @click="doThis"></button>

<!-- 停止冒泡 -->

<button @click.stop="doThis"></button>

<!-- 阻止默认行为 -->

<button @click.prevent="doThis"></button>

<!-- 阻止默认行为,没有表达式 -->

<form @submit.prevent></form>

<!--  串联修饰符 -->

<button @click.stop.prevent="doThis"></button>

<!-- 键修饰符,键别名 -->

<input @keyup.enter="onEnter">

<!-- 键修饰符,键代码 -->

<input @keyup.13="onEnter">

<!-- 点击回调只会触发一次 -->

<button v-on:click.once="doThis"></button>

<template>

  <div>

    <button v-on:click="isRed = !isRed">按钮</button>

    <button v-on:click="change()">按钮</button>

    <button @click="change">按钮</button>

  </div>

</template>

<script>

export default {

    data(){

        return {

            isRed: false,

            stus: [

                {

                    name: 'jack',

                    score: 'A'

                },

                {

                    name: 'lucy',

                    score: 'B'

                },

            ]

        }

    },

    // 声明函数,属于组件对象

    methods: {

        // 包含多个函数名称做key,函数提供做value

        change (){

            this.isRed = !this.isRed;

            this.stus.push({

                name: 'mick',

                score: 'A'

            });

        }

    }

}

</script>

<style>

.red{

    background-color: red;

}

.green{

    background-color: green;

}

.big{

    font-size: 30px;

}

</style>

v-for的使用

可以使用操作数组(item,index)

可以使用操作对象(value,key,index)

key 是类似于trank by的属性,为了告诉vue,js中的元素和页面的关联,当删除元素的时候,是单个元素的删除而不是整版的替换,所有需要其关联关系。2.0版本后必输设置(性能)

<template>

  <div>

    <ul>

        <li v-for="(stu, index) in stus" v-bind:key="index">

            index:{{ index }} - stu:{{ stu }}

        </li>

        使用对象的方式-滚动歌词(时间做key,内容作为value)<hr />

        <li v-for="(value, key, index) in person" v-bind:key="index">

            value:{{ value }}-key:{{ key }}-index:{{ index }}

        </li>

    </ul>

  </div>

</template>

<script>

export default {

    data(){

        return {

            isRed: false,

            stus: [

                {

                    name: 'jack',

                    score: 'A'

                },

                {

                    name: 'lucy',

                    score: 'B'

                },

            ],

            person: {

                name: 'zhangsan',

                realname: '张三'

            }

        }

    }

}

</script>

<style>

.red{

    background-color: red;

}

.green{

    background-color: green;

}

.big{

    font-size: 30px;

}

</style>

简单学生添加删除案例

<template>

  <div>

    <ul>

        <li v-for="(stu, index) in stus" :key="stu.id" :class="{'A':'red','B':'blue','C':'green','D':'pink'}[stu.score]">

            {{ stu.name }} - {{ stu.score }}   

            <button @click="del(index)">删除</button>

        </li>

    </ul>

    学生姓名:<input type="text" name="name" v-model="name"/><br/>

    学生成绩:<input type="text" name="score" v-model="score"/><br/>

    <button @click="addStu">添加学生</button>

  </div>

</template>

<script>

export default {

    data(){

        return {

            isRed: false,

            name:'',

            score:'',

            stus: [

                {

                    id: 1,

                    name: '张三',

                    score: 'A'

                },{

                    id: 2,

                    name: '张无忌',

                    score: 'B'

                },{

                    id: 3,

                    name: '赵敏',

                    score: 'C'

                },{

                    id: 4,

                    name: '殷素素',

                    score: 'D'

                },

            ]

        }

    },

    // 声明函数,属于组件对象

    methods: {

        // 添加

        addStu (){

            // 获取页面输入的值:v-model

            this.stus.push({

                id: 1,

                name: this.name,

                score: this.score

            });

            this.name = '';

            this.score = '';

        },

        // 删除

        del (index){

            this.stus.splice(index, 1);

        }

    }

}

</script>

<style>

.red{

    background-color: red;

}

.green{

    background-color: green;

}

.blue{

    background-color: skyblue;

}

.pink{

    background-color: hotpink;

}

</style>

父子组件使用(父传子)

父需要声明子组件,引入子组件对象,声明方式如下:

// 引入子组件

import 子组件对象名 from './xxx.vue';

// 声明子组件

components: {

// 组件名(在模板中使用): 组件对象

}

全局组件,使用更为方便,不需要引入和声明直接使用

在main.js中引入异常,在main.js中使用 vue.component('组件名',组件对象);

声明为全局组件后,就可以直接通过组件名使用

父组件向自组件传递数据

父组件通过子组件标签属性将值传递 

        方式一:常量 <header-vue 属性名="常量值"></header-vue>

        方式二:变量<header-vue :属性名="变量名"></header-vue>

子组件使用该属性值需要使用props 声明 

        在根属性加 props: ['属性名1','属性名2'...]

        在页面中就可以直接使用 {{ 属性名 }}

        在js中可以直接使用 this.属性名 访问

        export default{ data(){return{ } },

              // 接受父组件参数的设置

              props:['textbody']

        }

子组件向父组件通信(vuebus)

        通过new Vue() 的一个对象,来$on(‘事件名’, fn(prop1, prop1)) 绑定事件

        另一个组件引入统一个vuebus,来$emit(‘事件名’,prop1, prop2) 触发事件

vue高级

    `   vue过滤器

        获取dom元素

        mint-ui

        vue组件的使用

        组件间通信

        vue-router使用

        vue-resource发起http请求

        axios

vue过滤器

content | 过滤器, vue中没有提供默认过滤器,需要我们自定义过滤器

组件内过滤器 + 全局过滤器 

    组件内过滤器就是options中的一个filters的属性(一个对象) 

        多个key就是不同的过滤器名,多个value就是与key对应的函数体

    Vue.filter(名, fn)

    如果名称相同以局部为主

app.vue

<template>

  <div>

    请输入内容:

    <input type="text" name="name" v-model="name"/>

    显示:{{ name | myFilter}}

  </div>

</template>

<script>

    export default {

        // 自定义过滤器

        filters: {

            myFilter: function(value){

                // 输入的内容翻转: 转换为数组->翻转数组 ->转换为字符串

                return value.split('').reverse().join('');

            }

        },

        data(){

            return {

                name:''

            }

        }

    }

</script>

<style scoped>

</style>

main.js

// 全局过滤器Vue.filter('myFilter1', function(value){

    return value.split('').reverse().join(',');

});

获取DOM元素

前端框架就是为了减少dom操作,特定情况下也提供了的操作方式

在指定的元素上,添加ref=”名称”

在获取的地方加入 this.$refs.名称 

    如果ref放在了原生DOM元素上,获取的数据就是元素DOM对象

    如果ref放在组件对象上,获取的就是组件对象

    获取子组件DOM对象,通过this.refs.sub.refs.sub.el

事件

    created 完成数据初始化,未生成DOM

    mounted 将数据已经装载到DOM之上,且DOM生成完毕

<template>

  <div>

    <sub-vue ref="sub"></sub-vue>

    <div ref="myDiv"></div>

  </div>

</template>

<script>

    import SubVue from './components/sub.vue';

    export default {

        data(){

            return {

            }

        },

        components: {

            SubVue: SubVue

        },

        // 组件创建后,数据已经完成初始化,但DOM还未完成

        created (){ // 事件的处理函数(created)

            console.log(this.$refs.sub);          // vue的组件对象

            this.$refs.sub.$el.innerHTML = '哈哈';  // 获取vue组件对象对应的DOM对象

            console.log(this.$refs.myDiv);        // undefined 获取不到

        },

        // 数据装载到DOM上后,各种数据已经就位,将数据渲染到DOM上,DOM已经生产

        mounted (){ // 事件的处理函数(created)

            console.log(this.$refs.myDiv);// 获取的原生DOM对象

            this.$refs.myDiv.innerHTML = '案发生的发生';

        }

    }

</script>

<style scoped>

</style>

vue-router

前端路由 核心就是锚点值的改变,根据不同的值,渲染指定DOM位置的不同数据

ui-router(anglar):锚点值改变,通过ajax获取模板

vue中,模板数据不是通过ajax请求来的,而是调用函数获取到模板内容

vue核心插件: 

    vue-router 路由

    vuex 管理全局共享数据

使用方式 

    1: 下载 npm install vue-router -S

    2: 引入 impot Router from 'vue-router'

    3: 安装插件 Vue.use(Router)

    4: 创建路由对象并配置路由规则

    5: 将其李洋老师对象传递给Vue实例,options中

    6: 留坑

命名路由

需求:通过a标签单击实现页面跳转

使用 标签

<a href="#/music">进入音乐</a>

<a href="#/movie">进入电影</a>

// 以上直接通过a标签方式直接指定路径名称,如果锚点发生改变不好维护

<!-- 根据name跳转(推荐使用该方式)-->

<router-link :to="{name: 'Music'}">进入音乐</router-link>

<router-link :to="{name: 'Movie'}">进入电影</router-link>

<!-- 根据path跳转-->

<router-link to="/movie">进入电影</router-link>

router-link 参数传递

    vue-router 中挂在了两个对象

    route(信息数据)router(功能函数)

    参数传递两种方式: 

        1:查询字符串 query:{key: value} -> /detail?id=1


<router-link :to="{name: 'Detail',query: {id: user.id}}"> 查看详情 </router-link>

    路由path不用改:

    {

      path: '/detail',

      name: 'Detail',

      component: Detail

    }

2: 路径字符串 params:{key: value} -> /detial/1

<router-link :to="{name: 'Detail',params: {id: user.id}}"> 查看详情 </router-link>

    路由path需要改:

    {

      path: '/detail/:id',

      name: 'Detail',

      component: Detail

    }

获取参数 

    this.$route.query.id

    this.$route.params.id

编程式导航

不能保证用户一定会单击某些按钮.

并且当前操作除了路由跳转以外,还有一些别的附加操作

this.$router.go 根据浏览器记录 前进 1 后退-1

this.$router.push(直接跳转到某个页面显示) 

push参数: 字符串 /xxx

push参数: 对象 {name: ‘xxx’,query:{id:1}, params:{id:1,name:’zhangsan’}}

注意:有params的路由规则中一定记得在路由规则path中添加 path: ‘/movie/:id’,

<template>

  <div >

        <button @click="goMusic">跳转到music</button>

        <button @click="goMovie">跳转电影</button>

        <button @click="goBack">跳转到上一页</button>

        <button @click="testQuery">编程导航传递参数query方式</button>

        <button @click="testParams">编程导航传递参数params方式</button>

  </div>

</template>

<script>

export default {

  data () {

    return {

    }

  },

  methods: {

    goMusic (){

        this.$router.push('/music');

    },

    goMovie (){

        this.$router.push({

            name: 'Movie' // 路由规则 name值

        });

    },

    goBack (){

        this.$router.go(-1); //-1 上一次浏览器记录 1 下一个浏览器记录

    },

    testQuery (){

            // 查询字符串方式: /music?id=1&name=zhagnsan

            this.$router.push({

                name: 'Music', // 路由规则 name值

                query: {

                    id: 1,

                    name: 'zhagnsan'

                }

            });

    },

    testParams (){

            // 查询字符串方式: /movie/1

            this.$router.push({

                name: 'Movie', // 路由规则  name值

                params: {      // 路由规则  path: '/movie/:id',

                    id: 1,

                    name: 'zhagnsan'

                }

            });

    }

  }

}

</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->

<style scoped>

</style>

原生监听锚点值改变

window.addEventListener('hashchange', function(){

    var text = '';// 可以换成模板数据

    switch(location.hash){

        case '#/music':

            text = '各种音乐数据';

            break;

        case '#/movie':

            text = '各种电影数据';

            break;

    }

    document.getElementById('content').innerHTML = text;

});

重定向和404

重定向(写死路径名) {path: '/', redirect: '/home'}

重定向(使用name) {path: '/', redirect: {name: 'home'}}

404:在路由规则的最后一个规则中写一个很强大的匹配 

    {path: '*', component: notFoundVue}

    notFoundVue.vue: 404页面组件

多视图模式

    以前一个路由对应一个

    现在一个路由可以对应多个

    使用components 实现多视图模式

<router-view name="header"></router-view>

    <router-view ></router-view>  没有name使用default

    <router-view name="footer"></router-view>

    routes: [

        {

          path: '/',

          name: 'Home',

          // 注意这里名称为components

          components: {

            header: HeaderVue,

            footer: FooterVue,

            default: Home

          }

        }

    ]

嵌套路由

借助 vue-router,使用嵌套路由配置,就可以很简单地表达这种关系。

    用单页实现多页应用,使用复杂的嵌套路由完成

    开发中一般都会用到嵌套路由

    视图包含视图

    路由父子级关系路由配置

routes: [

{ path: '/user/:id', component: User,

children: [

{

// 当 /user/:id/profile 匹配成功,

// UserProfile 会被渲染在 User 的 <router-view> 中

path: 'profile',

component: UserProfile

},

{

// 当 /user/:id/posts 匹配成功

// UserPosts 会被渲染在 User 的 <router-view> 中

path: 'posts',

component: UserPosts

}

]

}

]

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 151,688评论 1 330
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 64,559评论 1 273
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 101,749评论 0 226
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 42,581评论 0 191
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 50,741评论 3 271
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 39,684评论 1 192
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,122评论 2 292
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 29,847评论 0 182
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 33,441评论 0 228
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 29,939评论 2 232
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,333评论 1 242
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 27,783评论 2 236
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,275评论 3 220
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 25,830评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,444评论 0 180
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 34,553评论 2 249
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 34,618评论 2 249

推荐阅读更多精彩内容

  • # 传智播客vue 学习## 1. 什么是 Vue.js* Vue 开发手机 APP 需要借助于 Weex* Vu...
    再见天才阅读 3,462评论 0 6
  • 相关概念 混合开发和前后端分离 混合开发(服务器端渲染) 前后端分离后端提供接口,前端开发界面效果(专注于用户的交...
    他爱在黑暗中漫游阅读 2,718评论 4 45
  • vue笔记 一.vue实例 vue的生命周期 beforeCreate(创建前), created(创建后), b...
    秋殇1002阅读 1,030评论 0 1
  • 这篇笔记主要包含 Vue 2 不同于 Vue 1 或者特有的内容,还有我对于 Vue 1.0 印象不深的内容。关于...
    云之外阅读 4,971评论 0 29
  • 今天是爸爸开工的第一天 今天下了2018年的第一场雨 风调雨顺,妈妈这么说的
    L小青阅读 343评论 0 0