学习记录3-Vue2(1)

161 阅读6分钟

之前做的笔记搬过来

Vue

介绍

  1. 组件化
  2. 声明式编码,让编码人员无需直接操作DOM,提高开发效率
  3. 使用虚拟DOM+优秀的Diff算法,尽量复用DOM节点
  4. Vue需要创建一个实例,且需要传入一个配置对象
  5. 容器代码依然符合html规范,混入了一些特殊的Vue语法;
  6. 容器中的代码被称为[Vue模板]
  7. Vue实例和容器是一一对应的
  8. 开发中只有一个Vue实例,并且会配合着组件一起使用
  9. {{XXX}}中要写JS表达式,且XXX可以自动读取到data中的所有属性
  10. 一旦data数据发生改变,页面会自动更新

区分代码和表达式

  1. JS表达式: 是特殊的JS语句会产生一个值,可以放在任何需要值的地方:

    • (1). a 变量里有值
    • (2). a+b 加法运算表达式
    • (3). demo(1) 函数调用表达式
    • (4).x === y ? 'a' : 'b'
  2. JS语句

    • .if(){} 判断
    • . for(){} 循环语句

实例(instance)和对象都是一一对应

入门

 <div id="root">
        <h1>Hello,{{name}}</h1>
        <h1>年龄为:{{age}}</h1>
    </div>
    <script>
        Vue.config.productionTip = false//阻止 vue 在启动时生成生产提示
        //创建Vue实例
        const x = new Vue({
            el: '#root',//el用于指定当前Vue实例为哪个容器服务,值通常为css选择器
            data: {//data中用于存储数据,数据供el所指定的容器去使用,值暂时写成一个对象 以后是函数
                name: '贾培东',
                age: '20'
            }
        })
​
    </script>

模板语法

  1. 插值语法

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

    写法 : {{xxx}},xxx是js表达式,可以直接读取到data中的所有值

  2. 指令语法

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

    v-bind 单向数据绑定

数据绑定

  1. 单向绑定(v-bind):数据只能从data流向页面
  2. 双向绑定(v-modle)数据也可从页面流向data

双向绑定一般应用再表单元素类上

(如: input,selsct) v-model:value

可简写为v-model因为v-model默认收集value值

el与data的写法

1.el的两种写法

  • new Vue对象时就配置el属性
  • 先创建Vue实例,后面用 v.$mount('#选择器')指定el的值 优点是更灵活,mount有挂载的意思

2.data的两种写法

  • 对象式 data{ 对象:'数据'}

  • 函数式 先写一个函数 返回你要的对象

    由Vue管理的函数 不要写成箭头函数,this就不在是Vue实例 而是 window

     data:function(){
         return{
             对象:'数据'
         }
    }
    ​
    

MVVM

  1. M (model) : 对应data中的数据 Plain JS Object

    V (view) : 模板 就是DOM

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

Data Bindings 数据绑定 在模型中把数据放到指定位置

DOM Listeners 监听DOM的改变 返回数据给模型数据

数据代理

复习

1.Object.define(定义)property(属性)方法

用于给一个对象定义属性

let number = 18
let person = {
    name:'张三',
    sex:'男'
}
​
Object.defineProperty(person,'age',{value:18,
  enumerable(可列举的):ture
  //控制属性是否可以枚举,默认值是false  
  writable:ture//控制属性是否可以被修改
  configurable:true//控制属性是否可以被删除
  get:function('有人读取age属性了'){
    ruturn number
}                                  
//当有人读取person的age属性时,get函数(getter)就会被调用,且返回值是age的值          set修改用法和get一样                          
 })
//添加了一个对象
/*这个方法传三个参数 
第一个:给哪个对象添加属性
第二个:添加属性的名字
第三个:配置项 常用的有value
和直接添加的对象不同 这个age是不能被枚举的
就是参与遍历
*/ 
console.log(person)
​

1.定义:

通过一个对象代理另一个对象中属性的操作

通过vm对象来代理data对象中属性的操作(读/写)

2.优点:

更加方便的操作data中的数据

3.代理过程:

  • 加工data
  • vm._data = data

4.基本原理:

通过Object.defineProperty()把data对象中所有属性添加到vm的_data上.

为每一个添加到vm上的属性.都指定一个getter/setter.

在getter/setter内部去操作(读/写)data中对应的属性.

事件处理

v-on:的简写是 @

  1. 使用v-on:xxx 或 @xxx 绑定事件,xxx是事件名
  2. 事件的回调需要配置在methods对象中,最终会在vm上
  3. methods中配置的函数,不要用箭头函数!否则this就不是vm了
  4. methods中配置的函数,都是被Vue所管理的函数,this的指向是vm或组件实例对象
  5. @click="demo" 和 @click="demo($event)"效果一致,但后者可以传参
 const vm = new Vue({
            el: '#root',
            data: {
                name: '贾培东',
​
            },
            methods: {
                showInfo1(event) {
                    // console.log(event.target);
                    //console.log(this);  此处的对象是vm
                    alert('加油')
                },
                showInfo2(number) {
                    console.log(number);
                    // console.log(event.target);
                    //console.log(this); // 此处的对象是vm
                    alert('加大油')
                }
​
            }
        })

事件修饰符

修饰符可以连续写

1.prevent: 阻止默认事件(常用)

2.stop:阻止事件冒泡(常用)

3.once:事件只触发一次(常用)


4.capture:使用事件的捕获模式

5.self:只有event.target是当前操作的元素时才触发事件

6.passive: 时间的默认行为立即执行

键盘事件

1.vue中常用按键别名:

  • 回车 => enter
  • 删除 => delete
  • 退出 => esc
  • 空格 => space
  • 换行 => tab 会在按下就会切走 要用 ketdown
  • 上下左右 up down left righ

键盘上每个按键都有自己的名字和编码

caps-look

 <div id="root">
        姓: <input type="text" v-model="firstName"> <br>
        名: <input type="text" v-model="lastName"> <br>
        全名: <span>{{fullName}}</span>
    </div>
​
    <script>
        const vm = new Vue({
            el: '#root',
            data: {
                firstName: '张',
                lastName: '三'
            },
            computed: {
                // 完整写法
                // fullName: {
                //     // 当有人读取fullName时,get就会被调用,且返回值就作为fullName的值
                //     // get什么时候调用? 1.初次读取fullName时. 2.所依赖的数据发生变化时.
                //     get() {
                //         console.log('get');
                //         return this.firstName + '-' + this.lastName
                //     },
                //     // 当fullName被修改时,调用set
                //     set(value) {
                //         console.log('set', value);
                //         const arr = value.split('-')
                //         this.firstName = arr[0]
                //         this.lastName = arr[1]
                //     }
                // }
                // 如果不需要修改计算属性set滴不要    简写
                fullName: function () {
                    console.log('get被调用了');
                    return this.firstName + '-' + this.lastName   //放在上面的时函数执行调用的结果
                }
            }
        })
    </script>

事件总结

修饰符可以连着写

计算属性

1.定义: 要用的属性不存在,要通过已有属性计算得来

2.原理: 底层借助了Object.defineproperty方法提供的getter和setter

3.get函数在最初读取 和 依赖的数据发生改变时调用

4.与methods实现相比,内部有缓存机制(复用),效率更高,调试方便

5.计算属性最总会出现在vm上, 如果计算属性要被修改,要写set

简写

监视属性

1.当监视属性变化时,回调函数自动调用

2.监视属性必须存在才能监视

// 监视属性的两种写法:
// 1.new Vue 时传入watch配置
// 2. 通过vm.$watch监视
​
​
const vm = new Vue({
            el: '#root',
            data: {
                isHot: true,
            },
            computed: {
                info() {
                    return this.isHot ? '炎热' : '凉爽'
                }
            },
            methods: {
                changeWeather() {
                    this.isHot = !this.isHot
                }
            },
            // watch: {
            //     info: {
            //         immediate: + true,  // 初始化时让handler调用一下
            //         // 当isHot发生改变时 调用handler(){}
            //         handler(newValue, oldVlaue){
            //             console.log('info被修改了', newValue, oldVlaue)
            //         }
            //     }
            // }
           
        })
        vm.$watch('isHot',{ 
                    immediate: true,  
                    // 初始化时让handler调用一下
                    // 当isHot发生改变时 调用handler(){}
                    handler(newValue, oldVlaue){
                    console.log('info被修改了', newValue, oldVlaue)
                     }
        })
​

深度监视

// 监视多级结构中某个属性的变化
                 'numbers.a':{
                 handler(){
                     console.log('a被改变了');
                 }
             }
              监视多级结构中所有属性的变化
             numbers:{
                 deep:true,
                 handler(){
                     console.log('numbers改变了');
                 }
             }

1.Vue中的watch默认不监测对象内部值得改变(一层)

2.配置deep:true可以监测对象内部多层得改变

监视属性简写

当配置项里只有 handler 时可以简写

 // 监视属性简写1
                 isHot(newValue, oldVlaue){  
                    console.log('info被修改了', newValue, oldVlaue)
                },
​
 // 监视属性简写2
                vm.$watch('isHot',function(newValue,oldValue){
                    console.log('isHot被修改了',newValue,oldValue);
                })

watch与computed之间的区别

computed行的wartch都行,watch行的computed不一定行 还有watch可以进行异步操作

绑定样式

<body>
    <div id="root">
        <!-- 绑定class样式--字符串写法, 适用于: 样式的类名不确定,需要动态指定 -->
        <div class="basic" :class="mood" @click="changeMood">{{name}}</div><br><!-- 绑定class样式--数组写法, 适用于: 要绑定的样式个数不确定,名字也不确定 -->
        <div class="basic" :class="classArr">{{name}}</div><br><!-- 绑定class样式--对象写法, 适用于: 要绑定的样式个数确定,名字确定,但要动态决定用不用 -->
        <div class="basic" :class="classObj">{{name}}</div><br>
​
        // :style="{fontSize: xxx}" 其中xxx是动态值
// :style="[a,b]" 其中a,b是样式对象
        <div class="basic" :style="{styleObj}">{{name}}</div>
​
    </div><script>
        const vm = new Vue({
            el:'#root',
            data:{
                name:'学习',
                mood:'normal',
                classArr:['atguigu1','atguigu2','atguigu3'],
                classObj:{
                    atguigu1:false,
                    atguigu2:false,
                },
                 styleObj:{
                     fontSize:'40px'
                 }
                },
            methods: {
                changeMood(){
                    const arr =['happy','sad','normal']
                    const index = Math.floor(Math.random()*3)
                    this.mood = arr[index]
                }
            },
        })
​

条件渲染

1.v-if 写法: 1.v-if="表达式" 2.v-else-if="表达式" 3.v-else="表达式"

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

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

2.v-show="表达式"

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

特点: 不移除 只是隐藏

列表渲染

v-for指令:

1.用于展示列表数据

2.语法: v-for="(item, index) in xxx" :key="yyy"

3.可遍历 数组 对象 字符串和指定次数

KEY的基本原理

<div id="root">
        <!-- 遍历数组 -->
        <button @click.conce='add'>添加一个老刘</button>
        <ul>
            <li v-for="(p,index) of personArr" :key="p.id">
                {{p.name}}-{{p.age}}
                <input type="text">
            </li>
        </ul>
        <script>
              new Vue({
            el:'#root',
            data:{
                personArr:[
                    {id:'001',name:'张三',age:18},
                    {id:'002',name:'李四',age:19},
                    {id:'003',name:'王五',age:20},
                ]
            },
            methods: {
                add(){
                    const p = {id:"004",name:'老刘',age:'40'}
                    this.personArr.unshift(p)
                }
            },
        })
  1. 虚拟DOM中KEY的作用: key是虚拟DOM对象的标识,当状态中的数据发生变化时,Vue会根据(新数据)生成(新的虚拟DOM),随后Vue进行 新旧虚拟DOM的差异比较

  2. 找到相同的KEY

    • 虚拟DOM中内容没变,直接使用之前的真实DOM
    • 如果改变了, 生成新的替换之前旧的
  3. 最好使用每条数据的唯一标识作为,key比如id,手机号,学号等 , 如果不存在数据的逆序添加,逆序删除等破坏顺序操作,仅用于渲染列表展示用index也无问题

列表过滤

<div id="root">
        <!-- 遍历数组 -->
        <input type="text" placeholder="请输入名字" v-model="keyWord">
​
        <ul>
            <li v-for="(p) in filPersonArr" :key="p.id">
                {{p.name}}-{{p.age}}-{{p.sex}}
            </li>
        </ul>
​
      
       
    <script>
        // new Vue({
        //     el:'#root',
        //     data:{
        //         keyWord:'',
        //         personArr:[
        //             {id:'001',name:'马冬梅',age:28,sex:'女'},
        //             {id:'002',name:'周冬雨',age:19,sex:'女'},
        //             {id:'003',name:'周杰伦',age:20,sex:'男'},
        //             {id:'004',name:'温兆伦',age:22,sex:'男'},
        //         ],
        //         filPersonArr:[]
        //     },
        //     // watch:{
        //     //     keyWord(val){
        //     //         this.filPersonArr = this.personArr.filter((p)=>{ // p形参每一个人的对象
        //     //             // fileter 筛选完后会返回一个全新的数组 不会改变原有数组
        //     //             return p.name.indexOf(val) !== -1  // return返回的是你需要的 
        //     //             //  indexOf 判断字符串里有没有指定val 返回的是字符所在的索引号
        //     //         })
​
        //     //     }
        //     watch:{
        //         keyWord:{
        //             immediate:true,
        //             handler(val){
        //                 this.filPersonArr = this.personArr.filter((p)=>{
        //                     return p.name.indexOf(val) !== -1
        //                 })
        //             }
        //         }
        //     }
            
            
        // })
        //  计算属性
        new Vue({
            el:'#root',
            data:{
                keyWord:'',
                personArr:[
                    {id:'001',name:'马冬梅',age:28,sex:'女'},
                    {id:'002',name:'周冬雨',age:19,sex:'女'},
                    {id:'003',name:'周杰伦',age:20,sex:'男'},
                    {id:'004',name:'温兆伦',age:22,sex:'男'},
                ], 
            },
            computed:{
                filPersonArr(){
                 return this.personArr.filter((p)=>{  // 第一个return是计算属性需要的
                    return p.name.indexOf(this.keyWord) !== -1  // 第二个return是filter决定的
                    })
                }
            }
        })

列表排序

<div id="root">
        <!-- 遍历数组 -->
        <input type="text" placeholder="请输入名字" v-model="keyWord">
        <button @click="sortType = 2">年龄升序</button>
        <button @click="sortType = 1">年龄降序</button>
        <button @click="sortType = 0">年龄原序</button>
        <ul>
            <li v-for="(p) of filPersonArr" :key="p.id">
                {{p.name}}-{{p.age}}-{{p.sex}}
            </li>
        </ul>
    <script>
        
        new Vue({
            el:'#root',
            data:{
                keyWord:'',
                sortType:0, // 0表示原顺序 1表示降序 2表示升序
                personArr:[
                    {id:'001',name:'马冬梅',age:28,sex:'女'},
                    {id:'002',name:'周冬雨',age:19,sex:'女'},
                    {id:'003',name:'周杰伦',age:20,sex:'男'},
                    {id:'004',name:'温兆伦',age:68,sex:'男'},
                ], 
            },
            computed:{
                filPersonArr(){
                const arr = this.personArr.filter((p)=>{  // 第一个return是计算属性需要的
                    return p.name.indexOf(this.keyWord) !== -1  // 第二个return是filter决定的
                    })
                    // 判断一下是否需要排序
                    if(this.sortType){
                        arr.sort((p1,p2)=>{
                            return this.sortType === 1 ? p2.age-p1.age : p1.age-p2.age
                        })
                    }
                    return arr
                }
            }
        })

监视数据的原理

我没怎么听懂,,,,,,

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

2.通过setter监视对象中的数据 , 且要在new Vue时就传入要监测的数据 如果需要给后添加的数据做响应式 使用一下API : Vue.set(target.propertyName/index.value)

3.通过包裹数组更新元素的方法 监视数组中的数据 本质就是: 调用原生对应的方法对数组进行更新 然后 重新解析模板更新页面

4.在Vue中修改数组中某个元素一定要用如下方法:

  • API : push() pop() ... Vue.set() Vue.$set() 不能给vm 和vm的根数据对象 添加属性
Vue.set(target,key,val) 添加可以动态代理的对象

数组操作方法

push 后面添加

pop 后面删除

shift 首个删除

splice(0,1,'替换为')

收集表单数据

// 1.如果没有配置input的value属性,呢么收集的就是checked (勾选 or 未勾选 , 是布尔值) 
// 2.配置input的value属性:
         // v-model的初始值是非数组,呢么收集的就是 checked
        // v-model的初始值是数组,那么收集的就是value组成的数组
   // v-model的三个修饰符:
    //   lazy: 失去焦点再收集数据
      //  number: 输入字符串转为有效数字
        //  trim: 输入首尾空格过滤
<div id="root">
        <form @submit.prevent="demo">
            账号: <input type="text" v-model.trim="userInfo.account"> <br>
            密码: <input type="password" v-model="userInfo.password"> <br>
            性别:
            男<input type="radio" name="sex" v-model="userInfo.sex" value="male">
            女<input type="radio" name="sex" v-model="userInfo.sex" value="female"> <br>
            爱好:
            学习<input type="checkbox" v-model="userInfo.hobby" value="study">
            吃饭<input type="checkbox" v-model="userInfo.hobby" value="game">
            还是学习 <input type="checkbox" v-model="userInfo.hobby" value="eat"> <br>
            所属校区 
            <select v-model="userInfo.city">
                <option value="">请选择校区</option>
                <option value="beijing">北京</option>
                <option value="shanghai">上海</option>
                <option value="shengzhen">深圳</option>
            </select> <br>
            其他信息:
            <textarea v-model.lazy="userInfo.other"></textarea> <br>
            <input type="checkbox" v-model="userInfo.agree"> 阅读并接受<用户协议>
            <button>提交</button>
        </form>
    </div>
​
    <script>
        new Vue({
            el:'#root',
            data :{
                  userInfo:{
                  account:'',
                  password:'',
                   sex:'',
                   hobby:[],
                   city:'beijing',
                   other:'',   
                   agree:''
               }
            },
            methods: {
                demo(){
                    console.log(JOSN.stringify(this.userInfo));
                }
            },
        })
​

过滤器

定义 :对要显示的数据进行特定格式化后再显示(适用于一些简单逻辑的处理)

语法:

1.注册过滤器 : Vue.filter(name,callback) 或 new Vue{filters:{ }}

2.使用过滤器: {{ xxx | 过滤器名}} 或 v-bind:属性 = "xxx | 过滤器名"

3.并没有改变原数据 产生新数据

内置指令

v-text : 向其所在的节点中渲染文本内容 与插值语法的区别: v-text会替换掉节点中的内容. {{xx}} 则不会

v-html : 向所在节点中渲染包含html结构的内容, v-html会替换掉节点中的内容 {{xx}}则不会 在网站上动态渲染任意HTML是非常危险的,容易导致XSS攻击, 不要用在用户提交内容上

v-click : 没有值 本质是一个特殊属性,Vue实例创建完毕并接管容器后,会删掉v-cloak属性 使用CSS配合v-cloak可以解决网速慢时页面展示出{{xxx}}的问题

v-once : v-once所在的节点在初次动态渲染后,就视为静态内容了 以后的数据的改变不会引起v-once所在结构的更新,可以用于性能优化

v-pre : 跳过其所在节点的编译过程 可以用它跳过 : 没有使用指令语法,没有使用插值语法的节点,会加快编译

自定义指令

定义语法:
局部指令:
new Vue({
    directives:{指令名:配置对象}
})
或
new Vue({
    directives:{指令名:回调函数}  // 回调函数 我们定义的但是没执行 最终执行了
})
--------------------------------
全局指令:
Vue.directive(指令名,配置对象)
或
Vue.directive(指令名,回调函数)
// 配置对象中常用的三个回调
1.bind: 指令与元素成功绑定时调用
2.inserted: 指令所在元素被插入页面时调用
3.update: 指令所在的模板结构被重新解析时调用
// 指令名定义时不加 v-,但使用时要加v-
指令名如果是多个单词,要使用kebab-case(user-name)命名方式,不要使用camelCase(userName)命名
​
<body>
    <div id="root">
        <h2>当前的n值是: <span v-text="n"></span></h2>
        <h2>放大十倍后的的n值是: <span v-big="n"></span></h2>
        <button @click="n++">点我n+1</button>
        <hr>
        <input type="text" v-fbind:value="n">
    </div>
</body>
<script>
    new Vue({
        el:'#root',
        data:{
            n:1
        },
        directives:{
            big(element,binding){
             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
                }
            }
        }  
    })
</script>

生命周期

1.又名:生命周期回调函数,生命周期函数,生命周期钩子

2.是 Vue在关键时刻帮我们调用的一些特殊名称的函数

3.名字不可更改 , 具体内容由我们编写

4.生命周期函数中的this指向是vm或组件的实例对象

常用的有两个

1.mounted: 发送ajax请求,启动定时器,绑定自定义事件,订阅消息等初始化操作

2.beforeDestory: 清除定时器,解绑自定义事件,取消订阅

生命周期挂载流程

beforeCreate

create

beforeMount

mounted

生命周期更新流程

beforeUpdate 数据是新的 页面还是旧的

updata 数据也是新的

生命周期销毁

beforeDestory 销毁之前

destroyed

vm.$destroy() 完全销毁一个实例, 清理与其他实例连接,解绑所有指令及自定义事件监听器

组件

组件就是 实现应用中 局部 功能代码和资源的集合

使用组件的步骤:

1.定义组件(创建组件)

使用Vue.extend(options)创建

2.注册组件

局部注册: new Vue的时候传入components

全局注册: Vue.component('组件名',组件)

3.使用组件(写组件标签)

<组件名>

VueComponent构造函数

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

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

3.每次调用Vue.extend时 返回的都是一个全新的VueComponent !

4.this指向:

  • 组件配置中: data函数,methods中的函数,watch中的函数,computed中的函数 this均是VueComponent实例对象
  • new Vue(options) 配置中: data函数,methods中的函数,computed中的函数, 他们的this均是Vue实例对象

Vue _rander函数

因为vue.runtime.xxx.js没有模板解析器,所以不能使用template配置项,需要使用render函数接收到的createElement函数去指定具体内容

修改脚手架默认配置

props配置

让组件接受外部传来的数据

1.传递数据:

2.接收数据

- 只接收
props:['name']
- 限制类型
props:{
  name:String
  }
限制类型,限制必要性,指定默认值
- props:{
  name:{
  type:String,
      required: true
      default:'老王'
   }
  }

mixin混入

可以把多个组件共用的配置提取成一个混入对象

// 定义
{
    data(){},
        methods:{}
}
// 混入
全局混入: Vue.mixin(xxx)
局部混入: mixins:['xxx']

插件

用于增强Vue ,本质是包含install方法的一个对象, install的第一个参数是Vue,后面的参数是插件使用者传递的数据

对象.install = function (Vue,options){
    // 添加全局过滤器
    Vue.filter()
    // 添加全局指令
    Vue.directive()
    // 配置全局混入
    Vue.mixin
    // 添加实例方法
    Vue.prototype.$myMethos = function () {..}
    Vue.prototype.$myProperty = xxx
}

TodoList案例

儿子给父亲传数据 父亲之前给儿子一个函数 然后儿子去调用

1.组件化编码流程:

  • 拆分静态组件: 组件要按照功能点拆分,命名不要与html元素冲突

  • 实现动态组件: 考虑好数据的存放位置,数据是一个组件在用,还是一些组件在用

    • 一个组件用就放在组件自身即可
    • 一些组件放在共同的父组件上(状态提升)
  • 实现交互: 从绑定事件开始

2.props适用于

  • 父组件 ===> 子组件 通信
  • 子组件 ===> 父组件 通信 (要求父先给子一个函数)

3.使用v-model时要切记 : v-model绑定的值不能是props传过来的值,因为props是不可以修改的

4.props传过来的若是对象类型的值,修改对象中的属性时Vue不会报错,但是也不推荐

浏览器的本地存储

sessionStorage

localStorage

xxxxxStrage.setItem('key','value')

把键值对添加到存储中

xxxxxStrage.getItem('person')

接收一个键名作为参数,返回键名对应的值

xxxxxStrage.removeItem('key')

接受一个键名作为参数,并删除

SessionStorage存储会随着浏览器窗口关闭而消失

组件的自定义事件

  1. 组件间通信的方式,适用于 子组件 ===> 父组件

  2. 子组件想给父组件传数据,就要在父组件中给子组件绑定自定义事件(事件的回调在父组件中)

  3. 绑定自定义事件:

    • 第一种方式,在父组件中:<Demo @thing="test">
    • 第二种方式,在父组件中给子组件用ref打一个标识,之后父组件挂载之后
    <Demo ref="demo"/>
        ...
    mounted(){
        this,$refs.xxx.$on('thing',this.test)
    }
    

    如果想让自定义事件只能触发一次,可以使用once修饰符,或$once方法

  4. 触发自定义事件: this.$emit('thing',数据)

  5. 解绑自定义事件this,$off('thing')

  6. 组件上也可以绑定原生DOM事件,需要使用native修饰符

  7. 注意: 通过this.refs.xxx.refs.xxx.on('thing',回调)绑定自定义事件时,回调要么配置在methods中,要么用箭头函数,否则this指向会出问题

全局事件总线

适用于任意组件间通信

1.安装

new Vue ({
    ......
    beforeCreate(){
    Vue.prototype.$bus = this // 安装全局事件总线,$bus就是当前应用的vm
}
})

2.使用

  • 接收数据: A组件想要接收数据,就在A组件中给$bus绑定自定义事件,事件的回调留在A组件自身

    methods(){
        demo(data){......}
    }
        .....
    mounted() {
        this.$bus.$on('xxxxx',this,demo)
    }
    
  • 提供数据: this.bus.bus.on('xxxx',数据)

3.最好在beforeDestroy钩子中,用$off去解绑当前组件所用到的事件

消息订阅与发布

需要数据的组件订阅消息,提供数据的人发布消息

nextTick

在下一次DOM更新结束后执行其指定的回调

Vue封装的过度与动画

1.作用: 在插入,更新或移除DOM元素时,在合适的时候给元素添加样式类名.

2.写法:

  • 准备好样式;
  • v-enter: 进入的样式
  • v-enter-active: 进入过程中
  • v-enter-to: 进入的终点
  • v-leave-active; 退出过程中

进入的起点就是离开的终点,进入的终点就是离开的起点

3.使用包裹要过度的元素,并配置name属性

修改Vue打开端口

node_modules 下的 @Vue 中cli-service 下的commands 的 serve.js

插槽

作用: 让父组件可以向子组件指定位置插入html结构,也是一种组件间通信的方式

1.默认插槽: 内容写在App中组件中用标签占个位

2.具名插槽: 给加name属性 给需要加入的标签加slot属性值时前面的name

3.作用域插槽

数据在组件自身,但根据数据生成的结构需要组件的使用者来决定

子组件里留插槽,放数据

Vuex

专门在Vue中实现集中式状态(数据)管理的一个Vue插件,对Vue应用中多个组件的共享状态进行集中式的管理(读/写),也是一种组件间通信的方式,且适用于任意组件间通信

Vue router

\