【补】vue01

1、vue的实例和容器是一一对应的

2、双向数据绑定(v-model)只能应用在表单类(输入类)元素上,都有value值

3、el的两种写法

//第一种
new Vue({
    el:'#root',
    data:{xx:'xxx'}
})


//第二种
const v = new Vue({
    el:'#root',
    data:{xx:'xxx'}
})
v.$mount('root')

4、data的函数式写法中的this为vue实例对象

5、mvvm模型

  • M:模型(Model) :data中的数据

  • V:视图(View) :模板代码

  • VM:视图模型(ViewModel):Vue实例

    观察发现:

  • 1.data中所有的属性,最后都出现在了vm身上。

  • 2.vm身上所有的属性 及 Vue原型上所有属性,在Vue模板中都可以直接使用。

6、数据代理

defineProperty

:通过defineProperty添加的属性默认不可以被枚举、不可以被修改、不可以被删除

Object.defineProperty(要添加属性的对象,'属性的名称'{
    value:'属性值'enumerable:true,//控制属性是否可以枚举,默认值为false
    writable:true,//控制属性是否可以被修改
    configurabel:true,//控制属性是否可以被修改
)}

eg:要给添加的属性值赋值为变量

get:当有人读取Person的age值时,才会获取到,比如浏览器中的浅颜色属性,值为…,点开才能看到

set:当有人修改person的age属性时,set函数会被调用,会收到修改的具体值

let number = 18;
Object.defineProperty(Person,'get'{
    get(){
        return number
    },
    set(value){
        console.log(value)
        number = value;//由于age使用的是number的值,所以要修改number的值
    }
)}

什么是数据代理

let obj = {x:100}
            let obj2 = {y:200}

            Object.defineProperty(obj2,'x',{
                get(){
                    return obj.x
                },
                set(value){
                    obj.x = value
                }
            })

通过obj2可以获取到obj中的x的值,并且可以修改obj中x的值

vue中的数据代理

7、计算属性

计算属性使用的是get和set方法,现在所使用的都是计算属性的简写,将get内的方法写出,如果需要直接修改计算属性的值,则需要给计算属性写一个set方法

计算属性的get调用时间:(1)初次读取计算属性时(2)计算属性所依赖的数据发生变化时

computed:{
    aa:{
        set(value){
            const arr = value.spilit('用什么分割计算属性所依赖的数据')
            //修改计算属性所依赖的数据
        },
        get(){
            console.log('我是get方法')
        },
    }
}
//简写
computed:{
    aaa(){
        console.log('我是get方法')
    }
}

计算属性中有缓存

区分计算属性和data中的数据:计算属性不存在于vm._data

8、监听

watch:{
    aaa:{
        imediate:true,//初始化时调用handler
        handler(newValue,oldValue){}
        }

}

深度监听

dat(){
    return {
        numbers:{
            a:1,
            b:2
        }
    }
},
watch:{
    //监视多级结构中某个属性的变化
    "numbers.a":{
        handler(){

        }
    },
    //监视多级结构中任何一个属性的变化
    numbers:{
        deep:true,
        handle(){}
    }
}


//简写
watch:{
    aaa(oldValue,newValu){}
}

computed和watch的区别

  • computed能完成的watch都能实现

  • watch可以进行异步操作,但是computed不可以

9、vue中的key

  • vue中使用key对比的是虚拟dom

  • 如果循环中没有写key,默认吧index作为key

  • 如果对数据进行破坏顺序的操作,不要使用index作为key,使用id作为key

vue中的key有什么作用

  • 虚拟DOM中key的作用:
    key是虚拟DOM对象的标识,当数据发生变化时,Vue会根据【新数据】生成【新的虚拟DOM】, 随后Vue进行【新虚拟DOM】与【旧虚拟DOM】的差异比较,比较规则如下:

  • 对比规则:
    (1).旧虚拟DOM中找到了与新虚拟DOM相同的key:
    ①.若虚拟DOM中内容没变, 直接使用之前的真实DOM!
    ②.若虚拟DOM中内容变了, 则生成新的真实DOM,随后替换掉页面中之前的真实DOM。
    (2).旧虚拟DOM中未找到与新虚拟DOM相同的key
    创建新的真实DOM,随后渲染到到页面。

  • 用index作为key可能会引发的问题:

    若对数据进行:逆序添加、逆序删除等破坏顺序操作:
    会产生没有必要的真实DOM更新 ==> 界面效果没问题, 但效率低。
    如果结构中还包含输入类的DOM:
    会产生错误DOM更新 ==> 界面有问题。

  • 开发中如何选择key?:
    1.最好使用每条数据的唯一标识作为key, 比如id、手机号、身份证号、学号等唯一值。
    2.如果不存在对数据的逆序添加、逆序删除等破坏顺序操作,仅用于渲染列表用于展示, 使用index作为key是没有问题的。

10、列表使用indexOf('')=0不等于-1

11、操作数据

方法是否改变源数据传入数据返回代码返回值
filter过滤条件返回过滤后的数据
sort比较的两个值(a,b)b-a:升序 a-b:降序返回排序后的数据

12、vue是如何监听对象数据变化的

观察者,创建一个Observer,监视的实例对象,用于监视实例的对象

  • 汇总对象中所有的属性形成一个数组

  • 遍历

//创建一个监视的实例对象,用于监视data中属性的变化
            const obs = new Observer(data)        
            console.log(obs)    

            //准备一个vm实例对象
            let vm = {}
            vm._data = data = obs

            function Observer(obj){
                //汇总对象中所有的属性形成一个数组
                const keys = Object.keys(obj)
                //遍历
                keys.forEach((k)=>{
                    Object.defineProperty(this,k,{
                        get(){
                            return obj[k]
                        },
                        set(val){
                            console.log(`${k}被改了,我要去解析模板,生成虚拟DOM.....我要开始忙了`)
                            obj[k] = val
                        }
                    })
                })
            }

13、Vue.set()

原始创建的对象添加一个属性时,vm._data中没有get和set方法,在vm身上也没有此属性,因为vm是代理的data中的数据,vm和vm._data不允许作为对象目标

如果想要给对象添加属性且赋值时,使用

Vue.set(vm._data.对象名称,属性名,属性值)

vm.$set和Vue.set的实现一致

14、vue监听数组变化

vue将侦听数组的变更方法(7个)进行包裹,所以会触发视图更新,或者使用set方法

比如更换第一个,可以使用splice(0,1,新的值),或者是使用set(数组,0,新的值)`

直接取到数组的索引去修改值是不会触发视图的变化的,但是数组对象可以

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. s e t ( ) 特别注意: ‘ V u e . s e t ( ) ‘ 和 ‘ v m . set() 特别注意:`Vue.set() `和 `vm. set()特别注意:Vue.set()vm.set()` 不能给vm 或 vm的根数据对象 添加属性!!!

15、vue收集表单数据

v-model双向数据绑定,默认收集的数据为value的值,但是单选和多选一般没有value,所以要给他设置一个value值,v-model绑定初始值能够影响v-model收集回来的数据,所以多选框选中初始值设置为一个空数组

收集表单数据:
        若:<input type="text"/>,则v-model收集的是value值,用户输入的就是value值。
        若:<input type="radio"/>,则v-model收集的是value值,且要给标签配置value值。
        若:<input type="checkbox"/>
                1.没有配置input的value属性,那么收集的就是checked(勾选 or 未勾选,是布尔值)
                2.配置input的value属性:
                        (1)v-model的初始值是非数组,那么收集的就是checked(勾选 or 未勾选,是布尔值)
                        (2)v-model的初始值是数组,那么收集的的就是value组成的数组

v-model的修饰符:

  • v-model.number收集数据为一个数据类型,一般和type='number一起使用

  • 输入框是实时收集,如果加上v-model.lazy,则在失去焦点的一瞬间去收集

  • v-model.trim去掉前后的空格

16、过滤器

日期处理:

  • momentjs

  • dayjs

使用管道符,可以传参,第一个一直是数据本身

17、指令

内置指令

v-bind    : 单向绑定解析表达式, 可简写为 :xxx
v-model    : 双向数据绑定
v-for      : 遍历数组/对象/字符串
v-on       : 绑定事件监听, 可简写为@
v-if     : 条件渲染(动态控制节点是否存存在)
v-else     : 条件渲染(动态控制节点是否存存在)
v-show     : 条件渲染 (动态控制节点是否展示)
v-text  :
    1.作用:向其所在的节点中渲染文本内容。
    2.与插值语法的区别:v-text会替换掉节点中的内容,{{xx}}则不会。
v-html:
        1.作用:向指定节点中渲染包含html结构的内容。
        2.与插值语法的区别:
                (1).v-html会替换掉节点中所有的内容,{{xx}}则不会。
                (2).v-html可以识别html结构。
        3.严重注意:v-html有安全性问题!!!!
                (1).在网站上动态渲染任意HTML是非常危险的,容易导致XSS攻击。
                (2).一定要在可信的内容上使用v-html,永不要用在用户提交的内容上!
v-cloak:
        1.本质是一个特殊属性,Vue实例创建完毕并接管容器后,会删掉v-cloak属性。
        2.使用css配合v-cloak可以解决网速慢时页面展示出{{xxx}}的问题。
v-once指令:
        1.v-once所在节点在初次动态渲染后,就视为静态内容了。
        2.以后数据的改变不会引起v-once所在结构的更新,可以用于优化性能。
v-pre指令:
        1.跳过其所在节点的编译过程。
        2.可利用它跳过:没有使用指令语法、没有使用插值语法的节点,会加快编译。

自定义指令

<!-- 
                需求1:定义一个v-big指令,和v-text功能类似,但会把绑定的数值放大10倍。
                需求2:定义一个v-fbind指令,和v-bind功能类似,但可以让其所绑定的input元素默认获取焦点。
                自定义指令总结:
                        一、定义语法:
                                    (1).局部指令:
                                                new Vue({                                                            new Vue({
                                                    directives:{指令名:配置对象}   或           directives{指令名:回调函数}
                                                })                                                                         })
                                    (2).全局指令:
                                                    Vue.directive(指令名,配置对象) 或   Vue.directive(指令名,回调函数)

                        二、配置对象中常用的3个回调:
                                    (1).bind:指令与元素成功绑定时调用。
                                    (2).inserted:指令所在元素被插入页面时调用。
                                    (3).update:指令所在模板结构被重新解析时调用。

                        三、备注:
                                    1.指令定义时不加v-,但使用时要加v-2.指令名如果是多个单词,要使用kebab-case命名方式,不要用camelCase命名。
        -->
        <!-- 准备好一个容器-->
        <div id="root">
            <h2>{{name}}</h2>
            <h2>当前的n值是:<span v-text="n"></span> </h2>
            <!-- <h2>放大10倍后的n值是:<span v-big-number="n"></span> </h2> -->
            <h2>放大10倍后的n值是:<span v-big="n"></span> </h2>
            <button @click="n++">点我n+1</button>
            <hr/>
            <input type="text" v-fbind:value="n">
        </div>
    </body>

    <script type="text/javascript">
        Vue.config.productionTip = false

        //定义全局指令
        /* Vue.directive('fbind',{
            //指令与元素成功绑定时(一上来)
            bind(element,binding){
                element.value = binding.value
            },
            //指令所在元素被插入页面时
            inserted(element,binding){
                element.focus()
            },
            //指令所在的模板被重新解析时
            update(element,binding){
                element.value = binding.value
            }
        }) */

        new Vue({
            el:'#root',
            data:{
                name:'尚硅谷',
                n:1
            },
            directives:{
                //big函数何时会被调用?1.指令与元素成功绑定时(一上来)。2.指令所在的模板被重新解析时。
                /* 'big-number'(element,binding){
                    // console.log('big')
                    element.innerText = binding.value * 10
                }, */
                big(element,binding){
                    console.log('big',this) //注意此处的this是window
                    // console.log('big')
                    element.innerText = binding.value * 10
                },
                fbind:{
                    //指令与元素成功绑定时(一上来)
                    bind(element,binding){
                        element.value = binding.value
                    },
                    //指令所在元素被插入页面时
                    inserted(element,binding){
                        element.focus()
                    },
                    //指令所在的模板被重新解析时
                    update(element,binding){
                        element.value = binding.value
                    }
                }
            }
        })

生命周期

  • 初始化:生命周期、事件,但数据代理还未开始

  • beforeCreated:此时无法通过vm访问到data中的数据和methods中的方法

  • 初始化:数据监测、数据代理

  • created:可以通过vm访问到data中的数据和methods中的方法

  • vue开始解析模板,生成虚拟dom(内存中),页面害不能显示解析好的内容

  • befrewMount:页面呈现的是未经vue编译的dom结构,所有对dom的操做,最终都不生效

  • 将内存中的虚拟dom转为真实dom插入页面

  • mounted

    • 页面中呈现的是经过vue编译的dom

    • 对dom的操做均有效(尽可能避免),初始化过程结束。一般再次进行:开启定时器、发送网络请求、订阅消息、绑定自定义事件等初始化操做

  • beforeUpdate: 此时data中的数据已经更新,但页面是旧的

  • 生成新的虚拟dom,与旧的进行比较,最终完成页面的更新

  • updated:数据是新的,页面也是新的,页面和数据保持同步

  • beforeDestroy: 对数据的修改不会再触发视图的更新,清除定时器、解绑自定义事件、取消订阅消息等【收尾工作】

  • destroryed:(react中没有此钩子)完全销毁一个实例,清理他与其他实例的链接,解绑它的全部指令及自定义事件监听器

组件

组件初始

vue.extend:vue创建组件

组件定义时不能写el,因为组件最后服务于一个vm

data为什么是函数:因为如果data是对象,a和b中的data都有c,修改data中的c时,a和b的c的都会改变,vm的组件可以是对象,但是组件的必须是函数

  • 创建组件
Vue.extend({
    data:{
        return {}
    },
    template:`<div>school组件</div>`//组件
})
  • 注册组件(局部注册)

    new Vue({
        el:'#root',
        compontents:{
            school:school
        }
    })
    
  • 使用 编写组件标签

    <template>
        <div>
            <school></school>
        </div>
    </template>
    

注册全局组件

Vue.components('school',school)

VueComponents

  • 组件本质是一个名为VueComponent的构造函数,且不是程序员定义的,是Vue.extend生成的。

  • 我们只需要写<school/><school></school>,Vue解析时会帮我们创建school组件的实例对象, 即Vue帮我们执行的:new VueComponent(options)

  • 特别注意:每次调用Vue.extend,返回的都是一个全新的VueComponen

  • (1).组件配置中: data函数、methods中的函数、watch中的函数、computed中的函数 它们的this均是【VueComponent实例对象】。

    (2).new Vue(options)配置中: data函数、methods中的函数、watch中的函数、computed中的函数 它们的this均是【Vue实例对象】。

  • VueComponent的实例对象,以后简称vc(也可称之为:组件实例对象)。
    Vue的实例对象,以后简称vm。

一个重要的内置关系

函数身上有显示原型,实例对象身上有隐式原型,指向同一个

实例的隐式原型永远指向自己缔造者的原型对象

VueComponent.prototype.__proto__ = Vue.prototype

由于VueConponent的原型对象也是一个普通的object对象,所以他的隐式原型指向object的原型对象,但是vueVueComponent的隐式原型指向了vue的原性对象

原因:数据沿着隐式原型链去查找数据,可以让组件的实例对象(vc)也可以访问到vue原型上面的属性、方法
在这里插入图片描述

单文件组件

App.vue管理所有的组件,注册在main.js里面,index.html主页面中放div

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值