Vue总结

Vue

1.语法格式

每个Vue应用都需要通过实例化Vue来实现,Vue实例和容器是一一对象的关系。

语法格式如下:

var vm = new Vue({
//选项
})

2.构造器需要的内容

  1. data:用于定义属性
  2. methods:用于定义函数,可以通过return来返回函数值
  3. ({}):用于输出对象和函数返回值
  4. Vue提供了一些有用的实例方法,他们都有前缀$,以便与用户定义的属性区分开来。
  5. 遇到v-bind时候属性括号中的当做js表达式

3.插值语法和指令语法

  1. 插值语法:{{}}:凡是在标签体中插入的内容都用插值语法
  2. 指令语法:v-bind:可以简写成一个冒号,一般用于解析标签,比如标签属性,标签体内容,绑定事件

4.单向数据绑定双向数据绑定

  1. 利用v-bind绑定属性之后,为单向数据绑定,当页面的输入框的值发生改变的时候,data中的值不改变
  2. 使用v-model绑定属性之后,为双向数据绑定,当表单值改变或者data值改变的时候另一边都会跟着改变
  3. 另外需要注意的是,双向绑定一般只用于表单类元素
//简写方式
<a :href="url">一点点内容</a>
        <a v-medol="title">亿点点内容</a>

el的两种写法

var data = {title:"第一个标题",url:"werewt"}
    var vm = new Vue({
        // el:"#app",
        data:data,
        methods:{
            ht:function(){
                return this.title+",就是随便写的,哈哈哈哈哈!"
            }
        }
    })
    vm.$mount("#app")

data两种写法

var vm = new Vue({
        // el:"#app",
        data:data,
        methods:{
            ht:function(){
                return this.title+",就是随便写的,哈哈哈哈哈!"
            }
        }
    })
    vm.$mount("#app")
    var vm = new Vue({
        el:"#app",
        data(){
            return{
                data
            }
        }
    })

在这个函数中this指向的Vue实例,因为是Vue实例调用了这个函数,如果是箭头函数的话,this指向就不再是Vue,二是windows

4.MVVM模型

5.关于Object.defineProperty技术

let data = {title:"第一个标题",url:"werewt"}
    Object.defineProperty(data,"method",{
        value:34,
        enumerable:true,//定义属性是否可以被枚举
        writable:true,//定义属性是否可以被修改
        configurable:true//定义属性是否可以被删除
    })
    //三种属性默认值都是false
    console.log(data);

6.数据代理

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

例子:

//数据代理
    let obj1 = {x:100}
    let obj2 = {y:200}

    Object.defineProperty(obj2,"x",{
        get(){
            return obj1.x
        },
        set(value){
            obj1.x = value
        }
    })

7.事件修饰符

1.阻止默认事件

<div id="app">
        <p @onclick.prevent="showe()">{{title}}</p>
        <p>{{url}}</p>
        <p>{{ht()}}</p>
        <a :href="url">一点点内容</a>
        <a v-medol="title">亿点点内容</a>
    </div>
    
    var vm = new Vue({
        el:"#app",
        data:{
            ti:"sdd"
        },
        methods:{
            showe(e){
                e.preventDefault()
                alert("fff");
            }
        }
    })

2.阻止事件冒泡

<div id="app"@onclick="showe()">
        <p @onclick.stop="showe()">{{title}}</p>
        <p>{{url}}</p>
        <p>{{ht()}}</p>
        <a :href="url">一点点内容</a>
        <a v-medol="title">亿点点内容</a>
    </div>

var vm = new Vue({
        el:"#app",
        data:{
            ti:"sdd"
        },
        methods:{
            showe(e){
                e.stopPropagation()
                alert("fff");
            }
        }
    })

3.事件触发一次

<div id="app">
        <p @onclick.once="showe()">{{title}}</p>
        <p>{{url}}</p>
        <p>{{ht()}}</p>
        <a :href="url">一点点内容</a>
        <a v-medol="title">亿点点内容</a>
    </div>

修饰符可以连写

<div id="app">
        <input type="text" @keyup.ctrl.y = "kf">//表示只有按下ctrl+y的时候才能触发事件
    </div>

6.Vue中常用的按键别名

  1. 回车------enter
  2. 删除------delete
  3. 退出------esc
  4. 空格------space
  5. 换行------tab(比较特殊,需要配合keydown使用)
  6. 上------up
  7. 下------down
  8. 左------left
  9. 右------right

Vue未提供别名的按键,可以使用按键原石的key值绑定,但是要注意转化为kebab-case(端横线命名法)

7.Vue的计算属性

  1. 字符拼接
<body>
    <div id="app">
        姓:<input type="text" name="" id= "" v-model = "firstname"><br>
        名:<input type="text" name="" id="" v-model = "lastname"><br>
        全名:<span>{{fullname()}}</span>
    </div>
    <div id="app1">
        姓:<input type="text" name="" id= "" v-model = "firstname"><br>
        名:<input type="text" name="" id="" v-model = "lastname"><br>
        全名:<span>{{fullname}}</span>
    </div>
</body>
<script>
    new Vue({
        el:"#app",
        data:{
            firstname:"张",
            lastname:"三"
        },
        methods:{
            fullname(){
                return this.firstname+"-"+this.lastname;
            }
        }
    })
    var vm = new Vue({
        el:"#app1",
        data:{
            firstname:"张",
            lastname:"三"
        },
        computed:{
            fullname:{
                //当有人读取fullname是,get就会被调用,返回值作为fullname的值
                //get什么时候会被调用?初次读取fullname时,或者所依赖的对象发生变化时
                get(){
                    console.log("get被调用了");
                    return this.firstname+"-"+this.lastname
                },
                //set什么时候被调用?当fullname被修改时
                set(value){
                    console.log('set',value);
                    const arr = value.split('-')
                    this.firstname = arr[0]
                    this.lastname = arr[1]
                }
            }
        }
    })
</script>
  1. 定义:要用的属性不存在,要通过已有的属性来计算得来。
  2. 原理:底层借助了object.defineproperty方法提供的getter和setter
  3. get函数什么时候执行?
    1. 初次独处时会执行一次
    2. 当依赖的数据发生改变时会再次调用
  4. 优势:与methos实现相比,内部有缓存机制(复用),效率更高,调用方便
  5. 备注:
    1. 计算属性最终会出现在vm上,直接读取使用即可
    2. 如果计算属性要被修改,那么必须写set函数去想用修改,set中要引起计算时依赖的数据发生变化。

当页面中没用使用Vue中的data属性的时候,在开发者工具中显示的数据不会改变,但是实际上数据是已经改变的。

8.监听属性

  1. 当被见识的属性发生变化时,毁掉函数自动调用,进行相关操作
  2. 简书的属性必须存在,才能进行监视
  3. 监视的两种写法:
    1. new Vue时传入watch配置
    2. 通过vm
    3. 通过vm.$watch监视

深度监视

监视多级结构中某个具体的属性的变化

const vm = new Vue({
            el:"#rood",
            data:{
                isHot:true,
                number:{
                    a:1,b:2
                }
            },
            computed:{
                info(){
                    return this.isHot?'炎热':'凉爽'
                }
            },
            methods: {
                changeWeather(){
                    this.isHot = !this.isHot
                }
            },
            //监视多级结构中某个属性的变化
            watch:{
                isHot:{
                    'number.a':{
                        handler(){
                            console.log("a的值发生了变化");
                        }
                    }
                }
            }
        })

监视多级结构中所有属性的变化

watch:{
      number:{
          deep:truehandler(){
      console.log("a的值发生了变化");
            }
         }
      }
    }

总结:

  1. Vue中的watch默认不检测对象内部的改变(一层)
  2. 配置deep:true可以检测对象内部值改变(多层)
  3. Vue自身课检测对象内部值的改变,但Vue提供的watch默认不可以、
  4. 使用watch时根据数据的具体结构,来决定是否采用深度监测

计算属性不同异步实现,如果结果是通过异步来完成的需要使用watch

定时器所管理的函数,不受Vue管理

属性:

deep:值为true或者false,确认是否深度监听,一般监听时是不能监听到对象属性值的变化的,数组的值变化可以听到

immediate:值为true或者false,确认是否以当前的初始值执行handler的函数,当值为true的时候,则会立即执行,当页面刷新时会立即执行一次handler函数

Computed和watch的区别

  1. computed能完成的功能,watch都可以完成
  2. watch能完成的功能,computed不一定能完成,比如:watch可以进行衣服操作。
  3. 被Vue所管理的函数,最好携程普通函数,这样this的指向才是vm或者组件实例对象
  4. 所有不被Vue所管理的函数(定时器的回调函数,ajax的回调函数),最好携程箭头函数,这样this的指向才是vm或者组件的实例对象76

9.绑定样式

绑定class样式的两种写法

  1. 字符串写法,适用于:样式的类名不确定,需要动态绑定

  2. 对象写法:要绑定的样式个数确定,名字也确定,但要动摇决定用不用

  3. 数组写法

绑定style样式的两种写法(样式对象中的属性不能随便写,需要是css有的属性)

  1. 对象写法
  2. 数组写法

不变的东西静态写,变化的东西使用vm管理

10.条件渲染

两种方式

  1. v-show
  2. v-if

相同点:当判断结果为true的时候都能使内容在页面上显示,为false都能使内容消失,但是v-if能直接使这个结构消失,而v-show修饰,结构还在,只是不显示而已

v-if:

有v-if,v-else-if,v-else三种,和条件语句一样,可以组成一组判断

但是当v-if和v-else后面的条件都不成立时,不管v-else后面的条件成立与否,都会执行v-else之后的语句

但是v-if和v-else-if中间不能有没有v-if的语句

template标签:当多个标签元素想要同时实现显示和消失的时候,如果给每个标签都添加v-show说着v-if的话太过于麻烦,如果手动用div包裹在div上添加v-if会强行改变文档结构,所以可以采用template标签来把这几个标签包裹起来,并且用template包裹起来的标签不会改变文档的结构,template标签在文档中不显示结构

但是template标签不能使用v-show只能搭配v-if使用

总结:

  1. 写法

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

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

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

    注意:v-if可以和v-else-if,v-else一起使用,但要求结构不能被打断

  2. v-show

    写法:v-show=“表达式”

    适用于:刷新频率较高的场景

    特点:不展示DOM元素,未被移除,仅仅是使用样式隐藏掉

  3. 备注:使用v-if时,元素可能无法获取到,而使用v-show一定可以获取到。

11.列表渲染

分以下几种情况:

  1. 遍历数组
  2. 遍历对象
  3. 遍历字符串
  4. 遍历指定次数

语法:

<div id="rood">
        <h2>遍历字符串</h2>
        <ul>
            <li v-for = "(char,index) of str">
                {{char}}-{{index}}
            </li>
        </ul>
    </div> 
    <script>
        const vm = new Vue({
            el:"#rood",
            data: {
                str:"helloworld"
            },
        })
    </script>
<h2>遍历指定次数</h2>
        <ul>
            <li v-for = "(a,b) of 4">{{a}}-{{b}}</li>
            //第一个表示从一开始,第二个是索引
        </ul>

12.key的作用与原理

给节点一个表示,相当于身份证号

原理:

  1. 初始数据在传到页面的时候首先会先生成一个虚拟DOM,在虚拟DOM中会给每个节点添加key值,但是这个key值在虚拟DOM转化为真实DOM的时候不会跟着一起显示
  2. 用户能够操作的一定是真实DOM
  3. 当用户想要在首位插入新数据的时候,再次生成的虚拟DOM的每个虚拟节点的key值会变换,新插入的key值为0,由于Vue中的对比算法,在顺序错乱的时候会出错

虚拟DOM中key的作用:

  1. key是虚拟DOM对象的表示,当状态中的数据发生变化时,Vue会根据新数据生成新的虚拟DOM,随后Vue进行新虚拟DOM的差异比较

对比规则:

  1. 旧虚拟DOM中找到了与新虚拟DOM相同的key

    1. 若虚拟DOM中内容没改变,直接使用之前的真实DOM
    2. 若虚拟DOM中的内容改变了,则生成新的真实DOM,随后替换掉页面之前的真实DOM
  2. 旧虚拟DOM中未找到与新虚拟DOM相同的key

    创建新的真实DOM,随后渲染到页面上

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

  1. 若对数据进行:你需添加,逆序删除等破坏顺序的操作

    会产生没有必要的真实DOM更新,界面效果没问题,但效率低

  2. 如果结构中还包含输入类的DOM

    会产生错误的DOM更新,从而导致界面有问题

开发中如何选择key:

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

13.列表过滤

可以使用两种方法实现:watch和computed

监视和计算

当watch和computed都能实现优先使用computed

代码:

<div id="rood">
        <input type="text" placeholder="请输入名字" v-model = 'keywords'>
        <ul>
            <li v-for = "person of filPeople">{{person.name}}-{{person.sex}}-{{person.age}}</li>
        </ul>
    </div> 
    <script>
        //用watch实现
        // new Vue({
        //     el:"#rood",
        //     data: {
        //         keywords:'',
        //         str:"helloworld",
        //         people:[
        //             {id:'001',name:"马冬梅",sex:'女',age:'19'},
        //             {id:'001',name:"周冬雨",sex:'女',age:'20'},
        //             {id:'001',name:"周杰伦",sex:'男',age:'21'},
        //             {id:'001',name:"温兆伦",sex:'男',age:'22'}
        //         ],
        //         filPeople:[]
        //     },
        //     watch:{
        //         keywords:{
                    
        //             immediate:true,
        //             handler(val){
        //                 this.filPeople = this.people.filter((p)=>{
        //                     return p.name.indexOf(val) !== -1
        //                 })
        //             }
        //         }
        //     }
        // })

        //用computed实现
        new Vue({
            el:"#rood",
            data: {
                keywords:'',
                str:"helloworld",
                people:[
                    {id:'001',name:"马冬梅",sex:'女',age:'19'},
                    {id:'001',name:"周冬雨",sex:'女',age:'20'},
                    {id:'001',name:"周杰伦",sex:'男',age:'21'},
                    {id:'001',name:"温兆伦",sex:'男',age:'22'}
                ]
            },
            computed:{
                filPeople(){
                    return this.people.filter((p)=>{
                            return p.name.indexOf(this.keywords) !== -1
                    })
                }
            }
        })
    </script>

功能升级:

在实现查询之后可以按照一定的顺序进行排序

new Vue({
            el:"#rood",
            data: {
                keywords:'',
                sortType:0,
                str:"helloworld",
                people:[
                    {id:'001',name:"马冬梅",sex:'女',age:'23'},
                    {id:'001',name:"周冬雨",sex:'女',age:'32'},
                    {id:'001',name:"周杰伦",sex:'男',age:'43'},
                    {id:'001',name:"温兆伦",sex:'男',age:'28'}
                ]
            },
            computed:{
                filPeople(){
                    const arr = this.people.filter((p)=>{
                            return p.name.indexOf(this.keywords) !== -1
                    })
                    //判断是否需要排序
                    if (this.sortType) {
                        arr.sort((a,b)=>{
                            return this.sortType ===1?b.age-a.age:a.age-b.age
                        })
                    }
                    return arr
                }
            }
        })

Vue监测数据改变的原理

Vue默认可以检测数据变化,Vue在创建好实例的时候会自动生成set和get方法,然后只要Vue监测到数据发生变化就会自动调用get或者set方法进行修改

Vue有一个特点就是,如果数据是undefined,则不会在页面上展示出来

添加属性

methods: {
                addSex(){
                    Vue.set(this.people,"sex","男")
                }
            },

Vue.set只能给data里面的属性添加值,不能直接给data添加属性和值

如果想要修改或者添加数组中的数据,需要用数组的方法

通过Vue.set()也可以实现对数组中数据进行修改

<div id="rood">
        <h1>学生信息</h1>
        <button @click = "student.age++">年龄+1</button>
        <button @click = "addSex()">点击添加性别</button>
        <button @click.once = "addFriend()">点击添加一个朋友</button>
        <button @click="updateFirstFriend()">点击修改第一个朋友的信息</button>
        <button @click.once = "addHobby()">点击添加一个爱好</button>
        <button @click = "updateFirstHobby()">修改第一个爱好为开车</button>
        <h3>姓名:{{student.name}}</h3>
        <h3>年龄:{{student.age}}</h3>
        <h3 v-if="student.sex">性别:{{student.sex}}</h3>
        <h3>爱好:</h3>
        <ul>
            <li v-for = "(h,index) of student.hobby">{{h}}</li>
        </ul>
        <h3>朋友:</h3>
        <ul>
            <li v-for = "(f,index) of student.friends">{{f.name}}-{{f.age}}</li>
        </ul>
    </div> 
    <script>
        let vm = new Vue({
            el:"#rood",
            data: {
                student:{
                    name:"zhangsan",
                    age:"23",
                    hobby:["爱好1","爱好2","爱好3"],
                    friends:[
                        {name:"lisi",age:"13"},
                        {name:"wangwu",age:"23"}
                    ]
                }
            },
            methods: {
                addSex(){
                    Vue.set(this.student,"sex","男")
                },
                addFriend(){
                    this.student.friends.unshift({name:"zhaoliu",age:"70"})
                },
                updateFirstFriend(){
                    this.student.friends[0].name = "诶嘿"
                    this.student.friends[0].age = "3"
                },
                addHobby(){
                    this.student.hobby.unshift("喝酒")
                },
                updateFirstHobby(){
                    this.student.hobby.splice(0,1,"开车")
                }
            },
        })
    </script>

总结:

  1. vue会检测data中多有层次的数据

  2. vue如何检测对象中的数据

    通过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. push()
    2. pop()
    3. shift()
    4. unshift()
    5. splice()
    6. sort()
    7. reverse()

特别注意:Vue.set(),vm.$set()不能给vm或者vm的跟数据对象添加属性!

14.收集表单数据

<div id="rood">
        账号:<input type="text" v-model = 'accont'><br>
        密码:<input type="password" v-model = 'password'><br>
        性别:
        男<input type="radio" name="sex" v-model = 'sex' value="male"><input type="radio" name="sex" v-model = 'sex' value="female"><br>
        爱好:
        <input type="checkbox" v-mosel = "hobby" value="study">学习
        <input type="checkbox" v-mosel = "hobby" value="game">打游戏
        <input type="checkbox" v-mosel = "hobby" value="wang">王者<br>
        所属学校:
        <select name="" id="">
            <option value="mo">请选择校区</option>
            <option value="beijing">北京</option>
            <option value="shanghai">上海</option>
            <option value="shenzhen">深圳</option>
        </select><br>
        其他信息:
        <textarea name="" id="" cols="30" rows="10"></textarea><br>
        <input type="checkbox">阅读并接受<a href="#">《用户协议》</a>
        <button>提交</button>
    </div> 
    <script>
        Vue.config.devtools = true;
        let vm = new Vue({
            el:"#rood",
            data:{
                accont:"",
                password:"",
                sex:"male",
                hobby:[],

            },
        })
    </script>

15.过滤器

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

语法:

  1. 注册过滤器:Vue.filter(name,callback)或者new Vue(filter:{})
  2. 使用过滤器:{{xxx | 过滤器名}}或者:x=“xxx | 过滤器名”

备注:

  1. 过滤器也可以接受额外参数,多个过滤器也可以串联
  2. 并没有改变原本数据,是产生新的数据
<div id="rood">
        <h2>显示格式化的时间</h2>
        <h3>现在是:{{fmtime}}</h3>
        <h3>时间是:{{time | timeFormat('YYYY年MM月DD日 HH:mm:ss')}}</h2>
        <h3>时间是:{{time | timeFormat('YYYY年MM月DD日')}}</h2>
    </div> 
    <script>
        Vue.config.devtools = true;
        let vm = new Vue({
            el:"#rood",
            data:{
                time:1666789411068
            },
            computed:{
                fmtime(){
                    return dayjs(this.time).format('YYYY年MM月DD日 HH:mm:ss')
                }
            },
            filters:{
                timeFormat(value,str='YYYY年MM月DD日 HH:mm:ss'){
                    return dayjs(value).format(str)
                }
            }
        })
    </script>

15.指令

  1. v-bind:单向绑定解析表达式
  2. v-model:双向数据绑定
  3. v-for:遍历数组、对象、字符串
  4. v-on:绑定事件监听,可以简写为@
  5. v-if:条件渲染(动态控制节点是否存在)
  6. v-else:条件渲染(动态控制节点是否存在)
  7. e-show:条件渲染(动态控制节点是否展示)

t-text:

  1. 想起所在的节点中渲染文本内容
  2. 与插值语法的区别:v-text会替换条节点中的内容,{{xxx}}不会

v-html:

  1. 作用:向指定节点中渲染包含html结构的内容

  2. 与差值语法的区别:

    1. v-html会替换掉节点中多有的内容,容易导致xss攻击
    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. 定义语法

    1. 局部指令:
    2. 全局指令:
    Vue.directives("big",function(){
                
            })
    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
                            element.focus()
                        }
                    }
                }
    
  2. 配置对象中常用的三个问题:

    1. bind:指令与元素成功绑定时调用
    2. inserted:指定所在元素被插入页面时调用
    3. update:指令所在模板结构重新被解析时调用
  3. 备注:

    1. 指令定义时不能加v-,但是使用的时候要加v-
    2. 指令名如果是多个单词,使用时多个单词之间要用“-”隔开,不要用驼峰命名法。

16.生命周期

  1. 定义:生命周期又称生命周期函数,生命周期回调函数,生命周期钩子
  2. 是什么:Vue在关键时刻帮我们调用一些特殊名称的函数
  3. 生命周期周期函数的名字不可更改,但函数的具体内容是程序员根据需求编写的
  4. 生命周期函数中的this指向的是vm或者组件实例对象

总共八个函数,四对

将要创建:调用beforeCrea函数

创建完毕:调用create函数

将要挂载:调用beforeMount函数

挂载完毕:调用mounted函数(重要钩子)

将要更新:调用beforeUpdate函数

更新完毕:调用update函数

将要销毁:调用beforeDestroy函数(重要钩子)

销毁完成:调用destroyed函数

常用的生命周期钩子:

  1. mounted:发送ajax请求,启动定时器,绑定自定义事件,订阅消息(初始化操作)
  2. beforDestroy:清楚定时器,解绑自定义事件,取消订阅事件(收尾工作)

关于销毁Vue实例:

  1. 销毁后借助Vue开发工具看不到任何信息
  2. 销毁后自定义事件会失效,但原生DOM事件已然有效
  3. 一般不会在beforDestroy操作数据,因为即便操作数据,也不会再触发更新流程了

17.组件

事件应用中局部功能代码和资源的集合

组件一定不能写配置项,因为最终所有组件都要被一个vm管理,由vm决定服务谁

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

一、定义组件(创建组件)

二、注册组件

三、使用组件(写组件标签)

一、定义组件

const student = Vue.extend({
            template: `
            <div>
            <h2>学生姓名:{{studentName}}</h2>
            <h2>学生年龄:{{age}}</h2>
        </div>`,
            data() {
                return {
                    studentName: "zhangsan",
                    age: 18
                }
            },
        })
        const hello = Vue.extend({
            template: `
            <h2>你好</h2>
            `,
            data() {
                return {
                    studentName: "zhangsan",
                    age: 18
                }
            },
        })

        Vue.component("hello",hello)
        let vm1 = new Vue({
            el: "#rood",
            components: {
                xuexiao: school,
                xuesheng: student
            },
            methods: {
            }
        })
  1. el不要写,最终所有组件都要经过一个vm管理,由vm中的el决定服务那个容器
  2. data必须写成函数,避免组件被复用时,数据存在引用关系

备注:使用template可以配置组件结构

二、如何注册组件

  1. 局部注册,考new Vue的时候传入components选项
  2. 全局注册,靠Vue.component(“组件名”,组件)

三、编写组件标签

直接使用组件名

几个注意点:

  1. 关于组件名

    一个单词组成:

    1. 第一种写法(首字母小写)
    2. 第二种写法(首字母大写)

    多个单词组成:

    1. 第一种写法(kebab-case命名)
    2. 第二种写法(CamelCase命名)

    备注:

    1. 组件名尽可能回避HTML中已有的元素名,大小写都不要,例如:h1,h2
    2. 可以使用name配置项指定组件在开发者工具中呈现的名字
  2. 关于组件标签:

    1. 第一种写法:
    2. 第二种写法:

    备注:不适用脚手架时,会导致后续组件不能渲染

  3. 一个简写方式:

    const school = Vue.extend(options)可以简写为const school = options

关于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()配置中:

      data函数,methods中的函数,watch中的函数,computed中的函数,他们的this均为Vue实例对象

  5. VueComponent的实例对象,以后简称vc(也可以称为:组件实例对象)

    Vue的实例对象,以后简称vm

Vue中的一个重要的内置关系:VueComponent.prototye._proto_=Vue.prototye

为什么要有这个关系,让组件实例对象vc可以访问到Vue原型上的属性、方法

18.单文件组件

render函数

  1. vue.js和vue.runtime.xxx.js的区别

    1. Vue.js是完整版的Vue,包含核心功能加模板解析器
    2. vue.runtime.xxx.js是运行版的vue,只包含核心功能,没有模板解析器
  2. 因为vue.runtime.xxx.js没有模板解析器,所以不能使用template配置型,需要使用render函数接受收到的createElement函数去指定其具体内容

ref

  1. 被用来给元素或者子组件注册引用信息(id替代)
  2. 应用在html标签上获取的是真实的DOM元素,应用在组件上是组件的实例对象
  3. 使用方式:
<h2 ref="title"></h2>
    <button @click="show">点我显示名字</button>
    <School ref="sho"></School>
export default {
    name:"App",
    components:{
        School
    },
    methods: {
      show(){
        console.log(this.$refs.title);//真实DOM元素
        console.log(this.$refs.sho);//School组件的实例对象
      }
    },
}

props配置项

功能:让组件接受外部传过来的数据

  1. 传递数据:

  2. 接受数据(三种方法)

    // props:['name','age','sex']//检点接收
      props:{
        name:String,
        age:Number,
        sex:String
      }
    props:{
        name:{
          type:String,
          required:true
        },
        age:{
          type:Number,
          default:99
        },
        sex:{
          type:String,
          required:true
        }
      }
    

    备注:props是只读的,Vue底层会检测你对props的修改,如果进行了修改就会发出警告,若是业务确实需求改参数,那么要用props的内容到data中一份,然后去data中修改数据

mixin

功能:可以把多个组件公用的配置提取成一个混入对象

使用方式:

  1. 第一步定义混合
  2. 第二如使用混合
    1. 全局使用混入:Vue.mixin(xxx)
    2. 局部混入:mixin[‘xxx’]

插件

功能:用于增强Vue

本质:包含install方法的一个对象,install的第一个参数是Vue,第二个以后的参数是插件使用者传递的数据

定义插件:

export default{
    install(Vue){
        Vue.filter("muSlice", function () {
            return values.slice(0,4)
        })
    }
}

使用插件:Vue.use()

19.组件化代码流程

  1. 实现静态组件:抽取组件,使用组件实现静态页面效果

  2. 展示动态数据:

    1. 数据类型,名称是什么
    2. 数据保存在哪个组件中
  3. 交互——从绑定事件监听开始


  1. 组件化的编码流程:

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

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

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

  2. props适用于:

    1. 父组件==》子组件通信
    2. 子组件==》父组件通信(要求父先给子一个函数)
  3. 使用v-model时要切记:v-model绑定的值不能是props传过来的值,因为props是不可以修改的

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

20.组件的自定义事件

  1. 一种组件之间通信的方式:适用于子组件===》父组件

  2. 使用场景:A是父组件,B是子组件,b想给a传数据,那么就要在A中给B绑定自定义事件(事件的回调在A中)

  3. 绑定自定义事件:

    1. 第一种方式:在父组件中:<Demo @事件名=“text”/>或者<Demo v-on:事件名=“text”/>

    2. 第二种方式:在父组件中:

      mouted(){

      this. r e f s . x x x . refs.xxx. refs.xxx.on(‘事件名’,this.text)

      }

    3. 若想让自定义事件只触发一次,需要使用once修饰

  4. 触发自定义事件:

    this.$emit(“事件名”,数据)

  5. 解绑自定义事件:

    this.$off(“事件名”)

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

  7. 注意:通过this. r e f s . x x x . refs.xxx. refs.xxx.on(‘事件名’,this.text)绑定自定义事件时,回调要么配置在methods中,要么用箭头函数,否则this指向会出问题

21.全局事件总线

  1. 任意组件之间通信

  2. 安装全局事件总线:

new Vue({
  // 下面这行代码,完成了一个功能:将App组件放入容器中
  render: h => h(App),
  beforeCreate(){
    Vue.prototype.$bus = this//安装全局事件总线  
  }
}).$mount('#app')
  1. 使用事件总线:

    1. 接受数据,A组件想接受数据,则在A组件中给$bus绑定自定义事件,事件的回调留在A组件自身
    methods:{
    demo(data){
    
    	}
    }
    mouted(){
    this.$bus.$on("xxx",demo)
    }
    
    1. 提供数据:this. b u s . bus. bus.emit(“xxx”,数据)
  2. 最好在beforDestroy钩子中,用$off解绑当前组件所用到的事件

21.路由

  1. 什么是路由?

    1. 一个路由就是一组对应关系(key-value)
    2. key为路径,value可能是function或者component
  2. 路由分类

    1. 后端路由:
      1. 理解:value是function,用于处理客户端提交的请求
      2. 工作过程:服务器接收到一个请求时,根据请求路径找到匹配的函数来处理请求,返回响应数据
    2. 前端路由:
      1. 理解:value是component,用于展示页面内容
      2. 工作过程:当浏览器的路径改变时,对应的组件就会显示

router-link:绑定路由

router-viem:路由视图

几个注意点:

  1. 路由组件通常放在pages文件中,一般组件通常放在components文件夹中
  2. 通过切换“隐藏”的路由组件,默认是被销毁的,需要的时候再去挂载
  3. 每个组件都有自己的$route,里面存储自己的路由信息
  4. 整个应用只有一个router,可以通过组件的$router属性获取

嵌套路由:

使用children进行嵌套

query传参:

query:{

id:m.id

title:m.title

}

在router-link标签中写

props传参

第一种:

props:{a:1,b:hello}

第二种:

props:true 为布尔值,若布尔值为真,就会吧该路由组件接收到的所有params参数,以props的形式穿给Detail组件

第三种写法:

props($route){

retern{a: r o u t e . q u e r y . i d , b : route.query.id,b: route.query.id,b:route.b}

}

router-linkde的replace属性

  1. 作用:公职路由器跳转时候操作浏览器历史记录的模式
  2. 浏览器的历史记录有两种写入方式:分别为push和replace,push是追加历史记录,replace是替换掉当前的记录路由跳转的时候默认为push
  3. 在router-link标签中添加replace属性即可开启

缓存路由组件:

  1. 作用:让步展示的路由组件保持挂载,不被销毁
  2. 具体编码

需保持挂载的内容

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值