vue核心语法2

一、计算属性

1、案例引入

实现如下效果 当姓和名变化时 全名跟着变化

2、使用插值语法实现和methods实现

<body>
<div id="root">
    姓<input v-model="firstName" type="text">
    名<input v-model="lastName" type="text">
    <!--使用插值语法实现-->
    全名<span>{{firstName}}{{lastName}}</span>
    <!--使用methods实现 vue当数据发生变化 模板重新渲染加载 数据也会重新更新-->
    全名<span>{{fullName()}}</span>
</div>
<script>
    const vm = new Vue({
        el:"#root",
        data:{
            firstName:"",
            lastName:""
        },
        methods:{
            fullName(){
              return this.firstName+this.lastName
            }
        }
    })
</script>
</body>

上面案例插入语法缺点

vue官网风格指南强烈建议插值语法保持简介

3、计算属性定义

要用的属性不存在 要通过已有属性计算得出

4、原理

通过object.defineproperty方法提供的getter和setter

5、优点

和methods对象实现相比 有缓存机制 效率更高 调试方便

备注:计算属性最终出现在vm上 直接读取即可

<body>
<div id="root">
    姓<input v-model="firstName" type="text">
    名<input v-model="lastName" type="text">
    全名<span>{{fullName}}</span>
</div>
<script>
    const vm = new Vue({
        el:"#root",
        data:{
            firstName:"",
            lastName:""
        },
        methods:{
        },
        /*1、fullName属性通过函数计算出的新属性 fullName也在vm对象上
        * 2、功能:当有人读取fullName时 get且返回值作为fullName值
        * 3、会做缓存处理,初次读取和所依赖的数据发生变化时get调用*/
        computed:{
            fullName:{
                get(){
                    return this.firstName+this.lastName
                },
                /*当新属性被修改时候调用*/
                set(){

                }
            }
        }
    })
</script>
</body>

6、计算属性简写方式

确定计算属性只读不写时候才能简写

<body>
<div id="root">
    姓<input v-model="firstName" type="text">
    名<input v-model="lastName" type="text">
    全名<span>{{fullName}}</span>
</div>
<script>
    const vm = new Vue({
        el:"#root",
        data:{
            firstName:"",
            lastName:""
        },
        methods:{
        },
        computed:{
            //简写方式 看着是个函数 实际是个属性
            fullName(){
                return this.firstName+this.lastName;
            }
        }
    })
</script>
</body>

二、监视属性

1、定义

监视某一个属性的变化,只有当监视的属性存在才能监视

2、两种写法

<body>
<div id="root">
    <span>天气{{info}}</span>
    <button @click="changeWeather">切换</button>
</div>
<script>
    const vm = new Vue({
        el:"#root",
        data:{
            isHot:true
        },
        methods:{
            changeWeather(){
                this.isHot = !this.isHot
            }
        },
        computed:{
            info(){
                return this.isHot ? '炎热':'凉爽'
            }
        },
        /*第一种写法:创建实列就已经知道要监视哪个属性就用这种方法*/
        watch:{
            //不仅可以监听data中属性 也可以监视计算属性info
            isHot:{
                immediate:true,//初始化就调用一下handler
                //当ishot发生变化时调用handler
                handler(newValue,oldValue){
                    console.log(newValue,oldValue);
                }
            }
        },
    });
    /*第二种写法:当用户行为发生变化时候才监视用这种*/
    vm.$watch('isHot',{
        immediate:true,
        handler(newValue,oldValue){
            console.log(newValue,oldValue);
        }
    })
</script>
</body>

3、深度监视

vue中的watch默认不监测对象内部值得变化(一层)

配置deep:true可以监测对象内部值得变化(多层)

<body>
<div id="root">
    <span>{{num.a}}</span>
    <button @click="num.a++">切换</button>
</div>
<script>
    const vm = new Vue({
        el:"#root",
        data:{
            num:{
                a:1,
                b:2
            }
        },
        methods:{
        },
        watch:{
            /*监视多级结构中某个属性变化*/
           'num.a':{
               handler(newValue,oldValue){
                   console.log(newValue,oldValue);
               }
           },
           /*监视多级中所有属性变化*/
            num: {
                deep:true,
                handler(newValue,oldValue){
                    console.log(newValue,oldValue);
                }
            }
        },
    });
</script>
</body>

备注:

vue自身是可以监测对象内部值得改变 但vue提供得watch默认不可以

使用watch需要根据数据结构得变化决定是否采用监视

4、简写

<body>
<div id="root">
    <span>{{num.a}}</span>
    <button @click="num.a++">切换</button>
</div>
<script>
    const vm = new Vue({
        el:"#root",
        data:{
            isHot:true
        },
        methods:{
        },
        watch:{
            /*当不用配置deep和immediate时监视可以简写如下*/
           isHot(newValue,oldValue){
               console.log(newValue,oldValue)
           }
        }
    });
    /*当不用配置deep和immediate时监视可以简写如下*/
    vm.$watch('isHot',function (newValue,oldValue) {
        console.log(newValue,oldValue)
    })
</script>
</body>

5、计算属性和监视属性对比

1、computed能完成的功能 watch都可以完成

2、watch能完成的功能 computed不一定能完成 例如watch可以进行异步操作

3、所有被vue管理的函数最好写成普通函数,别用箭头函数,这样this的指向才是vm

4、所有不被vue管理的函数(定时器函数、ajax回调函数、promise回调函数)最好携程箭头函数 这样this指向才是vm或者组件实列对象

三、样式绑定

1、通过class绑定样式(三种方式)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="js/vue.js"></script>
    <style>
        .basic{
            width: 200px;
            height: 200px;
        }
        .active1{
            background-color: rosybrown;
        }
        .active2{
            border-radius: 20px;
        }
        .active3{
            border-color: green;
            background-color: red;
        }
    </style>
</head>
<body>
<div id="root">
    <!--字符串写法:适用于样式的类名不确定需要动态指定-->
    <div class="basic" :class="one"></div>
    <!--数组写法:适用于要绑定的样式个数不确定 名字也不确定-->
    <div class="basic" :class="two"></div>
    <!--对象写法:适用于要绑定的样式个数确定 名字也确定 但要动态决定用不用-->
    <div class="basic" :class="three"></div>
</div>
<script>
    const vm = new Vue({
        el:"#root",
        data:{
            one:'active1',
            two:['active1','active2'],
            three:{
                active2:true,
                active3:true
            }
        },
    });
</script>
</body>
</html>

2、通过style绑定样式(2种)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="js/vue.js"></script>
    <style>
        .basic{
            width: 200px;
            height: 200px;
        }
        .active1{
            background-color: rosybrown;
        }
        .active2{
            border-radius: 20px;
        }
        .active3{
            border-color: green;
            background-color: red;
        }
    </style>
</head>
<body>
<div id="root">
    <!--对象写法-->
    <div class="basic" :style="styleObj">222</div>
    <!--数组写法-->
    <div class="basic" :style="styleArr">333</div>
</div>
<script>
    const vm = new Vue({
        el:"#root",
        data:{
            one:'active1',
            two:['active1','active2'],
            styleObj:{
                borderRadius:"20px",
                backgroundColor:"red"
            },
            styleArr:[
                {
                    borderRadius:"20px",
                    backgroundColor:"red"
                },
                {
                    fontSize:"20px",
                    padding:"20px"
                }
            ]
        },
    });
</script>
</body>
</html>

四、条件渲染和列表渲染

1、条件渲染

1.1、v-show语法

1、底层使用的是display实现,仅仅时样式的移除

<body>
<div id="root">
    <!--直接写表达式-->
   <div v-show="true">{{name}}</div>
    <!--通过属性控制-->
    <div v-show="flag">{{name}}</div>
</div>
<script>
    const vm = new Vue({
        el:"#root",
        data:{
            name:'hello',
            flag:true
        },
    });
</script>
</body>

1.2、v-if语法

1、v-if条件渲染时不展示dom的元素直接移除,而不是使用display隐藏

2、v-if可以和v-else-if、v-else一起使用 但要求结构不能被打断

3、template只能配置v-if使用(使用template不会破坏原来的元素结构)

html结构直接删掉

<body>
<div id="root">
    <!--直接写表达式-->
   <div v-show="true">{{name}}</div>
    <!--通过属性控制-->
    <div v-show="flag">{{name}}</div>
</div>
<script>
    const vm = new Vue({
        el:"#root",
        data:{
            name:'hello',
            flag:true
        },
    });
</script>
</body>

1.3、比较

1. 如果需要频繁切换 v-show 较好 因为节点在只是隐藏了

2. 当条件不成立时, v-if 的所有子节点不会解析

2、列表渲染

2.1、v-for

v-for指令用于展示列表数据,语法:v-for="(item,index) in xxx" :key="yyy"

可以遍历数组、对象、字符串、指定次数

<body>
<div id="root">
    <div>
        <!--遍历数组-->
        <h2 v-for="(item,index) in arr">{{item}}--{{item.id}}--{{item.name}}--{{index}}</h2>
        <!--遍历对象-->
        <h2 v-for="(value,key) in obj" >{{key}}--{{value}}</h2>
        <!--遍历字符串-->
        <h2 v-for="(item,index) in str" >{{item}}--{{index}}</h2>
        <!--遍历指定次数-->
        <h2 v-for="(number,index) of 5" >{{number}}--{{index}}</h2>
    </div>
</div>
<script>
    const vm = new Vue({
        el:"#root",
        data:{
            arr:[
                {
                    id:1,
                    name:'一'
                },
                {
                    id:2,
                    name:'二'
                },
                {
                    id:3,
                    name:'三'
                }
            ],
            obj:{
                id:1,
                age:12,
                name:'张三',
                sex:'男'
            },
            str:'hello',
        },
    });
</script>
</body>

2.2、key的作用和原理

3、列表过滤

案例截图,输入关键字模糊展示

3.1、使用监视属性实现

<body>
<div id="root">
    <input v-model="keyWord">
    <ul>
        <li v-for="(item,index) in filPersons" :key="item.id">{{item.id}}-年龄{{item.age}}-{{item.name}}</li>
    </ul>
</div>
<script>
    const vm = new Vue({
        el:"#root",
        data:{
            keyWord:'',
            persons:[
                  {id:1, name:'张三',age:10},
                {id:2, name:'李四',age:20},
                {id:3, name:'王五',age:30}
            ],
            filPersons:[]
        },
        watch:{
            keyWord:{
                immediate:true,
                handler(val){
                    this.filPersons = this.persons.filter((p)=>{
                        /*indexOf(str)没有找到返回-1 找到返回下表位置,如果var是''即空字符串,
                        则返回0即每个字符串都包含空字符串在开头*/
                        return p.name.indexOf(val)!== -1;
                    })
                }
            }
        }
    });
</script>
</body>

3.2、使用计算属性实现

<body>
<div id="root">
    <input v-model="keyWord">
    <ul>
        <li v-for="(item,index) in filPersons" :key="item.id">{{item.id}}-年龄{{item.age}}-{{item.name}}</li>
    </ul>
</div>
<script>
    const vm = new Vue({
        el:"#root",
        data:{
            keyWord:'',
            persons:[
                 {id:1, name:'张三',age:10},
                {id:2, name:'李四',age:20},
                {id:3, name:'王五',age:30}
            ],
        },
        computed:{
            filPersons(){
                return this.persons.filter((p)=>{
                    return p.name.indexOf(this.keyWord) !== -1
                })
            }
        }
    });
</script>
</body>

当计算属性和监视都能实现的时候优先选择计算属性

4、列表排序

<body>
<div id="root">
    <input v-model="keyWord" type="text" placeholder="输入关键字查询">
    <button @click="sortType = 2">年龄升序</button>
    <button @click="sortType = 1">年龄降序</button>
    <button @click="sortType = 0">原顺序</button>
    <ul>
        <li v-for="(item,index) in filPersons" :key="item.id">{{item.id}}-年龄{{item.age}}-{{item.name}}</li>
    </ul>
</div>
<script>
    const vm = new Vue({
        el:"#root",
        data:{
            keyWord:'',
            sortType:0,
            persons:[
                {id:1, name:'张三',age:10},
                {id:2, name:'李四',age:20},
                {id:3, name:'张二三',age:90},
                {id:4, name:'王五',age:30}
            ],
        },
        computed:{
            filPersons(){
                const arr = this.persons.filter((p)=>{
                    return p.name.indexOf(this.keyWord) !== -1
                });
                //只要sort不是0 都是true
                if(this.sortType){
                    //sort会改变原数组 filter不会改变原数组
                    arr.sort((pre,next)=>{
                        //sort降序用后一个元素减去前一个元素即可 升序用前一个元素减去后一个元素
                        return this.sortType === 1 ? next.age-pre.age : pre.age-next.age
                    });
                }
                return arr;
            }
        }
    });
</script>
</body>

五、内置指令

1、v-text

向其所在的节点中渲染文档内容;会替换掉其他节点中的内容,但是插值语法表达式不会

2、v-html

向指定节点渲染包含html结构的内容

v-html有安全问题容易导致xss攻击,一定要在可信的内容使用v-html 不要在用户提交的内容

3、v-if

如果为 true, 当前标签才会输出到页面

4、v-else

如果为 false, 当前标签才会输出到页面

5、v-show

通过控制 display 样式来控制显示/隐藏

6、v-for

遍历数组/对象

7、v-on

绑定事件监听, 一般简写为@

8、v-bind

绑定解析表达式, 可以省略 v-bind

9、v-model

双向数据绑定

10、v-cloak

配合css解决由于网速慢是在页面展示{{xx}}问题

正常的html+js+css页面如下 是从头往下渲染的

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!--如果加载这个资源花了5s(浏览器设置网速模拟) 
    那么前5s是空白界面 然后从上而下加载页面 这个称为页面的阻塞  -->
    <script src="http://xxx/js/vue.js"></script>
</head>
<body>
<div id="root">
    <span>你好</span>
</div>
<script>
    const vm = new Vue({
        el:"#root",
        data:{
           name:'<h3>你好</h3>'
        },
    });
</script>
</body>
</html>

上面也是可以正常运行的

但是js位置也可以放在body中

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        /*设置有v-clock属性的元素样式 v-clock在vue接管元素后自动消失*/
        [v-clock]{
            display: none;
        }
    </style>
</head>
<body>
<div id="root">
    <span v-clock>{{name}}</span>
</div>
<script src="http://xxx/js/vue.js"></script>
</body>
<script>
    const vm = new Vue({
        el:"#root",
        data:{
            name:'<h3>你好</h3>'
        },
    });
</script>
</html>

11、v-once

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

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="root">
    <span v-once>初始值{{num}}</span>
    <span>当前值{{num}}</span>
    <button @click="num++">num+1</button>
</div>
<script src="js/vue.js"></script>
</body>
<script>
    const vm = new Vue({
        el:"#root",
        data:{
            num:1
        },
    });
</script>
</html>

12、v-pre

v-pre不会编译当前元素

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="root">
    <span>固定的没有指令的可以加v-pre优化性能</span>
    <span v-pre>{{num}}有指令的不能加v-pre</span>
</div>
<script src="js/vue.js"></script>
</body>
<script>
    const vm = new Vue({
        el:"#root",
        data:{
            num:1
        },
    });
</script>
</html>

 六、vue生命周期

  1. 初始化显示

  • beforeCreate()
  • created()
  • beforeMount()
  • mounted()

  1. 更新状态: this.xxx = value

  • beforeUpdate()
  • updated()

  1. 销毁 vue 实例: vm.$destory()

  • beforeDestory()
  • destoryed()

七、插件

作用

对vue增加作用,本质是一个{}对象,但是要求这个对象必须包含install(安装)方法,所以可以自定义插件

定义

export default {
	/*vue会自动调用 可以带参数  这个Vue参数就是vm的缔造者即vue构造函数*/
	install(Vue,x,y,z){
		console.log(x,y,z)
		//全局过滤器
		Vue.filter('mySlice',function(value){
			return value.slice(0,4)
		})

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

		//定义混入
		Vue.mixin({
			data() {
				return {
					x:100,
					y:200
				}
			},
		})

		//给Vue原型上添加一个方法(vm和vc就都能用了)
		Vue.prototype.hello = ()=>{alert('你好啊')}
	}
}

引入并使用

main.js中引入并使用

import MyPlugins from "./MyPlugins";
Vue.use(MyPlugins,1,2,3)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序三两行

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值