玩转自如——VUE.JS实战开发系列

vue实战开发

分享指南

1.渐进式框架
2.vue中两个核心点
3.虚拟DOM
4.MVVM模式
5.vue实例
6.声明式渲染
7.指令
8.模板


基础语法
vue实例

一.vue介绍

1.渐进式框架vue
vue是什么

构建用户界面的渐进式框架
只关注视图层(view)


2.vue中两个核心点
响应的数据绑定

当数据发生改变---->自动更新视图
利用Object.definedProperty中的setter/getter代理数据,监控对数据的操作

组合的视图组件

ui页面映射为组件树
划分组件可维护 可重用可测试

3.虚拟DOM(virtual DOM)

运行js的速度是很快的,大量的操作DOM就会很慢.时长在更新数据后会重新渲染页面,这样造成在没有改变数据的地方也重新渲染DOM节点,这样就造成了很大程度上的资源浪费.
利用在内存中生成与真实DOM与之对应的数据结构,这个在内存中生成的结构称之为虚拟DOM.
当数据发生变化时,能够智能地计算出重新渲染组件的最小代价并应用到DOM操作上.


过程.png
虚拟DOM示意图.png
4.MVVM模式

M: Model数据模型
V: view视图模板
VM: view-Model 视图模型


MVVM.png
5.vue实例
渐进式框架学习提纲

基础语法

...
vue实例 模板语法
计算属性 class和style绑定
条件和列表渲染 事件处理器
表单控件绑定 组件

高级进阶

...
vue插件编写 mixin混合
过度效果 自定义制定
vue-router:路由系统的使用 vueX:状态管理器

构建工具

...
node.js:javascript运行环境 webpage:模块管理和打包工具
vue-cli:脚手架配置

vue实例
每一个应用都是通过vue这个构造函数创建根实例(root instance)启动 new Vue(选项对象)
需要传入选项对象,对象包含挂在元素,数据,模板,方法等...
el:挂载元素选择器   String|HemlElement
data: 代理数据     Object|Function
methods:定义方法   Object

<div id="demo">
    <input type="text" id="" v-model="message">
    <p v-on:click="clickHandle">{{message}}</p>
</div>
<script>
    var data={message:"hello"}
    var vm=new Vue({
        el:"#demo",
        data:data,
        methods:{
            clickHandle:function(){
                alert("click")
            }
        }
    })
</script>

vue代理data数据
每个vue实例都会代理其data对象里所有的属性,这些被代理的属性是响应的.新添加的属性不具备响应功能,改变后不会更新视图.

vue实例自身属性和方法
暴露自身的属性和方法,以$开头 例如 :$el $data...

6.声明与渲染

声明式
只需要声明在哪里(where)做什么(what),而无需关心如何实现(how)

命令式
需要以具体代码表达在哪里(where)做什么(what),如何实现(how)
例子: 求数据中每一项的倍数
命令式 使用for虚幻拿出每一项然后求值完成,再放入另一数组中
声明式:使用map方法,关注如何求值

vue声明式渲染
初始化根实例,vue自动将数据绑定在DOM模板上

7.指令

什么是指令
 是一种特殊的自定义行间属性
 指令的职责就是当期表达式的值改变时相应的将某些行为应用到DOM上
 在Vue中,指令以V-开头

vue中的内置指令

  • v-bind  动态的绑定数据。简写为
  • v-on    绑定事件监听器。简写为
  • v-text   更新数据,会覆盖已有结构
  • v-html    可以解析数据中的html结构
  • v-show  根据值的真假,切换元素的display属性
  • v-if     根据值的真假,切换元素会被销毁,重建
  • v-else-if  多条件判断,为真则渲染
  • v-else    条件都不符合渲染
  • v-for    基于源数据多次渲染元素或模板块
  • v-model  在表单控件元素航创建双向数据绑定
  • v-pre    跳过元素和子元素的编译过程
  • v-once   只渲染一次,随后数据更新不重新渲染
  • v-cloak   隐藏未变异的Mustache语法,css中设置[v-cloak]{display:none}
8.模板
A.html模板

html模板
基于DOM的模板,模板都是可解析的有效的HTML
插值
文本插值:使用"Mustache"语法(双大括号) {{value}}
作用:替换实例上的属性值,当值改变时,插值内容会自动更新
原生的html:双大括号输出的是文本,不会解析html(如要解析,添加指令v-html)
属性: 使用v-bind进行绑定,可以响应变化
使用JavaScript表达式:写简单的表达式

示例代码: 插值原生的HTML在双大括号输出的是文本,不会解析成HTML 这就要用到v-html
<div id="demo">
    <span v-html="html"></span>
    {{1+2}} //一些简单的表达式
    {{true?"yes":"no"}} //三目可以 但是不要写if语句
</div>
<script>
    /*数据*/
     let obj={
       html:"<div>这是一段html</div>"
    }
    var  vm=new Vue({
        el:"#demo",
        data:obj
    })
</script>
/*不要在模板里做过多的逻辑处理*/
B.字符串模板

template字符串

  • template选项对象的属性
  • 模板将会替换挂载的元素,挂在元素的内容将被忽略
  • 根节点只能有一个
  • 将HTML结构写在一对script标签中,设置 type="x-template"
示例代码:===>输出内容 : 这是一段str 123456
<!--模板-->
<div id="demo">
    <span>我是span里的原始内容</span>
</div>
<script>
    /*数据*/
     let obj={
       html:"<div>这是一段html</div>",
       abc:"123456"
    }
    var str="<div>这是一段str {{abc}}</div>"
    var  vm=new Vue({
        el:"#demo",
        data:obj,
        template:str
    })
</script>
示例代码2 : 将HTML结构写在一对script标签中,设置 type="x-template"
<div id="demo">啊?</div>
<script type="x-template" id="temp">
    <div>{{abc}}
        <span>我是span里的原始内容</span>
    </div>
</script>
<script>
    /*数据*/
     let obj={
       abc:"哈哈哈..."
    }
    var  vm=new Vue({
        el:"#demo",
        data:obj,
        template:"#temp"
    })
</script>
C.模板-render函数

render函数

  • render选项对象的属性
  • createElement(标签名,[数据对象],子元素);
  • 子元素为文本或数组
示例一:
<div id="demo"><span :class='{red:addClass}'>hello vue</span></div>
<script>
    /*数据*/
     let obj={
       addClass:true
    }
    var  vm=new Vue({
        el:"#demo",
        data:obj
});
</script>

render函数示例:
 <style> .bg{background:yellow}</style>
 <div id="demo"></div>
<script>
    /*数据*/
     let obj={
       addClass:true
    }
    var  vm=new Vue({
        el:"#demo",
        data:obj,
       render:function(createElement){
            return createElement(
                "ul",
                {
                    class:{bg:true},
                    style:{
                        fontSize:"50px",
                        listStyle:"none"
                    },
                    attrs:{
                        key:"我是value啊"
                    },
                    domProps:{
                        innerHTML:"<li>我是html</li>"
                    }//谨慎使用
                },
                [
                    createElement("li",1),
                    createElement("li",2),
                    createElement("li",3)
                ]
            )
       }
    })
</script>

数据对象属性
class:{} //绑定class,和v-bind:class一样的API (绑定和原生可以共存)
style:{} //绑定样式,和v-bind:style一样的API
attrs:{} //添加行间属性
domProps:{} //DOM元素属性
on:{} //绑定事件

nativeOn:{} //监听原生事件
directives:{} //自定义指令
scopedSlots:{} //slot作用域
slot:{} //定义slot名称
key:"key" //给元素添加唯一标识
ref:"ref" //引用信息

二 案例:增删便签 深入讲解 指令&模板

列表渲染
  • v-for指令
    根据一组数据的选项列表进行渲染
    语法 :
    value,key in items
    value,key of items
    变异方法
    vue提供一组方法,对数组进行操作的时候,会触发视图更新
    push() pop() shift() unshift() splice() sort() reverce()
事件处理器
  • v-on指令
    用来监听DOM事件触发代码
    语法: v-on:eventName="evnetHandle"
    指令简写: @
    事件处理函数,写在methods中统一管理
    事件对象 , 在事件处理函数中获取 , 内联事件处理函数执行 , 传入事件对象 $event
    事件修饰符 : 事件处理函数只有纯粹的逻辑判断 , 不处理DOM事假的细节
    例如:阻止冒泡,取消默认行为,判断按键
事件修饰符
  • 事件修饰符
    事件处理函数只有纯粹的逻辑判断,不处理DOM事件的细节 例如,阻止冒泡,取消默认行为,判断按键
    修饰符的位置:v-on;eventName.修饰符
    修饰符: .stop .prevent .capture .self .once
    按键修饰符: .enter .tab .delete .esc .space .up .down .left .right .ctrl .alt .shift .meta .键值
条件渲染
  • v-show指令
    根据表达式的值,用来显示/隐藏元素
    语法: v-show="表达式"
    元素会被渲染在页面中,只根据表达式的值进行css切换
动态class
  • 动态绑定class
    class也为元素的属性,可以使用v-bind:class
    语法
    :class="{className:表达式}"
    表达式值为true 添加className
    表达式值为false不添加className

    :class="[className,classname]"

自定义指令
  • 自定义指令
    除了vue内置的指令,可以自己设置指令
    选项对象的directives属性
    {
    directives:{ }
    }
    钩子函数:
    update被绑定元素所在的模板更新时调用
    钩子函数中参数:
    el:指令所绑定的元素,可以用来直接操作DOM
    binding:一个对象
    value:指令的绑定值
计算数据
  • 为什么要使用计算属性
    模板是为了描述视图的结构,模板中放入太多逻辑,导致模板过重且难以维护.
    在计算一个计算属性时,vue.js更新它的依赖列表并缓存结果,只有当其中一个依赖发生的变化,缓存的结果才无效.
    语法:
    在选项对象中
    {
    ...
    computed:{}
    }

五.watch深度监控数据

六.利用hash过滤数据

onhashchange 事件在当前 URL 的锚部分(以 '#' 号为开始) 发生改变时触发 。

锚部分的实例:指定当前 URL 为
http://www.example.com/test.htm#part2 - 这个 URL 中的锚部分为 #part2。

你可以使用以下方式调用事件:

七.什么是组件

组件化开发
  • 什么是组件?
    WEB中的组件其实就是页面组成的一部分,好比是电脑中的每一个元件(如硬盘,键盘,鼠标),它是一个具有独立的逻辑和功能或界面,同时又能根据规定的接口规则进行相互融合,变成一个完整的应用.
    页面就是由一个个类似这样的部分组成的,比如导航,列表,弹窗,下拉菜单等.页面只不过是这些组件的容器,组件自由组合形成功能完整的界面,当不需要某个组件,或者想要替换某个组建时,可以随时进行替换和删除,而不影响整个应用的运行.
    前端组件化的核心思路就是将一个巨大复杂的东西拆分成粒度合理的小东西
  • 使用组件的好处
    提高开发效率
    方便重复使用
    简化调整步骤
    提升整个项目的可维护性
    便于协同开发
vue中的组件
  • vue中的组件
    vue中组件是一个自定义标签,Vue.js的编辑器为它添加特殊功能
    vue也可以扩展原生的html元素,封装可重用的代码

组件的基本组成 : 样式结构 行为逻辑 数据

注册组件
  • 全局注册
    可以再任何模板中使用,使用之前要先注册
    语法: 使用Vue.component(组件名,选项对象)
    组件名命名约定:驼峰(camelCase),烤串(kebab-case)
    在html中使用组件:
    使用烤串(kebab-case)命名法
    使用: <my-component></my-component>
  • 局部注册
    在组件实例中通过选项对象注册,只在所注册的作用域中使用
    {
    components:{
    组件名:选项对象
    }
    }

局部注册:

 new Vue({
       el:"#app",
       components:{
       "custom-select":{
              template:`<section></section>`
         }
       }
 })

全局注册:

Vue.component("custom-select",{
      template:`<section class="warp"></section>`
})
组件间通信

父组件要给子组件传递数据,子组件需要将它内部发生的事情告知给父组件

  • 父组件-->子组件
    组件实例的作用域是孤立的,不能在子组件直接用父组件的数据
    可以在组件上使用自定义属性绑定数据,在组件中需要显示的用props声明自定义属性名

  • 子组件-->父组件
    需要用到自定义事件,父组件用$on监听自定义事件,$emit触发父组件所关心的自定义事件

组件间通信示意图.png

八.使用props传递数据

<div id="app-7">
  <ol>
    <!--
      现在我们为每个 todo-item 提供 todo 对象
      todo 对象是变量,即其内容可以是动态的。
      我们也需要为每个组件提供一个“key”,稍后再
      作详细解释。
    -->
    <todo-item
      v-for="item in groceryList"
      v-bind:todo="item"
      v-bind:key="item.id">
    </todo-item>
  </ol>
</div>

Vue.component('todo-item', {
  props: ['todo'],
  template: '<li>{{ todo.text }}</li>'
})

var app7 = new Vue({
  el: '#app-7',
  data: {
    groceryList: [
      { id: 0, text: '蔬菜' },
      { id: 1, text: '奶酪' },
      { id: 2, text: '随便其它什么人吃的东西' }
    ]
  }
})

组件中的data必须是函数

每个组件都是相互独立的,如果他们共用一个对象,在更改一个组件数据的时候,会影响其他组件,如果是函数的话,每个组件都有自己独立的数据,相互之间不会影响.

九.特殊is属性扩展原生html元素
受限制的元素
  • DOM模板解析
    Vue是在浏览器解析和标准化 HTML后才能获取模板内容,所以有些元素限制了能被它包裹的元素
    例如: ul中只能放li; select中只能放option
    某些元素中放入了自定义元素,不符合W3C标准,最终会解析错误

变通的方式是使用特殊属性 is来扩展HTML标签功能

十.v-bind动态绑定数据&十一.利用自定义事件通信

案例:

<div id="app">
    <h2>自定义下拉框</h2>
    <custom-select btn-value="查询" v-bind:list="list1"></custom-select>
    <custom-select btn-value="搜索" v-bind:list="list2"></custom-select>
</div>
<script>
    //注册组件 全局注册
    Vue.component("custom-select",{
        data:function(){
            return{sel:false, val:""}

        },
        props:["btnValue","list"],
        template:`<section class="warp">
                <div class="searchIpt clearFix">
                    <div class="clearFix">
                        <input type="text" class="keyWord" v-bind:value="val"  @click="sel=!sel"/>
                        <input type="button" v-bind:value="btnValue">
                        <span></span>
                    </div>
                    <custom-list v-show="sel" v-bind:list="list" v-on:receive="changeValue"></custom-list>
                </div>
            </section>`,
        methods:{
            changeValue:function(value){
                console.log(value)
                this.val=value;
            }
        }
    })
    Vue.component("custom-list",{
        props:["list"],
        template:`<ul class="list" >
                        <li  v-for="item in list" @click="selectValueHandle(item)">{{item}}</li>
                    </ul>`,
        methods:{
            selectValueHandle:function(item){
                //子组件中有交互 数据放到input当中去 告知父级,改变val的值 需要触发一个自定义事件
                this.$emit('receive',item) //this.item
            }
        }
    })
    var data={
        list1:["北京","上海","杭州"],
        list2:["17,10,25","18,1,1","17,12,22"]
    }
    new Vue({
        el:"#app",
        data:data
    })
</script>
十二.单向数据流
什么是单向数据流

数据从父组件流向(传递)给子组件,只能单向绑定
在子组件内部不应该修改父组件传递过来的数据

  • 改变prop的情况:
    1.作为data中局部数据的初始值使用
    2.作为子组件种的computed树属性
<div id="app">
    <custom-component :count="count"></custom-component>
</div>
<script>
    Vue.component('custom-component',{
        props:['count'],
        data(){
          return {
              incrementCount:this.count//作为局部这个组件的data的初始值
          }
        },
        computed:{
            incrementCount2(){
                return this.incrementCount;
            }
        },
        template:`
            <div>
             <h2>我是一个自定义组件</h2>
             <input type="button" value="改变count的值" @click="changeCount">
             {{incrementCount2}}
            </div>
         `,
        methods:{
            changeCount(){
                this.incrementCount++;
            }
        }
    })
    var vm=new Vue({
        el:"#app",
        data:{count:0},
        methods:{

        }
    })
</script>
十三.props验证

组件可以为props指定验证要求,如果未指定验证要求,vue会发出警告

props:{
  propA:Number,//指定类型
  propB:[String,Number],//多种类型
  propC:{type:String,required:true},//字符串类型,默认值为100
  propD:{type:Number,default:100}.//字符串类型,默认值为100
  propE:{type:Number,default:function(){
                 return 1000
  }
},
//自定义验证规则
propF:{validator:function(value){return value>10}}

验证类型为原生构造器:String,Number,FunctionObject,Boolean,Array

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

推荐阅读更多精彩内容