前端学习 Vue笔记 完整版

1.1 搭建Vue开发环境

  • 项目导入开发版本文件
<script type="text/javascript" src="../js/vue.js"></script>
<script>
	Vue.config.productionTip = false
</script>

1.2 Hello案例

在根目录放置 favicon.ico 文件即可在标签中显示

一般推荐在配置结束后再开始 Vue 组件

  1. 想让Vue工作,就必须创建一个Vue实例,且要传入一个配置对象;
  2. root容器里的代码依然符合html规范,只不过混入部分Vue语法;
  3. root容器里的代码称为【Vue模板】;
  4. Vue实例和容器是一一对应的;
  5. 真实开发中只有一个Vue实例,并且会配合着组件一起使用;
  6. {{xxx}}中的xxx要写js表达式,且xxx可以自动读取到data中的所有属性;
  7. 一旦data中的数据发生改变,那么模板中用到该数据的地方也会自动更新;
<body>
    <!-- 准备一个容器 -->
    <div id="root">
        <h1>Hello,{{name}},{{Date.now()}}</h1>
    </div>

    <script>
        Vue.config.productionTip = false
        // 创建Vue实例
        new Vue({
            el: '#root',
            data: {
                name: 'HMS Home'
            }
        })
    </script>
</body>

1.3 模板语法

  • 插值语法

​ 功能:用于解析标签体内容

​ 写法:{{xxx}},xxx是js表达式,且可以直接读取data中的所有属性

  • 指令语法

​ 功能:用于解析标签(包括:标签属性、标签体内容、绑定事件……)

​ 写法:v-???=“xxx”,xxx同样要写js表达式

<body>
    <div id="root">
        <h1>插值语法</h1>
        <h3>Hello,{{name}}</h3>
        <hr>
        <h1>指令语法</h1>
        <a :href="school.url">{{school.name}}的博客</a>
    </div>
</body>

<script>
    Vue.config.productionTip = false
    new Vue({
        el: '#root',
        data: {
            name: "HMS Home",
            school: {
                name: "HMS Home",
                url: "https://blog.csdn.net/Winchester_Y?spm=1010.2135.3001.5421"
            }
        }
    })
</script>

1.4 数据绑定

Vue中有2种数据绑定的方式:

  1. 单向绑定(v-bind):数据只能从data流向页面
  2. 双向绑定(v-model):数据会 data<=>页面
  • 双向绑定只能运用在表单类元素上(如:input、select等)
  • v-model:value可以简写为 v-model,因为v-model默认收集的就是value值
<body>
    <div id="root">
        <!-- 单向数据绑定:<input type="text" v-bind:value="name"><br>
        双向数据绑定:<input type="text" v-model:value="name"> -->
        单向数据绑定:<input type="text" :value="name"><br>
        双向数据绑定:<input type="text" v-model="name">
    </div>
</body>
<script type="text/javascript">
    Vue.config.productionTip = false
    new Vue({
        el: '#root',
        data: {
            name: 'HMS Home'
        }
    })
</script>

1.5 el和data的两种写法

  1. el有2种写法

    1. new Vue时配置el属性
    2. 先创建Vue实例,再通过xxx.$mount(‘#root’)指定el值
  2. data有2种写法

    1. 对象式

    2. 函数式

      学到组件时,data必须使用函数式,否则会报错

  3. 一个重要的原则

    ​ 由Vue管理的函数,一定不要写箭头函数

<body>
    <div id="root">
        你好,{{name}}
    </div>
</body>
<script>
    Vue.config.productionTip = false
    // const v = new Vue({
    //     // el: '#root',
    //     data: {
    //         name: 'HMS Home'
    //     }
    // })
    // console.log(v);
    // v.$mount('#root')
    new Vue({
        // data的第一种写法:函数式
        el: '#root',
        // data: {
        //     name: 'HMS Home'
        // }
        data: function () {
            return {
                name: 'HMS Home'
            }
        }
    })
</script>

1.6 MVVM模型

  1. M:模型(model):data中的数据
  2. V:视图(View):模板代码
  3. VM:视图模型(ViewModel):Vue实例

观察发现

  1. data中所有的属性,都出现在了vm身上
  2. vm身上所有的属性以及Vue原型上所有的属性,在Vue模板中都可以直接使用

1.7 数据代理

1.8 事件处理

1.8.1事件修饰符
  1. prevent:阻止默认事件(常用)
  2. stop:阻止事件冒泡(常用)
  3. once:事件只触发一次
  • 修饰符可以连续写
<body>
    <div id="root">
        <h2>欢迎来到{{name}}的博客</h2>
        <a href="https://blog.csdn.net/Winchester_Y?spm=1010.2135.3001.5421" @click.prevent="showInfo">查看</a>
        <div class="demo1" @click="showInfo">
            <button @click.stop="showInfo">点击</button>
        </div>
        <button @click.once="showInfo">点击</button>
        <div class="box1" @click="showMsg(1)">
            div1
            <div class="box2" @click.stop="showMsg(2)">
                div2
            </div>
        </div>
    </div>
</body>
<script>
    Vue.config.productionTip = false
    new Vue({
        el: '#root',
        data: {
            name: 'HMS Home'
        },
        methods: {
            showInfo() {
                alert('你好')
            },
            showMsg(msg) {
                console.log(msg);
            }
        }
    })
</script>
1.8.2键盘事件
  1. Vue常用按键
    • 回车 enter
    • 删除 delete
    • 退出 esc
    • 空格 space
    • 换行 tab(特殊,必须搭配keydown使用)
    • 上 up
    • 下 down
    • 左 left
    • 右 right
  2. Vue未提供的按键可以使用按键原始的key值去绑定,但注意格式
  • 键盘也可以连着写,说明同时按下会发生的操作
<body>
    <div id="root">
        <input type="text" placeholder="键盘事件" @keydown.tab="showInfo">
    </div>
</body>
<script>
    Vue.config.productionTip = false
    new Vue({
        el: '#root',
        data: {
        },
        methods: {
            showInfo(e) {
                console.log(e.key, e.keyCode)
            }
        }
    })
</script>

1.9 计算属性-computed

  1. 定义:要用的属性不存在,要通过已有属性计算得来
  2. 原理:底层借助了Object.defineproperty方法提供的getter和setter
  3. get函数什么时候执行?
    1. 初次执行时会执行一次
    2. 当以来的数据发生改变时会被再次调用
  4. 优势:与methods实现相比,内部有缓存机制,效率更高
  5. 备注:
    1. 计算属性最终会出现在vm上,直接读取即可
    2. 如果计算属性要被修改,那么必须写set函数去响应修改,且set中要引起计算时依赖的数据发生
<body>
    <div id="root">
        姓:<input type="text" v-model:value="xing"><br>
        名:<input type="text" v-model:value="ming"><br>
        你的名字:{{fullName}}
    </div>
</body>
<script>
    Vue.config.productionTip = false
    var vm = new Vue({
        el: '#root',
        data: {
            xing: '',
            ming: ''
        },
        methods: {

        },
        computed: {
            fullName: {
                get() {
                    return this.xing + ' ' + this.ming
                },
                set(value) {
                    const arr = value.split(' ');
                    this.xing = arr[0];
                    this.ming = arr[1]
                }
            }
        }
    })
</script>

1.10 监视属性-watch

  1. 当被监视的属性变化时,回调函数自动调用,进行相关操作
  2. 监视的属性必须存在,才能进行监视!!
  3. 监视的两种写法:
    1. new Vue时传入watch配置
    2. 通过vm.$watch监视
<body>
    <div id="root">
        <h2>天气很{{weather}}</h2>
        <button @click="changeWeather">切换天气</button>
    </div>
</body>
<script>
    Vue.config.productionTip = false
    new Vue({
        el: '#root',
        data: {
            isHot: true
        },
        methods: {
            changeWeather() {
                this.isHot = !this.isHot
            }
        },
        computed: {
            weather() {
                return this.isHot ? '炎热' : '凉爽'
            }
        },
        watch: {
            isHot: {
                handler(newValue, oldValue) {
                    console.log('isHot被修改了', newValue, oldValue);
                }
            }
        }
    })
</script>
1.10.1深度监视
  • 深度监视:
    1. Vue中的watch默认不监测对象内部值得改变(一层)
    2. 配置deep:true可以监测对象内部值改变(多层)
  • 备注:
    1. Vue自身可以监测对象内部值的改变,但Vue提供的watch默认不可以
    2. 使用watch时根据数据的具体结构,决定是否采用深度监测
            numbers: {
                deep: true,
                handler() {
                    console.log('numbers被改变了');
                }
            }
1.10.2computed和watch区别
  • computed和watch之间的区别
    1. computed能完成的功能,watch都可以完成
    2. watch能完成的功能,computed不一定能完成,例如:异步操作
  • 两个重要的小原则
    1. 所被Vue管理的函数,最好写成普通函数,这样this的指向才是vm或组件实例对象
    2. 所有不被Vue管理的函数(定时器的回调函数,ajax的回调函数等),最好写成箭头函数,这样this的指向才是vm或组件实例对象

1.11 条件渲染

  1. v-if

    • 写法

      1. v-if=“表达式”
      2. v-else-if=“表达式”
      3. v-else=“表达式”

      适用于:切换频率较低的场景

      特点:不展示的DOM元素直接被移除

      注意:可以搭配template使用,可以在不破坏结构的条件下做修改

  2. v-show

    • 写法:v-show=“表达式”
    • 适用于:切换频率较高
    • 特点:不展示的DOM元素未被移除,仅仅是使用样式隐藏掉
<body>
    <div id="root">
        <h2 v-if="a">你好,{{name}}</h2>
        <button @click="ifShow">显示/隐藏</button>
    </div>
</body>
<script>
    Vue.config.productionTip = false
    new Vue({
        el: '#root',
        data: {
            name: 'HMS Home',
            a: true
        },
        methods: {
            ifShow() {
                this.a = !this.a
            }
        }
    })
</script>

1.12 列表渲染

1.12.1基本列表

v-for指令

  1. 用于展示列表数据
  2. 语法:v-for=“(item,index) in xxx” :key=“yyy”
  3. 可遍历:数组、对象、字符串(用得少)、指定次数(用得少)
<body>
    <div id="root">
        <!-- 遍历数组 -->
        <h2>复刻的部分舰船</h2>
        <ul>
            <li v-for="(p,index) in persons" :key="p.id">
                {{p.name}}-{{p.rare}}
            </li>
        </ul>
    </div>
</body>
<script>
    Vue.config.productionTip = false
    new Vue({
        el: '#root',
        data: {
            persons: [
                { id: '001', name: 'HMS Howe', rare: 3 },
                { id: '002', name: 'HMS Perseus', rare: 3 },
                { id: '003', name: 'HMS Valiant', rare: 2 },
            ]
        },
        methods: {

        }
    })
</script>
1.12.2key作用与原理
  1. 用index作为key可能会引发的问题:
    1. 若对数据进行:逆序添加、逆序删除等破坏顺序操作==>会产生没有必要的真实DOM更新
    2. 如果结构包含输入类DOM:会产生错误DOM更新
  2. 开发中如何选择key
    1. 最好每天数据有唯一的标识作为key
    2. 如果不存在逆序操作等破坏顺序的操作,用index作为key是没问题的
1.12.3总结

Vue监视数据的原理:

  1. Vue会监视data中所有层次的数据

  2. 如何监视对象中的数据?

    • 通过setter实现,且要在new Vue时就传入要监测的数据
      1. 对象中后追加的属性,Vue默认不做响应式处理
      2. 如需给后添加的属性做响应式,请使用如下API
        • Vue.set(target,propertyName/index,value)
        • vm.$set(target,propertyName/index,value)
  3. 如何监测数组中的数据

    • 通过包裹数组更新元素的方法实现,本质就是做了两件事
      1. 调用原生对应的方法对数组进行更新
      2. 重新解析模板,进而更新页面
  4. 在Vue修改数组中的某个元素一定要用如下方法

    1. 使用这些API:push()、pop()、shift()、unshift()、splice()、sort()、reverse()
    2. Vue.set() 或 vm.$set()
    • 特别注意:Vue.set()和vm.$set()不能给vm或vm的根数据对象添加属性!!!
<body>
    <div id="root">
        <h1>舰船信息</h1>
        <button @click="people.rare++">稀有度+1</button><br>
        <button @click="addCamp">添加默认主阵营,默认值碧蓝航线</button><br>
        <button @click="people.camp='赤色中轴'">修改主阵营</button><br>
        <button @click="addOthers">在列表首位添加一个其他舰娘</button><br>
        <button @click="changeOthers">修改第一个舰娘的名字为:小加加</button><br>
        <button @click="addMengdian">添加第一个萌点</button><br>
        <button @click="changeMengdian">修改第一个萌点为:小饼干</button><br>
        <button @click="removeMengdian">过滤掉萌点中的一脸嫌弃</button><br>
        <h3>名称:{{people.name}}</h3>
        <h3>稀有度:{{people.rare}}</h3>
        <h3 v-if="people.camp">主阵营:{{people.camp}}</h3>
        <h3>萌点:</h3>
        <ul>
            <li v-for="(h,index) in people.mengdian" :key="index">
                {{h}}
            </li>
        </ul>
        <h3>皇家的其他角色</h3>
        <ul>
            <li v-for="(f,index) in people.others" ::key="index">
                {{f.name}}-{{f.rare}}
            </li>
        </ul>
    </div>
</body>
<script>
    Vue.config.productionTip = false
    const vm = new Vue({
        el: '#root',
        data: {
            people: {
                name: 'HMS Home',
                rare: 3,
                mengdian: ['连身袜', '半掌手套', '女子力爆表', '单纯的贵族小姐', '一脸嫌弃'],
                others: [
                    { name: 'HMS Perseus', rare: '3' },
                    { name: 'HMS Valiant', rare: '2' }
                ]
            }
        },
        methods: {
            addCamp() {
                Vue.set(this.people, 'camp', '碧蓝航线')
            },
            addOthers() {
                this.people.others.unshift({ name: '樫野', rare: '2' })
            },
            changeOthers() {
                this.people.others[0].name = "萨拉托加"
            },
            addMengdian() {
                this.people.mengdian.unshift('撩舰')
            },
            changeMengdian() {
                Vue.set(this.people.mengdian, 0, '小饼干')
            },
            removeMengdian() {
                this.people.mengdian = this.people.mengdian.filter((h) => {
                    return h !== '一脸嫌弃'
                })
            }
        }
    })
</script>

1.13 收集表单数据

  • ,则v-model收集的是value值,用户输入的就是value值

  • ,则v-model收集的是value值,要给标签配置value值

    1. 没有配置input的value属性,那么收集的就是checked
    2. 配置input的value属性
      1. v-model的初始值是非数组,那么收集的就是checked
      2. v-model的初始值是数组,那么收集的的就是value组成的数组

    备注:v-model的三个修饰符:

    • lazy:失去焦点再收集数据
    • number:输入字符串转为有效的数字
    • trim:输入首尾空格过滤

1.14 过滤器

1.15 内置指令

1.16 自定义指令

1.17 生命周期

1.17.1引出生命周期

生命周期:

  1. 又名:生命周期回调函数、生命周期函数、生命周期钩子
  2. 是什么:Vue在关键时刻帮我们调用的一些特殊名称的函数
  3. 生命周期函数的名字不可更改,但函数的具体内容是程序员根据需求编写的
  4. 生命周期函数中的this指向的是vm 或 组件实例对象
<body>
    <div id="root">
        <h2 :style="{opacity}">{{name}}</h2>
    </div>
</body>
<script>
    Vue.config.productionTip = false
    const vm = new Vue({
        el: '#root',
        data: {
            name: 'HMS Home',
            opacity: 1,
        },
        mounted(){
            setInterval(() => {
                this.opacity -= 0.01;
                if (this.opacity <= 0) vm.opacity = 1
            }, 16)
        }
    })
</script>
1.17.2挂载流程
  • 常用的生命周期钩子
    1. mounted:发送ajax请求、启动定时器、绑定自定义事件、订阅信息等
    2. beforeDestory:清楚定时器、解绑自定义事件、取消订阅消息等
  • 关于销毁Vue实例
    1. 销毁后Vue开发者工具看不到任何消息
    2. 销毁后自定义事件会失效,但原生DOM事件任然生效
    3. 一般不会在beforeDestory操作数据,因为即使操作,也不会触发更新

2.1 模块与组件

Vue中使用组件的三大步骤:

  1. 定义组件(创建组件)
    • 使用Vue.extend(options)创建,其中options和new Vue(options)时传入的那个options几乎一样,但也有点区别:
      1. el不要写,为什么? —— 最终所有的组件都要经过一个vm的管理,由vm中的el决定服务哪个容器
      2. data必须写成函数,为什么? —— 避免组件被复用时,数据存在引用关系
  2. 注册组件
    1. 局部注册:靠new Vue的时候传入components选项
    2. 全局注册:靠Vue.component(‘组件名’,组件)
  3. 编写组件标签:
    • <组件名></组件名>
<body>
    <div id="root">
        <!-- 第三步:编写组件标签 -->
        <hello></hello>
        <hr>
        <character></character>
        <hr>
        <game></game>
    </div>
</body>
<script>
    Vue.config.productionTip = false
    // 第一步:创建组件
    const character = Vue.extend({
        template: `
            <div>
                <h2>角色名称:{{characterName}}</h2>
                <h2>公会名称:{{sociaty}}</h2>
                <button @click="name">点我弹出角色名</button>
            </div>
        `,
        data() {
            return {
                characterName: '佩可莉姆',
                sociaty: '美食殿堂'
            }
        },
        methods: {
            name() {
                alert(this.characterName)
            }
        },
    })
    const game = Vue.extend({
        template: `
            <div>
                <h2>游戏名称:{{gameName}}</h2>
                <h2>厂商名称:{{company}}</h2>
            </div>
        `,
        data() {
            return {
                gameName: '赛马娘',
                company: 'Cygames'
            }
        }
    })
    const hello = Vue.extend({
        template: `
            <div>
                <h2>{{hello}}</h2>
            </div>
        `,
        data() {
            return {
                hello: 'hello'
            }
        }
    })
    // 第二步:注册组件(全局注册)
    Vue.component('hello', hello)
    new Vue({
        el: '#root',
        // 第二步:注册组件(局部注册)
        components: {
            character: character,
            game: game,
        }
    })
</script>

2.2 几个注意点

  1. 关于组件名:
    • 一个单词组成:
      • 第一种写法(首字母小写):school
      • 第二种写法(首字母大写):School
    • 多个单词组成:
      • 第一种写法(kebab-case命名):my-school
      • 第二种写法(CamelCase命名):MySchool (需要Vue脚手架支持)
    • 备注:
      1. 组件名尽可能回避HTML中已有的元素名称,例如:h2、H2都不行
      2. 可以使用name配置项指定组件在开发者工具中呈现的名字
  2. 关于组件标签:
    • 第一种写法:
    • 第二种写法:
    • 备注:不用使用脚手架时,会导致后续组件不能渲染
  3. 一个简写方式:
    • const school = Vue.extend(options) 可简写为:const school = options

2.3 组件的嵌套

<body>
    <div id="root">

    </div>
</body>
<script>
    Vue.config.productionTip = false

    const game = Vue.extend({
        template: `
            <div>
                <h2>游戏名称:{{gameName}}</h2>
                <h2>厂商名称:{{company}}</h2>
            </div>
        `,
        data() {
            return {
                gameName: '赛马娘',
                company: 'Cygames'
            }
        }
    })

    const character = Vue.extend({
        template: `
            <div>
                <h2>角色名称:{{characterName}}</h2>
                <h2>公会名称:{{sociaty}}</h2>
                <hr>
                <game/>
                <hr>
            </div>
        `,
        data() {
            return {
                characterName: '佩可莉姆',
                sociaty: '美食殿堂'
            }
        },
        components: {
            game
        }
    })

    const hello = {
        template: `
            <div>
                <h2>{{msg}}</h2>
            </div>
        `,
        data() {
            return {
                msg: 'HMS Home'
            }
        }
    }

    const app = {
        template: `
            <div>
                <character/>
                <hello/>
            </div>
        `,
        components: {
            character,
            hello
        }
    }

    new Vue({
        el: '#root',
        template: `<app/>`,
        components: {
            app
        }
    })
</script>

2.4 VueComponent

关于VueComponent:

  1. school组件本质是一个名为VueComponent的构造函数,且不是程序员定义的,是Vue.extend生成的
  2. 我们只需要写或,Vue解析时会帮我们创建school组件的实例对象,即Vue帮我们执行的:new VueComponent(options)
  3. 特别注意:每次调用Vue.extend,返回的都是一个全新的VueComponent
  4. 关于this指向:
    1. 组件配置中:data函数、methods中的函数、watch中的函数、computed中的函数中的this均是【VueComponent实例对象】
    2. new Vue(options)配置中:data函数、methods中的函数、watch中的函数、computed中的函数中的this均是【Vue实例对象】
  5. VueComponent的实例对象,以后简称vc(也可称之为:组件实例对象);Vue的实例对象,以后简称vm
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值