谷粒商城第四天-前端基础

13 篇文章 0 订阅
2 篇文章 0 订阅

目录

一、前言

二、学习的内容

一、ES6新语法

1.1  var与let

1.2  const

1.3  解构表达式的使用

1.4  字符串Api的使用

1.5  函数优化

1.6  箭头函数

1.7 对象优化

1.8 map和reduce

1.9 promise异步编排

1.10  模块化(export和import的使用)

二、vue中的常用指令

2.0  vue环境的搭建

2.1  简单例子

2.2  v-text、v-html

2.3  v-bind

2.4  v-model

2.5  v-on

2.6  v-for

2.7 v-if、v-else-if、v-else和v-show

三、vue中的计算属性和监听器

四、vue中的过滤器

五、钩子函数

六、vue中组件的使用

七、使用vue脚手架搭建前端工程以及使用elementUI来快速开发

三、完成的进度

四、总结


一、前言

从最开始的项目介绍,架构介绍,到后面的环境搭建,然后到微服务组件的介绍,第四天迎来的前端基础环节,这个项目基础篇的主要目标就是打通全栈开发能力,当然前端也就不容忽视了。但这里的讲的前端,并不是原生的html,css和js了,默认我们都会了,其实我这些还好多都不会,说实话只学了一少部分,学的不多,看什么时候有时间好好的补一补,今天第四天主要学的是响应式框架-vue。

二、学习的内容

主要学的是vue,之前一部分学的是ES6,ES是一套规范,JS是基于这套规范的,就像Java中的JDK一样,这部分主要学的是一些新语法。后面就主要是vue了,学习vue的一些语法:指令、计算属性、监听器、过滤器、钩子函数、组件还有基于vue的脚手架开发。

一、ES6新语法

1.1  var与let

这两者都是用来声明变量的,区别在于var比较随意,而let比较严格。

var声明的变量跨块使用,而这个let不能跨块使用,就是var有点类似于全局变量。

并且var还比较放肆,可以对于同一个变量名,可以重复声明。

下面是代码例子:

<script>
        {
            var v = 1;
            let l = 2;
        }
        console.log(v);
        //console.log(l); // l is not defined

        var m = 1;
        var m = 2;
        console.log(m);
        let n = 1;
        //let n = 3; 不可重复定义
        console.log(n);
</script>

1.2  const

和c语言中的const以及Java中的final一样,都是代表声明的是常量,一旦声明好之后,就不能在被修改。

<script>
        const m = 1;
        //m = 2; //2. const.html:11  Uncaught TypeError: Assignment to constant variable. 
        console.log(m);
        console.log(m);
</script>

1.3  解构表达式的使用

这个比较有意思,何为解构,就是说可以直接分解结构获取到值。其实就是一个写好了的数组或者是一个对象,我们可以很简单的获取到里面的元素赋值变量,不需要我们一个一个的自己手动的去获取。

就比如说数组就可以直接使用[变量]进行接受,如下是示例:

<script>
let arr = [1, 2, 3];
const [x, y, z] = arr;
console.log(x, y, z); //打印出1,2,3
</script>

 还可以解构对象哦!如下所示:

<script>
//const {name,age} = person;
//console.log(name,age);
//可以给name起别名。注意这个变量名也不能重复
const {name:nn,age} = person;
console.log(nn,age);
</script>

1.4  字符串Api的使用

首先是很简单的字符串函数的使用:

<script>
let str = "hello world";
console.log(str.startsWith("he"));//true
console.log(str.endsWith("ld"));//true
console.log(str.includes("o"));//true
console.log(str.includes("hello"));//true
</script>

下面就是关于字符串的相关的几个方便之处,也就是 使用 ``

//多行字符串 `的使用
<script>
         let ss = `<div>
                    <span>Hello World</span>        
                 </div>
        `
        console.log(ss);
        let name = "zhangsan";
        let age = 20;
        let info = `我是${name},今年${age}岁了`;
        console.log(info);
        function fun(){
            return "这是一个函数";
        }
        let sss =  `这是什么?${fun()}`;
        console.log(sss);
</script>

1.5  函数优化

可以为函数的参数直接指定默认值。还可以使用可变形参和Java一样

<script>
        //函数参数默认值
        function add1(a,b){
            b = b|2;
            return a + b;
        }
        console.log(add1(1));
        function add2(a,b=1){
            return a + b;
        }
        console.log(add2(1));
        //不定参数
        function fun(...values){
            console.log(values.length);
        }
        fun(1,2,3,4);
        fun(2,3);
        
 </script>

1.6  箭头函数

箭头函数和Java中的lambda很像,都是简便方法对象的创建。当然创建的结果不一样,JS中是函数对象,而Java不单指方法对象,而是接口实现类对象。

箭头函数可以结合解构表达式使用,在之后的前端发送请求,获取到的result对象,可以直接解构拿出其中的属性(比如说data)。直接使用{data}解构出data属性,得到后端真正发送的响应对象。

<script>
        let hello = function (a,b){
            return a + b;
        }
        console.log(hello(1,2));
        //使用箭头函数
        let hello1 = (a,b) => a+b;
        console.log(hello1(2,3));
        //箭头函数结合解构表达式
        const person = {
            name: "jack",
            age: 20
        }
        //以前的方式
        function hello3(person){
            console.log(person.name);
        }
        hello3(person);
        //现在结合解构表达式
        let hello2 = ({name}) => console.log("name:",name);
        hello2(person);
</script>

1.7 对象优化

主要就是Object类的使用、拷贝、对象的简写、对象的方法的简写、对象的拓展运算符(拷贝对象、合并对象)

<script>
        //新增的Api
        const person = {
            name : "Jack",
            age : 20,
            language: ["Java","C++","Python"]
        }
        console.log(Object.keys(person));
        console.log(Object.values(person));
        console.log(Object.entries(person));
        
        
        let target = {a : 1};
        let resource1 = {b : 2};
        let resource2 = {c : 3};
        //拷贝
        Object.assign(target,resource1,resource2);
        console.log(target);
        //声明对象简写
        let name = "zhangsan";
        let age = 20;
        //传统的
        let stu = {name: name,age: age}
        console.log(stu);
        //对于属性名和值变量名同名的情况,可以省略掉属性名
        let stu1 = {name,age};
        console.log(stu1);
        //对象的方法属性简写
        let dog = {
            //方式一
            dis:function(){
                console.log("这是一条小狗");
            },
            //方式二
            dis1:() => console.log("这是一条小狗......"),
            dis2(){
                console.log("这是一条小狗'''''");
            }
        }
        dog.dis();
        dog.dis1();
        dog.dis2();
        //对象的拓展运算符
        //拷贝对象
        let person1 = {name:"wangwu",age:20};
        let someone = {...person1};
        console.log(someone);
        //合并对象
        let name1 = {name:"lisi"};
        let age1 = {name:"zhaoliu",age:22};
        //重复的属性名,选取最后一个
        let person2 = {...name1,...age1};
        console.log(person2);
    
    </script>

1.8 map和reduce

就是使用map转换集合中的元素,和Java中的有点像。但是Java中的stream流中的map需要最终进行收集。但JS不需要。另外对于运算链来计算集合中的元素则可以使用reduce,比如求得集合中所有元素的乘积或者是和等。

<script>
        //map转换
        let arr = [1,2,3,4];
        arr = arr.map(s => s*2);
        console.log(arr);
        //reduce
        let arr1 = [3,4,5,6];
        console.log(arr1.reduce((a,b) => a+b));
        //还可以指定初始值
        console.log(arr1.reduce((a,b)=>a+b,1));
</script>

1.9 promise异步编排

promise存在的意义其实就是为了使代码变得清晰,而不混乱。解决的是链式调用的嵌套问题。就比如说不用promise之前,如果每次返回的结果又作为下次的请求参数,如果请求次数多了那么嵌套的层数也就多了,就比如说下面这个例子:

下面是user.json文件,存放着用户的姓名以及学生编号:

{
    "userName": "wangwu",
    "userId":5
}

下面是user_course_5.json文件,存放着学生编号为5的学生的课程信息,包含课程名称以及课程编号:

{
    "courseName" : "Math",
    "courseId" : 10
}

下面是course_score_10.json文件,存放着课程编号为10的课程成绩:

{
    "score" : 100
}

 传统的方式是下面这个样子:

$.ajax({
url: "mock/user.json",
success(data) {
console.log("查询用户:", data);
$.ajax({
url: `mock/user_corse_${data.id}.json`,
success(data) {
console.log("查询到课程:", data);
$.ajax({
url: `mock/corse_score_${data.id}.json`,
success(data) {
console.log("查询到分数:", data);
},
error(error) {
console.log("出现异常了:" + error);
}
});
},
error(error) {
console.log("出现异常了:" + error);
}
});
},
error(error) {
console.log("出现异常了:" + error);
}
});

很明显,代码很混乱,多层的嵌套。

于是promise的作用就体现出来了,promise能很清晰的知道一层一层的往下传递,结果很清晰,

如下:

<script> 
使用promise处理多层的嵌套
        new Promise((resove,reject)=>{
            $.ajax({
                url: "mock/user.json",
                success(data){
                    console.log("查询用户:",data);
                    resove(data.userId);
                },
                error(error){
                    console.log("出现异常了,",error);
                } 
            }
            )
        }).then((userId) =>{
            return new Promise((resove,reject)=>{
                $.ajax({
                    url: `mock/user_course_${userId}.json`,
                    success(data){
                        console.log("查询课程:",data);
                        resove(data.courseId);
                    },
                    error(error){
                        console.log("出现了异常,",error);
                    }
                })
            })
        }).then((courseId)=>{
            new Promise((resove,reject)=>{
                $.ajax({
                    url: `mock/course_score_${courseId}.json`,
                    success(data){
                        console.log("查询成绩:",data);
                    },
                    error(error){
                        console.log("出现了异常,",error);
                    }
                })
            })
        })
</script>

 使用resove方法将成功的结果一步一步的往下传递。每次使用promise对象对每次调用进行处理。

当然实际开发中,追求尽可能的通用,简洁。于是可以将一次处理就返回一个promise对象作为一个方法的返回值。

//优化
<script>
        let get = function(url,data){
            return new Promise((resove,reject)=>{
                $.ajax({
                    url: url,
                    type: "get",
                    data: data,
                    success(res){
                        resove(res);
                    },
                    error(error){
                        reject(error);
                    }
                })
            })
        }
        get("mock/user.json")
        .then((result)=>{
            console.log("查询到用户:",result);
            return get(`mock/user_course_${result.userId}.json`);
        })
        .then((result)=>{
            console.log("查询到课程:",result);
            return get(`mock/course_score_${result.courseId}.json`);
        })
        .then((result)=>{
            console.log("查询到分数:",result);
        })
    </script>

1.10  模块化(export和import的使用)

和Java一样,如果不是使用的自己造的东西,而是使用的别人的,就需要从外界导入进来,同样使用import关键字。

下面是导出的例子,语法是使用export关键字进行导出,可以导出JS中的任何变量。并且有一些简洁的方式,如下:

//先声明好对象,写好对象名,然后直接使用对象名导出即可
const util = {
    sum(a,b){
        return a + b;
    }
}
export {util};
//还可直接导出,就是将export和导出的内容连成一句话
export const util = {
    sum(a,b){
        return a + b;
    }
}
//还可以不指定对象的名字,这样在其它文件中导入的时候可以不指定名字,只需写明正确的路径即可
export default {
    sum(a,b){
        return a + b;
    }
}
//除了对象,其它任何js变量都可以导出,数组,函数,基本类型变量
let name = "Jack";
let age = 20;
export {name,age};

下面是导入的例子, 使用import xxx(变量名) from 文件路径的语法进行导入。

//导入的对象的名字和从哪个文件导入的位置写好
import { util } from "./hello";
//当是默认导出的时候,名字可以随便取
import { util1 } from "./hello";
//导入基本数据类型,并不是完全都要导入的,导入我们所需要的即可
import { name,age } from "./hello";

二、vue中的常用指令

2.0  vue环境的搭建

首先,但凡是环境的搭建,都可以参考官方的文档,翻阅vue的官方文档可以知道,vue的环境搭建,可以有下面的三种方式:

1. 直接引入vue的js文件,可以是直接使用script直接引入网址或者是引入离线的文件

2. 使用DNS的方式

3. 使用node.js的npm下载工具vue工程

官方推荐使用npm的方式进行搭建。

既然要使用npm的方式,npm又是依赖于node.js的环境的,所以得首先在本地下载好node.js的环境。

下载的步骤如下:

1)、官网下载安装 node.js,并使用 node -v 检查版本

2)、配置 npm 使用淘宝镜像 npm config set registry http://registry.npm.taobao.org/

3)、大家如果 npm install 安装依赖出现 chromedriver 之类问题,先在项目里运行下面命令 npm install chromedriver --chromedriver_cdnurl=http://cdn.npm.taobao.org/dist/chromedriver 然后再运行 npm install

创建vue的简单项目步骤如下:

1. 在本地创建好一个文件夹,使用vscode进行打开

2. 使用vscode的终端执行 npm install -y的命令,项目会生成package-lock.json的文件,这个文件类似于Maven的pom文件,是用来管理依赖的

3. 使用 npm install vue的命令,给当前项目下载vue,项目下面会多出来node_modules文件夹,这个文件夹下面有vue文件夹。(之后使用script标签导入vue的环境就是靠这个vue文件夹中的dist目录下的vue.js文件)。当没有vue.js文件的时候,可以下载vue2版本,使用 npm install vue@2命令下载版本2的vue

这是创建的vue项目的大致样子:

使用src文件夹来放置源代码。 

2.1  简单例子

下面这个例子,简单的体会vue这种“去掉对dom元素直接操作”的思想,其实也就是MVVM的思想,前面的MV指的是Model(模型,也就是数据)和View(也就是视图,将数据进行展示的),

最后的VM也就是View-Model 视图和模型间的双向操作,这里无需开发人员干涉,开发人员不在需要关注DOM操作,只需要关心 :数据怎么来,界面怎么画,数据怎样渲染到界面里面去。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="/node_modules/vue/dist/vue.js"></script> 
    <title>Document</title>
</head>
<body>
    <div id="app">
        <input type="text" v-model="num"><br>
        我是{{name}},今年{{age}}岁了<br>
        <h2>有{{num}}个人为我点赞</h2><br>
        <button v-on:click="num++">增赞</button>
    </div>
    <script>
        let vm = new Vue({
            el : "#app",
            data :{
                name: "zhangsan",
                age:20,
                num: 0
            } 
        })
    </script>
</body>
</html>

其中简单的涉及到 事件,双向绑定,以及插值表达式的使用 

2.2  v-text、v-html

我们知道可以使用插值表达式拿出Model中的数据进行显示,其实也可以使用v-text将数据进行显示,但是这是使用在标签里面,另外当字符串为一段HTML代码的时候,不想要它直接显示,而是解析HTML代码,进行显示就使用v-html指令。下面是代码示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="/node_modules/vue/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        下面是一段普通文本:<br>
        <span v-text="text"></span><br>
        下面是一段Html代码:<br>
        <span v-html="htmlStr"></span>
    </div>
    <script>
        let vm = new Vue({
            el: "#app",
            data(){
                return {
                    text:"<h1>普通文本</h1>",
                    htmlStr:"<h1 style='color:red'>你好</h1>"
                }
            } 
        })
    </script>
</body>

</html>

效果: 

2.3  v-bind

其实也就是动态的改变html或者是css的自带属性中的属性值的可以,我反正感觉就是这个作用,包括  <a>标签,class属性,以及style属性等,在后面还有key,用来区分每一行li或者是tr

下面是示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="/node_modules/vue/dist/vue.js"></script>
    <div id="app">
        <a v-bind:href="link">百度一下</a><br>
        <span v-bind:class="{active:isActive,'text-danger':hasError}" :style="{color:color1,fontSize:size}">
              你好      
        </span>
    </div>
</head>
<body>
    <script>
        new Vue({
            el : "#app",
            data() {
                return {
                    link:"www.baidu.com",
                    isActive:false,
                    hasError:true,
                    color1:'red',
                    size: '36px'
                }
            }
        })
    </script>
</body>
</html>

注意:现在这些属性值是使用{}进行包裹,其实也就是一个对象,所以里面使用逗号分隔,另外,属性名如果带上了 ‘-’那么需要使用  一对 ' ' 单引号括起来,可以使用bool值来确定某个样式是否存在,以及通过model中的值动态指定样式。 

2.4  v-model

双向绑定指令,相较于单向绑定,只能使用模型改变视图,而不能视图改变模型。这在开发中有个时候是不方便的,例如表单,以及复选框等结构。

下面这个示例中,使用v-model处理复选框,使得我们通过视图所选的值,也能更新到模型中。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="/node_modules/vue/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        擅长的语言:<br>
        <input type="checkbox" value="Java" v-model="language">Java<br>
        <input type="checkbox" value="C++" v-model="language">C++<br>
        <input type="checkbox" value="Python" v-model="language">Python<br>
    </div>
    <script>
        let vm = new Vue({
          el: "#app",
          data(){
            return{
                language:[]
            }
          }  
        })
    </script>
</body>
</html>

2.5  v-on

这个指令就是绑定事件的,常见的比如说绑定单击事件click,鼠标单击事件,键盘按下事件等。

今天学的就是这个,单纯的绑定一个事件比较简单,比较需要注意的是,绑定的那个事件的执行可以不是函数,可以是js代码段,另外还需要理解事件修饰符的使用(可以利用这个来对事件进行控制,比如说阻止事件冒泡,限制事件的执行次数等)。

还有按键修饰符的使用,其实就是绑定的按下键盘事件。

这里着重的解释下 事件修饰符的使用:

1. `.stop` :阻止事件冒泡到父元素

2.  `.prevent`:阻止默认事件发生

3. `.capture`:使用事件捕获模式

4.  `.self`:只有元素自身触发事件才执行。(冒泡或捕获的都不执行)

5.  `.once`:只执行一次

下面解释事件冒泡:

怎样理解呢?可能有小伙伴不理解冒泡的意思,其实就是像气泡一样,从下往上冒上去。

但这里冒的不是气泡,是函数。

就比如说两个div盒子是嵌套的,如果是两个盒子上面给单击事件绑定了相同的方法的话,那么点击里面的盒子,那么会将那个函数执行两次,原因很简单,因为点击了里面的盒子,实际上也是点击了外面的那个盒子。

使用.stop指令则更好可以阻止冒泡,给里面那个盒子加上这个,就能阻止冒泡上去。

而.capture是来干啥的呢?加上了它,其实就是跌倒冒泡的顺序,加上了它,就会执行最外层盒子的事件。

这个事件修饰符可能不是那么好理解,那我直接给出示例:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <script src="/node_modules/vue/dist/vue.js"></script>
    <style>
        .common{
            border: 1px solid red;
            padding: 20px
        }
    </style>
  </head>
  <body>
    <div id="app">
      <!-- 事件中直接写js片段 -->
      <button v-on:click="num++">点赞</button><br />
      <!-- 事件中写函数 -->
      <button @click="cancel">取消</button><br />
      <h2>当前有{{num}}个赞</h2>
      <!-- 事件修饰符 -->
      <div style="border: 1px solid red; padding: 20px" @click.once="dis()">
        大div
        <div style="border: 1px solid blue; padding: 20px" @click.stop="dis()">
          小div <br />
          <a href="http://www.baidu.com" @click.prevent>百度一下</a>
        </div>
      </div>
      <!-- 测试capture修饰符:打乱冒泡顺序 -->
      <div class="common" @click.capture="outer">
        <div class="common" @click.capture="middle">
          <div class="common" @click="innerdiv">
            <button @click="inner">点击我(^_^)</button>
          </div>
        </div>
      </div>
      <!-- 按键修饰符 -->
      <input type="text" @keyup.enter="enter"><br>
      <input type="text" @keyup.alt.67="altc">
    </div>
    <script>
      let vm = new Vue({
        el: "#app",
        data() {
          return {
            num: 0,
          };
        },
        methods: {
          cancel() {
            this.num--;
          },
          dis() {
            alert("被点击");
          },
          outer() {
            console.log("outer,最外面的div被点击了");
          },
          middle() {
            console.log("middle,中间的div被点击了");
          },
          inner() {
            console.log("inner,最里面的按钮被点击了");
          },
          innerdiv(){
            console.log("最里面的div被点击了");
          },
          enter(){
            alert("按下了回车键");
          },
          altc(){
            alert("按下了Alt+C的组合键");
          }
        },
      });
    </script>
  </body>
</html>

上面那个例子没啥好说的,大div只会执行一次函数,因为.once,并且点击里面的盒子也只会执行一次,因为在里面这个盒子加上了.stop阻止冒泡到上面那个盒子,而如果点击百度一下,则只会执行里面这个盒子的函数,因为没有阻止冒泡,并且.prevent了,所以默认的事件(也就是原本的点击超链接跳转网页的这个事件)被禁止里面,因此也就不会跳转到百度网站去了。

下面的这一组div是为了测试.capture事件修饰符的,也就是打乱冒泡的顺序。原本本应该是从里往外进行冒泡的,但是现在加上了这个,使得最外面的盒子先是响应,先执行函数,其实也就是先执行离得最远的盒子绑的事件。所以运行结果是下面这样:

 outer,最外面的div被点击了

middle,中间的div被点击了

最里面的div被点击了

inner,最里面的按钮被点击了

因为第三个盒子没有加上这个修饰符,因此按照正常顺序执行,也就是里面的盒子先冒泡。

2.6  v-for

v-for这个标签就是遍历的元素的,可以遍历数组,也可以遍历对象,到那个元素上面进行遍历呢?一般是 li 或者是 table中的tr

下面这个例子就是演示使用li这个元素来遍历 数组和对象。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <script src="/node_modules/vue/dist/vue.js"></script>
  </head>
  <body>
    <div id="app">
      <ul>
        <!-- 加上key可以提高渲染效率 -->
        <li v-for="user,index in users" :key="index">
            {{index}} => {{user.name}} => {{user.gender}} => {{user.age}}
        </li>
      </ul>
      <ul>
        <li v-for="(value,key,index) in user">
            {{index+1}} => {{key}} => {{value}}
        </li>
      </ul>
    </div>
    <script>
      let vm = new Vue({
        el: "#app",
        data() {
          return {
            users: [
              { name: "柳岩", gender: "女", age: 21 },
              { name: "张三", gender: "男", age: 18 },
              { name: "范冰冰", gender: "女", age: 24 },
              { name: "刘亦菲", gender: "女", age: 18 },
              { name: "古力娜扎", gender: "女", age: 25 }
            ],
            user:{
                name: "张三",
                gender: "男",
                age: 20
            }
          };
        },
      });
    </script>
  </body>
</html>

注意:可以加上索引,索引都是指明在最后,可以使用索引来作为:key的值,可以提高渲染的速度。当遍历对象时,可以同时获取到对象的key value 和 index 但是是按照这个顺序的,缺少了的话,就相当于少了后面,比如只写两项那么index就没有了。其中无论是遍历数组还是遍历对象都可以省略圆括号。 

2.7 v-if、v-else-if、v-else和v-show

v-if 以及 v-show都是根据model中的布尔值来决定元素是否存在,当然只有是v-if当布尔值为false的时候,这个dom元素才是真的没有,而v-show只是改变了样式,加了个style="display:none"

 因此v-if的开销更大,因此能使用v-show,尽量使用v-show。

这个命令很简单,很程序设计语言中使用没有区别,下面给出简单的示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="/node_modules/vue/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <button @click="show = !show">点我呀</button><br>
        <!-- v-if是将整个dom删掉 -->
        <h1 v-if="show">
            看到我了
        </h1>
        <!-- v-show是改变样式 -->
        <h1 v-show="show">
            看到我了--show
        </h1>
        <!-- v-else-if v-else -->
        <button @click="random = Math.random()">
            点我呀
        </button><br>
        <span>{{random}}</span>
        <h1 v-if="random>=0.75"> 
            看到我啦?random>=0.75
        </h1>
        <h1 v-else-if="random>0.5">
            看到我啦?random>0.5
        </h1>
        <h1 v-else-if="random>0.25">
            看到我啦?random>0.25
        </h1>
        <h1 v-else>
            看到我啦?random<=0.25
        </h1>
    </div>
    <script>
        new Vue({
            el : "#app",
            data(){
                return {
                    show : true,
                    random:1
                }
            }
        })
    </script>
</body>
</html>

三、vue中的计算属性和监听器

计算属性和监听器差不蛮多,计算属性其实就是监听结果,而监听器则是监听某个变量。

计算属性和监听器,现在是vue实例对象形参对象中的又一属性了,和el以及data平级。

里面放的都是函数,函数名就是监听的对象。

给出下面这个简单的示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="/node_modules/vue/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <ul>
            <li>
                西游记:价格{{xyjPrice}},数量:<input type="number" v-model="xyjNum">
            </li>
            <li>
                水浒传:价格{{shzPrice}},数量:<input type="number" v-model="shzNum">
            </li>
            <li>
                总价:价格{{zongPrice}}
            </li>
            {{msg}}
        </ul>
    </div>
    <script>
        let vm = new Vue({
            el : "#app",
            data(){
                return{
                    xyjPrice:29.14,
                    shzPrice:43.53,
                    xyjNum:1,
                    shzNum:1,
                    msg:""
                }
            },
            //计算属性
            computed:{
                //函数名就是最后要实时计算的结果
                zongPrice(){
                    return this.xyjPrice*this.xyjNum + this.shzPrice*this.shzNum;
                }
            },
            //监听器
            watch:{
                xyjNum(newVal,oldVal){
                    if(newVal>3){
                        this.msg = "西游记的库存不足";
                        this.xyjNum = 3;
                    }else{
                        this.msg = "";
                    }
                }
            }
        })
    </script>
</body>
</html>

计算属性里面有一个zongPrice名字的函数,其实就是监听zongPrice这个结果

而监听器里面则是有一个xyjNum名字的函数就是监听xyjNum值的变化,当值发生变化的时候,可以进行一段逻辑处理,比如这里对数量进行一个限制,形参可以接受两个参数,分别是新值和旧值。当然计算属性函数的返回值是一个结果,因为是“计算” 。

四、vue中的过滤器

过滤器其实就是可以对值进行转换的,比如一个经典的例子就是将使用数字表示的状态,转为对应的文字信息,之前是通过三元运算符来实现的,但是这种方式,代码是硬编码了,有代码侵入的风险,并且也不是很灵活。

下面这个例子就是转换性别:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="/node_modules/vue/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <table>
            <tr v-for="user in userList">
                <td>{{user.id}}</td>
                <td>{{user.name}}</td>
                <!-- 以前的写法 -->
                <!-- <td>{{user.gender==='1'?"男":"女"}}</td> -->
                <!-- 使用过滤器的写法 -->
                <td>{{user.gender | genderFilter}}</td>
            </tr>
        </table>
    </div>
    <script>
        //全局过滤器
        Vue.filter('genderFilter',function(gender){
            return gender==='1'?"男":"女";
        })
        var vm = new Vue({
            el : "#app",
            data(){
                return{
                    userList:[
                        {id:1,name:'Jack',gender:'1'},
                        {id:2,name:'Mary',gender:'0'}
                    ]
                }
            }
            //局部过滤器
            // filters:{
            //     genderFilter(gender){
            //         return gender==='1'?"男":"女";
            //     }
            // }
        })
    </script>
</body>
</html>

可以使用全局过滤器,以及使用局部的过滤器。

 在script标签下写上下面这样:

//全局过滤器
        Vue.filter('genderFilter',function(gender){
            return gender==='1'?"男":"女";
        })

而不是定义在Vue示例里面就是使用全局声明,之后的组件也类似。

具体怎样使用这个过滤器呢? 

<td>{{user.gender | genderFilter}}</td>

这样使用,也就是使用 | 前面放上要处理的数据,后面放上过滤器。

局部的话,就像计算属性和监听器一样,Vue示例中的属性。

//局部过滤器
            filters:{
                genderFilter(gender){
                    return gender==='1'?"男":"女";
                }
            }

 就像这样,方法名就是过滤器的名字。局部的只能在这个Vue示例所包围的范围进行使用,例如这个例子就只能在div这个标签中使用。

五、钩子函数

钩子函数其实就是关联着Vue的生命周期中的各个阶段的函数。

要知道在生命周期中大致有以下的几种状态:

1. beforeCreated:也就是Vue实例刚刚创建之前,连Model中的数据都没有填充上。是未定义的状态

2. created:刚刚创建好Vue实例,现在Model中的数据填充上了。

3. beforeMount:渲染之前,就是Model中的数据还未渲染到View视图中,此时查看视图,会发现{{name}}这样。

4. mounted:视图已经渲染好数据了,数据可以正常显示了

5. beforeUpdated:这个其实就是更新之前,就是Model中的数据已经更新了,但是这个更新还没有同步到视图里面去。

6. updated:视图中的数据也已更新。

例子:

<body>
  <div id="app">
    <span id="num">{{num}}</span>
    <button v-on:click="num++">赞!</button>
    <h2>{{name}},非常帅!!!有{{num}}个人点赞。</h2>
  </div>
</body>
<script src="/node_modules/vue/dist/vue.js"></script>
<script>
      let app = new Vue({
      el: "#app",
      data: {
      name: "张三",
      num: 100
      },
      methods: {
            show() {
                return this.name;
            },
            add() {
                this.num++;
            }
      },
      beforeCreate(){
        console.log("=========beforeCreate=============");
        console.log("数据模型未加载:" + this.name, this.num);
        console.log("方法未加载:" + this.show());
        console.log("html 模板未加载:" + document.getElementById("num"));
    },
    created: function () {
        console.log("=========created=============");
        console.log("数据模型已加载:" + this.name, this.num);
        console.log("方法已加载:" + this.show());
        console.log("html 模板已加载:" + document.getElementById("num"));
        console.log("html 模板未渲染:" + document.getElementById("num").innerText);
    },
    beforeMount() {
        console.log("=========beforeMount=============");
        console.log("html 模板未渲染:" + document.getElementById("num").innerText);
    },
    mounted() {
        console.log("=========mounted=============");
        console.log("html 模板已渲染:" + document.getElementById("num").innerText);
    },
    beforeUpdate() {
        console.log("=========beforeUpdate=============");
        console.log("数据模型已更新:" + this.num);
        console.log("html 模板未更新:" + document.getElementById("num").innerText);
    },
    updated() {
        console.log("=========updated=============");
        console.log("数据模型已更新:" + this.num);
        console.log("html 模板已更新:" + document.getElementById("num").innerText);
    }
  });
</script>

运行结果:

六、vue中组件的使用

组件其实可以看作就是一种复用的模板,就是抽取出来的,满足程序设计的高复用性的特点。

组件其实和Vue实例没有区别,只不过这里因为是要复用了,因此不能只挂载到某个界面上面,而是拿着这个组件就相当于一个独立的东西,直接可以进行显示,因此有一个模板template,然后后面的部分就和Vue实例一样了,也可以声明函数,data。

只要声明好了,直接用就行了,局部的就只能在Vue所挂载的范围进行使用,而全局则在当前页面那里都可以进行使用。

这里局部和全局和过滤器真的很像;

在Vue实例的外面写上这个:

Vue.component('rounter',{
            template:'<button @click="count++">你点了我{{count}}次,我记住了</button>',
            data(){
                return {
                    count: 0
                }
            }
        })

就代表声明了一个名为rounter的全局组件。注意组件里面的data写成函数的形式。 

那么就可以直接这样使用:

<div id="app">
        <button @click="count++">你点了我{{count}}次,我记住了</button>

        <rounter></rounter>
        <rounter></rounter>
        <rounter></rounter>
    </div>

而局部就和过滤器、计算属性、监听器一样声明一个和el以及data并行的结构,使用components这个属性,里面定义各种各样的组件。就比如下面这样:

const rounter = {
            template:'<button @click="count++">你点了我{{count}}次,我记住了</button>',
            data(){
                return {
                    count: 0
                }
            }
        };
//定义局部组件
            components:{
                rounter:rounter
            }

 完整代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="/node_modules/vue/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <button @click="count++">你点了我{{count}}次,我记住了</button>

        <rounter></rounter>
        <rounter></rounter>
        <rounter></rounter>
    </div>
    <script>
        //定义全局组件
        Vue.component('rounter',{
            template:'<button @click="count++">你点了我{{count}}次,我记住了</button>',
            data(){
                return {
                    count: 0
                }
            }
        })
        const rounter = {
            template:'<button @click="count++">你点了我{{count}}次,我记住了</button>',
            data(){
                return {
                    count: 0
                }
            }
        };
        new Vue({
            el: "#app",
            data(){
                return{
                    count:0
                }
            },
            //定义局部组件
            components:{
                rounter:rounter
            }
        })
    </script>
</body>
</html>

七、使用vue脚手架搭建前端工程以及使用elementUI来快速开发

这里的介绍在我的另外一篇博文里:

http://t.csdn.cn/ewa4h 

三、完成的进度

ES的这些新语法都写了一遍,以及Vue的各种指令还有一些计算属性、监听器、过滤器、组件这些都写了一遍例子。但是并不是一天之内完成的,断断续续的几天。在这几天中补其它文章了。

四、总结

主要就是熟悉ES的几个新的语法,以及熟悉vue的这几种基础语法。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值