vue入门--vue常用属性、生命周期、计算属性、过滤器、组件、虚拟DOM、数组的响应式方法、页面闪烁、ES6简单语法增强

vue入门–基础命令+axios+案例练习
vue入门–vue常用属性、生命周期、计算属性、过滤器、组件、虚拟DOM、数组的响应式方法、页面闪烁、ES6简单语法增强
vue入门–js高阶函数(箭头函数)、v-model数据绑定、组件化、父子组件通信及访问
vue入门–插槽(具名、匿名、作用域插槽)+ES6模块化导入导出+webpack的使用(基本使用+配置使用+如何一步步演化成cli脚手架)+webpack插件使用(搭建本地服务器、配置文件分离)
vue-cli脚手架2版本及3+版本安装、目录解析、only和compiler的区别、3+版本如何改配置、箭头函数及this的指向
vue-router基本使用、路由传参、懒加载、嵌套路由、导航守卫、keep-alive
Promise基本使用、三种状态、链式调用及简写、all方法
Vuex的作用、使用、核心概念(State、Mutations、Getters、Actions、Modules)、文件抽离
axios网络请求基本使用、配置使用(全局axios和局部axios实例)、模块封装、axios拦截器

Vue及组件介绍

vue是一个前端框架,开发者只需要关注视图层(HTML+CSS+JS),其他的框架都已经封装好了。

网络通信:axios

页面跳转:vue-router

状态管理:vuex

VUE-UI: element-ui等等

学习vue之前,一定要有HTML、CSS、JavaScript的基础。

Webpack打包(js构建工具)

原生js开发,就是让我们按照【ECMAScript】标准的开发方式,简称ES,特点是:所有浏览器都支持。ES也有很多版本。开发时,大多是按照ES6的版本开发。但是大多数浏览器现在基本支持到ES5,所有我们需要使用 Webpack进行打包。

本质上,webpack是一个现代JavaScript应用程序的静态模块打包器,项目下需要有 package.json文件。webpack是一款模块加载兼打包工具,能把各种资源(js,ES6)图片等作为模块来处理和使用。

MVVM模式

  • Model:模型层,这里表示JavaScript对象
  • View:视图层 ,DOM(HTML操作的元素)
  • ViewModel: 连接视图和数据的中间间,Vue.js就是MVVM的ViewModel层的实现者

ViewModel能够监听数据的变化,并且对视图进行更新。而且还能监听到视图的变化,通知数据进行改变。

Vue详情

vue常用属性

  • el : 指示vue编译器从什么地方开始解析vue语法,可以说是进行元素绑定
  • data : 用来放数据的地方
  • methods : 定义需要用的方法实现
  • computed : 用来计算
  • watch : 监听data中的数据
  • template : 用来设置模板,会替换页面元素,包括占位符
  • components: 组件

vue命令

命令 说明 实例
v-bind 绑定属性 v-bind:title=“message” 或者 :title=“message”
v-on 绑定事件 v-on:click=“方法” 或者 @click=“方法”
v-if 是否显示(删除DOM元素方式) <h2 v-if=“num > 0”>我是h2</h2>
v-show 是否显示(改属性方式) <h2 v-show=“num > 0”>我是h2</h2>
v-for 遍历 <li v-for=“item in 列表”>{ { item.name }}</li>
v-model 数据视图双向绑定 <input v-model=“name” value=“默认文本” />
v-once 在标签元素上使用后,元素中vue变量的值不会再改变 <h2 v-once>{ { message }}</h2>
v-pre 不解析{ {}},插值表达式,原封不动
v-cloak 解决插值表达式闪烁

v-on

为某个元素绑定事件,实现一个事件监听功能。

语法

语法:v-on 或者使用v-on的语法糖 @

当函数中没有需要参数时,vue指令中调用函数时,可以不加(),但是插值表达式必须加

<div id="app">
    <h2>{
   
   {counter}}</h2>
    <button @click="increment">+</button>	

    <button @click="decrement">-</button>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    const app = new Vue({
      
      
        el:"#app",
        data:{
      
      
            counter:0
        },
        methods:{
      
      
            increment(){
      
      
                this.counter++;
            },
            decrement(){
      
      
                this.counter--;
            }
        }
    })
</script>

参数传递问题

当方法中定义了参数,但是使用的时候没有传过来,那么Vue会将浏览器生成的event对象给调用的方法中第一个参数传过去。

<div id="app">
    <button @click="add">+</button>	<!-- 由于调用add没给参数,vue会把event给传过去 -->
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    const app = new Vue({
      
      
        el:"#app",
        methods:{
      
      
            add(abc){
      
      	// 这里会获取到event对象
                console.log(abc)	
            }
        }
    })
</script>

当方法中,需要一般参数和事件参数时,特殊情况

<div id="app">
    <button @click="add">+</button>				<!-- 没传参数 -->	
    <button @click="add(11, event)">+</button>	<!-- 错误参数 -->
    <button @click="add(11,$event)">+</button>	<!-- 正确参数 -->
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    const app = new Vue({
      
      
        el:"#app",
        methods:{
      
      
            add(abc,event){
      
      
                console.log(abc, event)
            }
        }
    })
</script>

在这里插入图片描述

修饰符问题

  • .stop : 调用event.stopPropagation(),阻止冒泡

    使用后,当子元素和父元素都设置了点击事件时,点击子元素,只执行子元素的点击事件

    <div id="app" @click="divClick">
        aaaaaa
        <button @click.stop="btnClick">按钮</button>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        const app = new Vue({
            
            
            el:"#app",
            methods:{
            
            
                btnClick(){
            
            
                    console.log('btnClick')
                },
                divClick(){
            
            
                    console.log('divClick')
                }
            }
        })
    </script>
    
  • .prevent : 调用event.preventDefault(),阻止默认事件,比如表单提交,我点提交按钮,只想执行我自己定义的事件进行提交

    <div id="app" @click="divClick">
        <form action="aaa">
            <!--点提交后,我指向使用formSubmit定义的提交,不想走默认的表单提交
    			可以使用 .prevent修饰符
    		-->
            <input type="submit" value="提交" @click.prevent="formSubmit">
        </form>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        const app = new Vue({
            
            
            el:"#app",
            methods:{
            
            
                formSubmit(){
            
            
                    console.log('formSubmit')
                }
            }
        })
    </script>
    

在这里插入图片描述

  • .keyCode: 监听键盘点击

    @keyup.enter: 回车

    <div id="app">
        <input type="text" @keyup.enter="add" value="">
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        const app = new Vue({
            
            
            el:"#app",
            methods:{
            
            
                add(){
            
            
                    alert("回车了")
                }
            }
        })
    </script>
    
  • .native : 监听组件的根元素的原生事件

  • .once : 只触发一次,回调只执行一次

vue生命周期

从开始创建 -> 初始化数据 -> 编译模板 -> 挂载DOM -> 渲染->卸载等

开发中,经常会需要在某一个时刻把数据加载到页面元素中,那么在vue生命周期中,就存在一些钩子函数(事件),我们可以在某一刻的钩子函数中加载数据。

  • beforeCreate:创建vue实例之前执行的钩子函数

  • created: 创建vue实例完成后,执行的钩子函数

  • beforeMount: 将编译完成的HTML挂载到对应虚拟DOM时触发的钩子(此时页面是没有内容的)

  • mouted: 编译好的HTML挂载到页面完后执行的钩子(可在此做数据的初始化),注意:mounted在整个实例中只会执行一次

    。。。

var app = new Vue({
    
    
    el:"#app",
    data:{
    
    
        items:["java","Linux"]
    },
    mounted(){
    
    
        console.log("初始化数据了")
    }
})

vue组件

组件就是可以复用的Vue实例,说白了,就是一组可以重复使用的模板

<div id="app">
    <!--
		每遍历一次 vue 标签,都把item的值 传给了 vue组件的 props中的值(接收外部的值所定义的属性)
	-->
    <vue v-for="item in items" :wlh="item"></vue>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    // 定义组件
    Vue.component("vue",{
      
      
        props:['wlh'],	// 定义这个组件接收的参数
        template: '<li>{
      
      { wlh }}</li>'	// 定义展示的模板
    })
    var app = new Vue({
      
      
        el:"#app",
        data:{
      
      
            items:["java","Linux"]
        }
    })
</script>

后面开发中,我们一个vue文件就是一个组件,可在view(html)中引用。

需要注意的是:vue组件中不能定义data属性,只能定义一个data的函数

vue计算属性

计算属性:计算出来的结果保存在属性中,内存中运行:虚拟DOM。计算属性的主要特性就是为了将不经常变化的计算结果进行缓存,节约系统开销。

理解为:将计算结果存入缓存

需要注意的是:计算属性是一个属性,不是一个函数,调用时不要加小括号 '()'

<div id="app">
    <p>currentTime1 : {
   
   { currentTime1() }}</p>
    <p>currentTime2 : {
   
   { currentTime2 }}</p>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>

    var app = new Vue({
      
      
        el:"#app",
        data:{
      
      
            message:"hello vue"
        },
        methods:{
      
      
            currentTime1:function(){
      
      
                return Date.now(); // 返回一个时间戳
            }
        },
        // 计算属性 不要和 methods属性中的方法重复,否则只会调用 methods中的方法
        computed:{
      
       
            currentTime2:function(){
      
      
                this.message;   // 当发现 message属性变化时,会重新返回一个 时间戳,否则就不会变
                return Date.now(); // 返回一个时间戳
            }
        }
    })
</script>

以上代码中实现,当 vue对象的message属性变化时(由于currentTime2函数中用到了 message),currentTime2会再次执行一次,并且将结果返回给 { {currentTime2}}

计算属性的getter和setter

计算属性的实现,实际上就是属性的get方法

new Vue({
    
    
  el: '#app',
  data:{
    
    
    firstName:"w",
    lastName:"lh"
  },
  computed:{
    
    
    fullName:function(){
    
    		// fullName和fullName2达到同样的效果
      return this.firstName + " " + this.lastName;
    },
    fullName2:{
    
    		
      set:function(){
    
    	// 计算属性中,set方法一般不用实现,这里只是为了说明

      },
      get:function(){
    
    	// 通过get方法,获取值
        return this.firstName + " " + this.lastName;
      }
    }
  }
})

Vue虚拟DOM

问题一:

网页元素被正式渲染到浏览器上面之前,会先去虚拟DOM中做一次预处理。假如有上次遗留的可复用的一些网页元素,那么Vue就会去直接去使用这些用过的DOM元素(导致某些数据没有被清空),把某些属性给替换掉。

问题二:

假如一个数组已经渲染到了浏览器上,然后我要动态给数组中插入一个元素,那么默认的做法就是:找到要替换的位置,然后把值直接赋给这个位置上,然后后面依次去修改元素的值。导致效率低下。

解决方案:

给标签元素加key,给标签做一个标识,假如两个标签元素的key是相同的,那么vue才会去复用标签元素;当我们插入元素时,需要使用key给每个节点做一个唯一标识,Diff算法就可以正确的识别此节点,找到正确的位置区插入新的节点。

key要选择具有唯一值的

<li :key="xxx.id"></li>

ES6语法

let/var

let支持块级作用域。var是不支持块级作用域的,也就是var定义的变量全局可用。

ES5及之前因为if和for都没有块级作用域的概念,所以很多时候都要借助于function的作用域(注意function是有作用域的)来解决使用外面变量的问题。

在ES6中,加入了let,let是有if和for块级作用域。

实例讲解:

var

if(true){
    
    
    var name = "zs"	// 在if代码块中定义了一个 name属性
}
alert(name)// 因为name是没有块级作用域的(name变成了全局变量),if代码块外部同样可以调用。。。

在这里插入图片描述

let

if(true){
    
    
    let name = "zs"	// 在if代码块中定义了一个 name属性
}
alert(name)// 因为name是有块级作用域的(name变成了局部变量),if代码块外部不能调用

在这里插入图片描述

const

将标识符修改为常量。在ES6开发中,优先使用const,只有需要改变某一个标识符的时候才去使用let。

定义const时,必须要赋值进行初始化。

需要注意的是:常量的含义是,指向的对象不能修改,但是可以改变对象内部的属性。

const obj = {
    
    
    name:"zs",
    age:21
}
obj.name = "ls"	// 可以修改

对象字面量的增强写法

属性增强

const name ="zs"
const age = 21
function hello(){
    
    
    alert("你好")
}
const obj = {
    
    
    name,		// 可直接省略value值,会自动找上面的name
    age,
    hello		// 这里会直接找同名的 对象赋给 hello属性
}
console.log(obj)

在这里插入图片描述

函数增强

const obj = {
    
    
    run(){
    
    

    },
    eat(){
    
    

    }
}

数组中的响应式方法

  • push()
  • pop()
  • shift()
  • unshift()
  • splice()
  • sort()
  • reverse()
<div id="app">
    <ul>
        <li v-for="item in letters" :key="item">{
   
   {item}}</li>
    </ul>
    <button @click="clickBtn">点击</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    const app = new Vue({
      
      
        el: "#app",
        data: {
      
      
            letters: ["a", "b", "f","c", "d"]
        },
        methods: {
      
      
            clickBtn() {
      
      
                // 1.push()方法 是响应式
                this.letters.push('aa','bb');

                // 2.直接修改数组中的值  注意:不是响应式,修改后,页面上不会发生任何改变
                this.letters[0] = 'bbbbb';

                // 3.pop() (删除尾部的一个元素)响应式
                this.letters.pop();

                // 4.shift() (删除头部的一个元素) 响应式
                this.letters.shift()

                // 5.unshift() 在头部插入元素 响应式
                this.letters.unshift("aaaa","bc");

                // 6.splice() (插入元素) param1:开始位置 param2:数量 params3:元素或者数组 响应式
                this.letters.splice(1,1,"j","k","l")    // 把下标是 1 的元素替换成了 j、k、l

                // 7.sort() 排序 响应式
                this.letters.sort()

                //8.reverse() 反转 响应式
                this.letters.reverse()
            }
        }
    })
</script>

vue过滤器

<!-- 使用方式: 值 | 过滤器引用    会自动把值给过滤器中传过去 -->
<td>¥{
   
   {item.price | getFinalPrice}}</td>

<script>
    const app = new Vue({
      
      
        el: "#app",
        filters:{
      
      
            getFinalPrice(price){
      
      
                return price.toFixed(2);	// 保留两位小数
            }
        }
    })
</script>

解决页面刷新闪烁问题

原理:当vue对象解析 { {message}}之前,div标签会存在一个 v-cloak的属性,在vue解析完{ {message}}之后,将div标签的v-cloak属性删除掉。

<style>
    [v-cloak]{
      
      
        display: none;
    }
</style>
<body>
    <div id="app" v-cloak>
        {
   
   {message}}
    </div>
</body>

vue练习

下拉框双向绑定

实现:当选中一个选项时,把当前选项的value值,及时更新到变量中

<div id="app">
    <select v-model="selected">
        <option value="" disabled>--请选择--</option>
        <option value="A">A</option>
        <option value="B">B</option>
        <option value="C">C</option>
    </select>
    <h2>{
   
   { selected }}</h2>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    var app = new Vue({
      
      
        el:"#app",
        data:{
      
      
            selected:''
        }
    })
</script>

v-bind:class 数组语法

<h2 class="title" :class="[active, line]"></h2>		
<h2 class="title" :class="['active', 'line']"></h2>

第一个h2标签的 active和line是使用的vue中的变量

第二个h2标签是定义class的值为: active和line

class和:class最后都会被合并到一起。

动态绑定style

<h2 :style="{font-size: '20px'}"></h2>	// 使用值
<h2 :style="{font-size: vueFontSize+'px'}"></h2>	// 使用vue变量

购物车

<div id="app">
    <h2 v-if="books.length==0">购物车为空</h2>
    <table border="1px">
        <tr v-if="books.length!=0">
            <td>序号</td>
            <td>书名</td>
            <td>出版日期</td>
            <td>价格</td>
            <td>购买数量</td>
            <td>操作</td>
        </tr>
        <tr v-for="(item,index) in books" :key="item.id">
            <td>{
   
   {index+1}}</td>
            <td>{
   
   {item.name}}</td>
            <td>{
   
   {item.date}}</td>
            <td>¥{
   
   {item.price | getFinalPrice}}</td>
            <td>
                <button @click="decrement(index)" :disabled="item.count===1">-</button>
                {
   
   {item.count}}
                <button @click="increment(index)">+</button>
            </td>
            <td>
                <button @click="remove(index)">移除</button>
            </td>
        </tr>

    </table>
    总价:{
   
   {totalPrice | getFinalPrice}}
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    const app = new Vue({
      
      
        el: "#app",
        data: {
      
      
            books:[
                {
      
         
                    id:1,
                    name:"《算法导论》",
                    date:"2006-9",
                    price:85.12,
                    count:1
                },
                {
      
      
                    id:2,
                    name:"《UNIX编程艺术》",
                    date:"2006-2",
                    price:59.28,
                    count:1
                },
                {
      
      
                    id:3,
                    name:"《编程珠玑》",
                    date:"2008-10",
                    price:39.2,
                    count:1
                },
                {
      
      
                    id:4,
                    name:"《代码大全》",
                    date:"2006-3",
                    price:128.00,
                    count:1
                }
            ]
        },
        methods:{
      
      
            remove(index){
      
      
                this.books.splice(index, 1);
            },
            increment(index){
      
      
                this.books[index].count++;
            },
            decrement(index){
      
      
                this.books[index].count--;
            }
        },
        computed:{
      
      
            totalPrice:function(){
      
      
                console.log("totalPrice")
                return this.books.reduce((a, b) => a+b.count*b.price, 0);
            }
        },
        filters:{
      
      
            getFinalPrice(price){
      
      
                return price.toFixed(2);
            }
        }
    })
</script>

在这里插入图片描述

vue入门–基础命令+axios+案例练习
vue入门–vue常用属性、生命周期、计算属性、过滤器、组件、虚拟DOM、数组的响应式方法、页面闪烁、ES6简单语法增强
vue入门–js高阶函数(箭头函数)、v-model数据绑定、组件化、父子组件通信及访问
vue入门–插槽(具名、匿名、作用域插槽)+ES6模块化导入导出+webpack的使用(基本使用+配置使用+如何一步步演化成cli脚手架)+webpack插件使用(搭建本地服务器、配置文件分离)
vue-cli脚手架2版本及3+版本安装、目录解析、only和compiler的区别、3+版本如何改配置、箭头函数及this的指向
vue-router基本使用、路由传参、懒加载、嵌套路由、导航守卫、keep-alive
Promise基本使用、三种状态、链式调用及简写、all方法
Vuex的作用、使用、核心概念(State、Mutations、Getters、Actions、Modules)、文件抽离
axios网络请求基本使用、配置使用(全局axios和局部axios实例)、模块封装、axios拦截器

猜你喜欢

转载自blog.csdn.net/weixin_45248492/article/details/124806147