Vue 基础篇

Vue 基础篇

一、框架与库的区别

  • JQ库->DOM(DOM操作) + Ajax请求
  • art-template库->模板引擎
  • 框架 -> 全方位、功能齐全
    • 简易的DOM体验 + 发请求 + 模板引擎 + 路由功能 + ...
  • 代码上的不同:
    • 一般使用库:调用某个函数,自己可以把控库的代码
    • 一般使用框架:其框架在帮我们运行已编写好的代码
      • 框架:初始化自身的一些行为
      • 执行你所编写的代码
      • 施放一些资源

库:小而精

框架:大而全 ( 框架包含了各种库 )

二、起步

  • 引包
    • 直接用 <script> 引入
    • CDN
    • NPM
npm install --yes
npm install vue --save ( npm install vue -S )
  • 创建实例化对象 **new Vue( options 对象 ) **
    • options
      • el : 目的地( 选择器 )
      • data : 数据属性 ( 既可以是一个对象,也可以是一个函数 )
        • 数据驱动试图:数据发生改变时,视图 发生改变。
        • 除了数据属性,vue 实例还暴露了一些有用的实例属性和方法。他们都有前缀 ,如:el,$data 。
      • template : 模板内容
        • 优先级:如果 template 中定义了内容,那么有限加载 template;反之,加载 el 挂载的模板
  • vue的模板语法:
    • {{}} 双大括号插值 同 react 中的 {}
    • {{ 表达式 }}
      • 对象 ( 不要连续三个大括号 {{ { key : value } }} )
      • 字符串 {{ ’XXX‘ }}
      • 判断后的布尔值 {{ true }}
      • 三元表达式 {{ true ? '正确' : '错误' }}
    • 可以用于页面中简单粗暴的调试
    • 注意:必须在 data 这个函数中返回的对象中声明
  • 设计模式:MVC 与 MVVM
    • MVC:Model( 数据模型 )、View( 视图 )、Controller( 控制器 )
      • 数据不是主动展示到 视图 上的,它是靠 控制器 取到 model 然后展示到 view。
    • MVVM:Model、View、ViewModel
      • vue的设计模式为MVVM, 只关注的是视图层

三、指令 ( v-xxx )

  • 在vue中提供了一些对于页面+数据的更为方便的输出,这些操作就叫做指令
    • 比如html页面中的属性 <div v-xxx></div>
    • 指令中封装了一些DOM行为,结合属性作为一个暗号,暗号有对应的值,根据不同的值,框架会进行相关的DOM操作的绑定。
  • 常用指令
    • v-text:元素的InnerText属性,其实就是给元素的innerText赋值,必须是双标签,跟{{}}效果是一样的,使用较少。
    • v-html:元素的InnerHtml,其实就是给元素的innerHtml赋值
    • v-if:判断是否插入这个元素,相当于对元素的销毁和创建。appendChild()、removeChild()
    • v-else-if
    • v-else
    • v-show:隐藏元素,如果确定要隐藏,会给元素的style加上 display:none;,是基于css样式的切换。
  • v-if 与 v-show 的区别 ( 官网解释 )
    • v-if是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当的被销毁和重建。
    • v-if也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。
    • 相比之下,v-show就简单的多——不管初始条件是什么,元素总会被渲染。并且只是简单的基于css进行 显/隐 切换。
    • 一般来说,v-if有更高的切换开销,而v-show有更高的初始渲染开销。因此,如果需要非常频繁的切换,则使用v-show较好;如果在运行时条件很少改变,则使用v-if较好。
  • v-bind:绑定标签上的属性( 内置的属性和自定义的属性 ),v-bind:class="box",简写 :
<div class="container" :class="{active: true}"></div>
// 渲染为 DOM
<div class="container active"></div>
  • v-on:v-on:原生事件名 = '函数名',简写@
// html
<div class="container" @click="clickHandler"></div>
// js
methods:{
    clickHandler(e){
        console.log(this);
    }
}
  • v-for:v-for="item,index in arr"
<ul>
    <li v-for="item,index in list">
        {{index}}--{{item}}
    </li>
</ul>
  • v-model:数据双向绑定
    • 只会体现在UI空间中,只能应用在有value属性的元素。
<input v-model="msg">
// 等同于
<input :value="msg" @input="msg = $event.target.value" />

那么 v-model 其实就是 v-bindv-on 的语法糖。

四、组件

1.局部组件

局部组件使用打油诗:声子挂子用子

声明子组件;父组件挂载子组件;父组件使用子组件。

// 局部组件的声明
var App = {
    data(){
        return{

        }
    },
    template:`
        <div>我是入口组件</div>
    `
}
// vue实例
new Vue({
    el:"",
    data(){

    },
    // 挂载子组件
    components:{
        App
    },
    // 父组件直接可以使用
    template:`<App />`
})

组件命名:

​ 1.短横线分隔 命名:当引用组件时,也要使用 短横线分隔 形式。( 如: <my-compnent-name> )

​ 2.驼峰式命名:当引用组件时,可以使用 短横线分隔 形式或者 驼峰 形式。( 如: <my-compnent-name> 或 <MyCompnentName>)

​ [注]:直接在DOM( 即非字符串的模板 )中使用时只有 短横线分隔 形式是有效的。

​ [建议]:命名时用 驼峰 形式,使用时用 短横线分隔 形式。

2.全局组件

Vue.component("组件名", options)

// 全局组件声明
// 第一个参数是组件的名字,第二个参数是options配置项
Vue.component("Vbtn", {
    template:`
        <button>按钮</button>
    `
})
// 全局组件使用
var App = {
    template:`
        <div>
            ...
            <Vbtn />
        </div>
    `
}

五、组件通信

1.通过 prop 往子组件通信
  • 1.Parent 2.Child
  • 先给父组件中绑定自定义的属性
Vue.component("Parent", {
    data(){
        return{
            msg:"我是父组件的数据"
        }
    },
    template:`
        <div>
            <p>我是父组件</p>
            <Child :childData="msg" />
        </div>
    `
})
  • 在子组件中使用 props 接收父组件传递的数据

  • 在子组件中任意使用

Vue.component("Child", {
    template:`
        <div>
            <p>我是子组件</p> 
            <input type="text" v-model="childData" />
        </div>
    `,
    props:["childData"]
})
2.通过 事件 向父组件发送消息
  • 在父组件绑定自定义的事件
  • 在子组件中 触发原生的事件,在函数中使用 $emit 触发其父组件中自定义的事件
    • $emit("自定义的事件名", "消息")
// Child
Vue.component("Child", {
    template:`
        <div>
            <p>我是子组件</p> 
            <input type="text" v-model="childData" @input="changeValue(childData)" />
        </div>
    `,
    props:["childData"],
    methods:{
        changeValue(val){
            // 自定义的事件一定要通过 this.$emit() 去触发
            // $emit("自定义的事件名", "消息")
            this.$emit(childHandler, val)
        }
    }
})

// Parent
Vue.component("Parent", {
    data(){
        return{
            msg:"我是父组件的数据"
        }
    },
    template:`
        <div>
            <p>我是父组件</p>
            <Child :childData="msg" @childHandler="childHandlerFn" />
        </div>
    `,
    methods:{
        childHandlerFn(val){
            console.log(val);
        }
    }
})

六、插槽 slot

插槽:内置组件 slot,作为承载分发内容的出口

/* 模拟 elementUI 按钮组件的实现 */
// 子组件
Vue.component("Vbtn", {
    template:`
        <button class="default" :class="type">
            <slot>按钮</slot>
        </button>
    `,
    props:["type"]
})

// 父组件
var App = {
    template:`
        <div>
            ...
            <Vbtn type="primary">登陆</Vbtn>
            <Vbtn type="success">注册</Vbtn>
        </div>
    `
}
具名插槽
// 子组件
Vue.component("liItem", {
    template:`
        <li>
            第一个槽
            <slot name="idx-1"></slot>
            第二个槽
            <slot name="idx-2"></slot>
        </li>
    `
})

// 父组件
var App = {
    template:`
        <div>
            <ul>
                <liItem>
                    <h1 slot="idx-1">我是第一个槽</h1>
                    <h3 slot="idx-2">我是第二个槽</h3>
                </liItem>
            </ul>
        </div>
    `
}

七、过滤器

  • 过滤器的作用:为页面中的数据进行添油加醋的功能
  • 分类
    • 局部过滤器
    • 全局过滤器
/* 局部过滤器 */
// 1.声明过滤器
// 2. {{ 数据 | 过滤器的名字 }}
var App = {
    data(){
        return{
            price:0,
            msg:"hello filter"
        }
    },
    template:`
        <div>
            <input type="number" v-model="price" />
            <!-- 使用过滤器 -->
            <h2>{{ price | myCurPrice }}</h2>
            <h3>{{ price | myReverse }}</h3>
        </div>
    `,
    filters:{
        // 声明过滤器
        myCurPrice: function(val){
            return "¥" + val
        }
    }
}

/* 全局过滤器 */
// 字符串反转过滤器
Vue.filter("myReverse", function(val){
    return val.split("").reverse().join("");
})

{{ 数据 | 过滤器的名字(可以传值) }}

例:

​ {{ price | myReverse("这里是传入的值") }}

​ // 其中 arg 就是传入的值

​ Vue.filter("myReverse", function(val, arg){
​ return val.split("").reverse().join("");
​ })

八、watch 监听

watch 监听的是单个属性

基本的数据类型 -- 简单监视

复杂的数据类型 -- 深度监视

  • 监听简单数据类型
new Vue({
    el:"",
    data(){
        return{
            msg : ''
        }
    },
    watch:{
        msg: function(newVal, oldVal){
            console.log(newVal, oldVal);
        }
    }
})
  • 监听复杂数据类型 obj, arr, 等 -- 深度监视
new Vue({
    el:"",
    data(){
        return{
            userList : [{name:"jack"}]
        }
    },
    watch:{
        userList: {
            deep:true, // 深度监视
            handler: function(newVal, oldVal){
                console.log(newVal, oldVal);
            }
        }
    }
})

九、计算属性

  • 计算属性 getter
// html
<img :src="getCurSrc" />
<ul>
    <li v-for="item,index in dataList" @click="clickHandler(index)" :class="{active: curIdx == index}">{{ index }}</li>
</ul>

// js
new Vue({
    el:"",
    data(){
        return{
            dataList:[{imgsrc:'1'},{imgsrc:'2'},{imgsrc:'3'}],
            curIdx : 0
        }
    },
    computed:{
        // 计算属性默认只有 getter
        getCurSrc: function(){
            return this.dataList[this.curIdx].imgsrc
        }
    },
    methods:{
        clickHandler(index){
            this.curIdx = index;
        }
    }
})
  • 计算属性 setter
// js
new Vue({
    computed:{
        getCurSrc: {
            set: function(newVal){
                console.log(newVal);
                this.curIdx = newVal;
            },
            get: function(){
                return this.dataList[this.curIdx].imgsrc
            }
        }
    },
    methods:{
        clickHandler(index){
            // 点语法 set方法 和 get方法
            // getter 方法
            console.log(this.getCurSrc);
            // 调用set方法
            this.getCurSrc = index;
        }
    }
})

十、生命周期

  • beforeCreate:组件创建之前会调用
  • created:组件创建之后 会调用
    • 在created这个方法中可以操作后端的数据,数据驱动视图
    • 应用:发起Ajax请求
  • beforeMount:挂载数据到 DOM 之前会调用
  • mounted:挂载数据到 DOM 之后会调用
    • 应用:操作DOM
  • beforeUpdate:在更新DOM之前 调用该钩子
    • 应用:可以获取原始的DOM
  • updated:在更新DOM之后 调用该钩子
    • 应用:可以获取最新的DOM
  • beforeDestroy:组件销毁之前会调用
  • destroyed:组件销毁之后会调用

vue 内置组件 <keep-alive></keep-alive>:能在组件的切换过程中将状态保留在内存中,防止重复渲染DOM。

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

推荐阅读更多精彩内容

  • 1.安装 可以简单地在页面引入Vue.js作为独立版本,Vue即被注册为全局变量,可以在页面使用了。 如果希望搭建...
    Awey阅读 10,982评论 4 129
  • # 传智播客vue 学习## 1. 什么是 Vue.js* Vue 开发手机 APP 需要借助于 Weex* Vu...
    再见天才阅读 3,523评论 0 6
  • VUE介绍 Vue的特点构建用户界面,只关注View层简单易学,简洁、轻量、快速渐进式框架 框架VS库库,是一封装...
    多多酱_DuoDuo_阅读 2,684评论 1 17
  • 前言 您将在本文当中了解到,往网页中添加数据,从传统的dom操作过渡到数据层操作,实现同一个目标,两种不同的方式....
    itclanCoder阅读 25,730评论 1 12
  • 主要还是自己看的,所有内容来自官方文档。 介绍 Vue.js 是什么 Vue (读音 /vjuː/,类似于 vie...
    Leonzai阅读 3,324评论 0 25