分布式基础篇3——前端开发基础知识(谷粒商城)

news2024/11/18 16:32:00

  • 前端技术对比
  • 一、ES6
    • 1、简介
    • 2、什么是 JavaScript
    • 3、ES6新特性
      • 3.1 let
      • 3.2 const
      • 3.3 解构表达式
      • 3.4 字符串扩展
      • 3.5 函数优化
      • 3.6 对象优化
      • 3.7 map 和 reduce
      • 3.8 Promise
      • 3.9 模块化
  • 二、Vue
    • 1、MVVM 思想
    • 2、Vue 简介
    • 3、Vue 入门案例
    • 4、Vue 指令
      • 插值表达式
      • v-text、v-html
      • v-bind
      • v-model
      • v-on
        • 事件修饰符
        • 按键修饰符
      • v-for
      • v-if 和 v-show
    • 5、计算属性和监听器
    • 6、过滤器
    • 7、组件
    • 8、声明周期钩子函数
    • 9、Vue模块化开发
    • 8、声明周期钩子函数
    • 9、Vue模块化开发

视频来源: 【Java项目《谷粒商城》Java架构师 | 微服务 | 大型电商项目】

前端技术对比

image-20221221160306446

一、ES6

1、简介

ECMAScript 6.0(以下简称 ES6,ECMAScript 是一种由 Ecma 国际(前身为欧洲计算机制造商协会,英文名称是 European Computer Manufacturers Association)通过 ECMA-262标准化的脚本程序设计语言) JavaScript 语言的下一代标准,已经在 2015 年 6 月正式发布了,并且从 ECMAScript 6 开始,开始采用年号来做版本。即 ECMAScript 2015,就是 ECMAScript6。它的目标,是使得 JavaScript 语言可以用来编写复杂的大型应用程序,成为企业级开发语言。每年一个新版本

2、什么是 JavaScript

ECMAScript 是浏览器脚本语言的规范,而各种我们熟知的 js 语言,如 JavaScript 则是规范的具体实现

3、ES6新特性

3.1 let

  <script>
        // var 声明的变量往往会越域 
        // let 声明的变量有严格局部作用域 
        { 
            var a = 1; 
            let b = 2; 
        }
        console.log(a); // 1 
        console.log(b); // ReferenceError: b is not defined


        // var 可以声明多次 
        // let 只能声明一次
        var m = 1 
        var m = 2 
        let n = 3
        // let n = 4 
        console.log(m) // 2 
        console.log(n) // Identifier 'n' has already been declared


        // var 会变量提升 
        // let 不存在变量提升 
        console.log(x); // undefined 
        var x = 10; 
        console.log(y); //ReferenceError: y is not defined 
        let y = 20;
    </script>

3.2 const

    <script>
        // 1. 声明之后不允许改变 
        // 2. 一但声明必须初始化,否则会报错 
        const a = 1; 
        a = 3; //Uncaught TypeError: Assignment to
    </script>

3.3 解构表达式

数组解构

    <script>
        let arr = [1,2,3]

        // 普通赋值
        // let a = arr[0]
        // let b = arr[1]
        // let c = arr[2]

        // ES6 
        const [a,b,c] = arr

        console.log(a,b,c)
    </script>

对象解构

        const person =
         { 
            name: "jack", 
            age: 21, 
            language: ['java', 'js', 'css'] 
        }

        // 普通写法
        // const name = person.name
        // const age = person.age
        // const language = person.language

        // ES6
        const {name,age,language} = person
        // 可以指定新的变量名
        const {name: aa,age,language} = person

        console.log(name,age,language) 

3.4 字符串扩展

新的字符串API

- includes():返回布尔值,表示是否找到了参数字符串。

- startsWith():返回布尔值,表示参数字符串是否在原字符串的头部。

- endsWith():返回布尔值,表示参数字符串是否在原字符串的尾部。

        // 3、几个新的字符串API
        let str = "hello.vue"; 
        console.log(str.startsWith("hello"));//true 
        console.log(str.endsWith(".vue"));//true 
        console.log(str.includes("e"));//true 
        console.log(str.includes("hello"));//true

字符串模板

模板字符串相当于加强版的字符串,用反引号 `,除了作为普通字符串,还可以用来定义多行字符串,还可以在字符串中加入变量和表达式。

        // 4、字符串模板
        let ss = 
        `
        hello
        world !!!
        `
        console.log(ss)

        // 4.1、字符串插入变量和表达式。变量名写在 ${} 中,${} 中可以放 入 JavaScript 表达式。 
        let name1 = "张三";
        let age1 = 18;
        // 4.2 ${} 调用方法
        function fun() {
            return "这是一个函数"
        }
        let info = `我是${name1},今年${age1}了, 我想说: ${fun()}`;
        console.log(info)

3.5 函数优化

(1)函数参数默认值

    <script>
        // 1、函数参数默认值

        //在 ES6 以前,我们无法给一个函数参数设置默认值,只能采用变通写法: 
        function add(a, b) {
            // 判断 b 是否为空,为空就给默认值 1 
            b = b || 1;
            return a + b;
        }
        // 传一个参数 
        console.log(add(10));


        //现在可以这么写:直接给参数写上默认值,没传就会自动使用默认值
        function add2(a, b = 1) {
            return a + b;
        }
        console.log(add2(20));

    </script>

(2)不定参数

不定参数用来表示不确定参数个数,形如,…变量名,由 …加上一个具名参数标识符组成。具名参数只能放在参数列表的最后**,并且有且只有一个不定参数**


        // 2、不定参数
        function fun(...values) {
            console.log(values.length)
        }
        fun(1, 2)      //2
        fun(1, 2, 3, 4)  //4

(3)箭头函数

类似于Java中的Lambda

        // 3、箭头函数
        // 一个参数
        var print = obj => console.log(obj)
        print(100)
        // 多个参数
        var print = (o1,o2) => console.log(o1+o2)
        print(10,20)

(4)箭头函数+解构表达式

        // 4、箭头函数 + 结构表达式
        const person = {
            name: "jack",
            age: 21,
            language: ['java', 'js', 'css']
        }

        //  普通方式
        function hello(person) {
            console.log("hello," + person.name)
        }

        // 箭头函数+解构
        var hello2 = ({name}) => console.log("hello," + name);
        hello2(person);

3.6 对象优化

(1)新增的API

ES6 给 Object 拓展了许多新的方法,如:

keys(obj):获取对象的所有 key 形成的数组

values(obj):获取对象的所有 value 形成的数组

entries(obj):获取对象的所有 key 和 value 形成的二维数组。格式:[[k1,v1],[k2,v2],...]

assign(dest, ...src) :将多个 src 对象的值 拷贝到 dest 中。(第一层为深拷贝,第二层浅拷贝)

        const person = {
            name: "jack",
            age: 21,
            language: ['java', 'js', 'css']
        }

        console.log(Object.keys(person));//["name", "age", "language"]
        console.log(Object.values(person));//["jack", 21, Array(3)]
        console.log(Object.entries(person));//[Array(2), Array(2), Array(2)]

        const target = { a: 1 };
        const source1 = { b: 2 };
        const source2 = { c: 3 };

        //{a:1,b:2,c:3}
        Object.assign(target, source1, source2);

        console.log(JSON.stringify(target));//{"a":1,"b":2,"c":3}

(2)声明对象简写

        // 2、声明对象简写
        const age = 23
        const name = "张三"
        // 普通方式
        const person1 = { age: age, name: name }
        // ES6:属性名和属性值变量名一样,可以省略
        const person2 = { age, name }
        console.log(person2);

(3)对象的函数属性简写

        // 3、对象的函数属性简写
        let person3 = {
            name: "jack",
            // 以前:
            eat: function (food) {
                console.log(this.name + "在吃" + food);
            },
            // 箭头函数this不能使用,对象.属性
            eat2: food => console.log(person3.name + "在吃" + food),
            // 常用的方式
            eat3(food) {
                console.log(this.name + "在吃" + food);
            }
        }

        person3.eat("香蕉");
        person3.eat2("苹果")
        person3.eat3("橘子");

(4)对象拓展运算符

        // 4、对象拓展运算符
        //  拷贝对象(深拷贝)
        let p1 = { name: "Amy", age: 15 }
        let someone = { ...p1 }
        console.log(someone)  //{name: "Amy", age: 15}

        //  合并对象
        let age1 = { age: 15 }
        let name1 = { name: "Amy" }
        let p2 = { name: "zhangsan" }
        p2 = { ...age1, ...name1 }
        console.log(p2) // {age: 15, name: 'Amy'}

3.7 map 和 reduce

和Java8中的Stream流使用方式一样。。

    <script>
        //数组中新增了map和reduce方法。
        //map():接收一个函数,将原数组中的所有元素用这个函数处理后放入新数组返回。
        let arr = ['1', '20', '-5', '3'];

        //  arr = arr.map((item)=>{
        //     return item*2
        //  });
        arr = arr.map(item => item * 2);
        console.log(arr);
        
        //reduce() 为数组中的每一个元素依次执行回调函数,不包括数组中被删除或从未被赋值的元素,
        //[2, 40, -10, 6]

        //arr.reduce(callback,[initialValue])
        /**
            1、previousValue (上一次调用回调返回的值,或者是提供的初始值(initialValue))
            2、currentValue (数组中当前被处理的元素)
            3、index (当前元素在数组中的索引)
            4、array (调用 reduce 的数组)
        */
        let result = arr.reduce((a, b) => {
            console.log("上一次处理后:" + a);
            console.log("当前正在处理:" + b);
            return a + b;
        }, 100);
        console.log(result)


    </script>

3.8 Promise

在 JavaScript 的世界中,所有代码都是单线程执行的。由于这个“缺陷”,导致 JavaScript 的所有网络操作,浏览器事件,都必须是异步执行。

异步执行可以用回调函数实现。一旦有一连串的 ajax 请求 a,b,c,d… 后面的请求依赖前面的请求结果,就需要层层嵌套。这种缩进和层 层嵌套的方式,非常容易造成上下文代码混乱,我们不得不非常小心翼翼处理内层函数与外 层函数的数据,一旦内层函数使用了上层函数的变量,这种混乱程度就会加剧…总之,这 种层叠上下文的层层嵌套方式,着实增加了神经的紧张程度

案例:

使用三个Json文件模拟数据,发送三次请求

  1. 查询用户

  2. 查询用户成功,查询科目

  3. 根据科目的查询结果,获取去成绩

corse_score_10.json 得分
{
    "id": 100,
    "score": 90
}

user.json 用户
{
    "id": 1,
    "name": "zhangsan",
    "password": "123456"
}


user_corse_1.json 课程
{
    "id": 10,
    "name": "chinese"
}

以前的方式

嵌套Ajax请求

 <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    <script>
         //1、查出当前用户信息
        //2、按照当前用户的id查出他的课程
        //3、按照当前课程id查出分数
        $.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);
            }
        });
    </script>

使用 Promise 之后:


        // 使用 Promise 封装异步操作
        let p = new Promise((resolve, reject) => { //传入成功解析,失败拒绝
            //1、异步操作
            $.ajax({
                url: "mock/user.json",
                success: function (data) {
                    console.log("查询用户成功:", data)
                    resolve(data);
                },
                error: function (err) {
                    reject(err);
                }
            });
        });

        p.then((obj) => { // 查询用户成功,继续查询课程
            return new Promise((resolve, reject) => {
                $.ajax({
                    url: `mock/user_corse_${obj.id}.json`,
                    success: function (data) {
                        console.log("查询用户课程成功:", data)
                        resolve(data);
                    },
                    error: function (err) {
                        reject(err)
                    }
                });
            })
        }).then((data) => { // 查询课程成功,继续查询成绩
            console.log("上一步的结果", data)
            $.ajax({
                url: `mock/corse_score_${data.id}.json`,
                success: function (data) {
                    console.log("查询课程得分成功:", data)
                },
                error: function (err) {
                }
            });
        })

封装Promise成一个方法:

        // 封装Promise成一个方法
        function get(url, data) { 
            return new Promise((resolve, reject) => {
                $.ajax({
                    url: url,
                    data: data,
                    success: function (data) {
                        resolve(data);
                    },
                    error: function (err) {
                        reject(err)
                    }
                })
            });
        }

        get("mock/user.json")
            .then((data) => {
                console.log("用户查询成功~~~:", data)
                return get(`mock/user_corse_${data.id}.json`);
            })
            .then((data) => {
                console.log("课程查询成功~~~:", data)
                return get(`mock/corse_score_${data.id}.json`);
            })
            .then((data)=>{
                console.log("课程成绩查询成功~~~:", data)
            })
            .catch((err)=>{ //失败的话catch
                console.log("出现异常",err)
            });

3.9 模块化

模块化就是把代码进行拆分,方便重复利用。类似 java 中的导包:要使用一个包,必须先导包。而 JS 中没有包的概念,换来的是 模块

模块功能主要由两个命令构成:exportimport

export命令用于规定模块的对外接口。

import命令用于导入其他模块提供的功能。

案例

提供三个 js 文件: hello.js,user.js,main.js

hello.js
const util = {
    sum(a,b) {
        return a+b
    }
}
user.js
var name = "jack"
var age = 21

在 main.js 中引用以上俩个js中的方法和属性

hello.js

// 第二种写法
//export const util = {
//     sum(a,b) {
//         return a+b
//     }
// }

// 第三种写法: 不指定名字
export default {
    sum(a, b) {
        return a + b
    }
}
//  第一种写法
// export {util}

user.js

var name = "jack"
var age = 21

export {name,age} 

main.js

//  导入 js 文件
import util from './hello.js'
import {name,age} from './user.js'

//  使用
util.sum(10,20)

二、Vue

1、MVVM 思想

  • M:即 Model,模型,包括数据和一些基本操作
  • V:即 View,视图,页面渲染结果
  • VM:即 View-Model,模型与视图间的双向操作(无需开发人员干涉)

在 MVVM 之前,开发人员从后端获取需要的数据模型,然后要通过 DOM 操作 Model 渲染到 View 中。而后当用户操作视图,我们还需要通过 DOM 获取 View 中的数据,然后同步到Model 中。

而 MVVM 中的 VM 要做的事情就是把 DOM 操作完全封装起来,开发人员不用再关心 Model和 View 之间是如何互相影响的:

  • 只要我们 Model 发生了改变,View 上自然就会表现出来。
  • 当用户修改了 View,Model 中的数据也会跟着改变。

image-20221222133942216

2、Vue 简介

Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。

官网:https://cn.vuejs.org/

Git 地址:https://github.com/vuejs

3、Vue 入门案例

Vue 三种安装方式:

  1. 直接 script 引入本地 vue 文件。需要通过官网下载 vue 文件。

  2. 通过 script 引入 CDN 代理。需要联网,生产环境可以使用这种方式

  3. 通过 npm 安装。这种方式也是官网推荐的方式,需要 nodejs 环境。

    <script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>
    <div  id="app">
        <h1>hello, {{ name }}</h1>
    </div>
    <script>
        let vm = new Vue({
            el: "#app",
            data: { 
                name: "jack"
            }
        })
    </script>

首先通过 new Vue()来创建 Vue 实例

然后构造函数接收一个对象,对象中有一些属性:

  • el:是 element 的缩写,通过 id 选中要渲染的页面元素,本例中是一个 div
  • data:数据,数据是一个对象,里面有很多属性,都可以渲染到视图中
    • name:这里我们指定了一个 name 属性

4、Vue 指令

插值表达式

格式:{{表达式}}

说明

  • 该表达式支持 JS 语法,可以调用 js 内置函数(必须有返回值)

  • 表达式必须有返回结果。例如 1 + 1,没有结果的表达式不允许使用,如:let a = 1 + 1;

  • 可以直接获取 Vue 实例中定义的数据或函数


插值表达式可能会造成 插值闪烁 的问题:

使用{{}}方式在网速较慢时会出现问题。在数据未加载完成时,页面会显示出原始的{{}}, 加载完毕后才显示正确数据,我们称为插值闪烁。

image-20221222155323616

v-text、v-html

可以使用 v-text 和 v-html 指令来替代 {{}}

说明:

  • v-text:将数据输出到元素内部,如果输出的数据有 HTML 代码,会作为普通文本输出
  • v-html:将数据输出到元素内部,如果输出的数据有 HTML
<body>
    <div id="app">
        {{msg}}
        <br>
        <span v-text="msg"></span>
        <br>
        <span v-html="msg"></span>
    </div>
    <script src="js/vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            data: {
                msg: "<h1>hello,world!!</h1>"
            }
        })
    </script>
</body>

v-bind

html 属性不能使用双大括号形式绑定,我们使用 v-bind 指令给 HTML 标签属性绑定值;而且在将 v-bind 用于 classstyle 时,Vue.js 做了专门的增强

<body>
    <div id="app">
        <!-- 为标签属性绑定值 -->
        <a v-bind:href="link">Go</a>
        
        <!-- class、style -->
        <!-- 如果 isActive为true则增加active,text-dangers也一样。 -->
        <span v-bind:class="{active:isActive,'text-dangers':hasError}">你好</span>
        <!-- style与data中的数据绑定,v-bind可省略 -->
        <span :style="{color: colors, 'font-size': size}">Style</span>
    </div>
    <script src="./js/vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            data: {
                link: 'http://www.baidu.com',
                isActive: true,
                hasError: true,
                colors: "green",
                size: "35px"
            }
        })
    </script>
</body>
  • 属性名可以用驼峰式 (camelCase) 或短横线分隔 (kebab-case,这种方式记得用单引号括起来) 来命名。
    • 例如: font-size ——> fontSize 或者 ‘font-size’
  • v-bind 可省略,使用 :style :class

v-model

刚才的 v-text、v-html、v-bind 可以看做是单向绑定,数据影响了视图渲染,但是反过来就不行。接下来学习的 v-model 是双向绑定,视图(View)和模型(Model)之间会互相影响。

既然是双向绑定,一定是在视图中可以修改数据,这样就限定了视图的元素类型。目前 v-model 的可使用元素有:

- input

- select

- textarea

- checkbox

- radio

- components(Vue 中的自定义组件)

基本上除了最后一项,其它都是表单的输入项。

<body>
    <div id="app">
        精通的语言:
        <input type="checkbox" v-model="language" value="Java">
        <input type="checkbox" v-model="language" value="C++">
        <input type="checkbox" v-model="language" value="PHP">
        <br>
        选中的语言: {{language.join(',')}}
    </div>
    <script src="js/vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            data: {
                language: []
            }
        })
    </script>
</body>

v-on

v-on 指令用于给页面元素绑定事件。

语法: v-on:事件名=“js 片段或函数名”

<body>
    <div id="app">
        <button v-on:click="num++">点赞</button>
        <!-- 也可以省略 v-on: 使用@替代 -->
        <button @click="num--">取消</button>
        <br>
        点赞数: {{num}}
    </div>
    <script src="js/vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            data: {
                num: 0
            }
        })
    </script>
</body>

事件修饰符

在事件处理程序中调用 event.preventDefault()event.stopPropagation() 是非常常见的需求。尽管我们可以在方法中轻松实现这点,但更好的方式是:方法只有纯粹的数据逻辑,而不是去处理 DOM 事件细节。

为了解决这个问题,Vue.js 为 v-on 提供了事件修饰符。修饰符是由点开头的指令后缀来表示的:

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

.prevent:阻止默认事件发生

.capture:使用事件捕获模式

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

.once:只执行一次

<body>
    <div id="app">
        <button v-on:click="num++">点赞</button>
        <!-- 也可以省略 v-on: 使用@替代 -->
        <button @click="num--">取消</button>
        <br>
        点赞数: {{num}}

        <div style="border: 1px solid red;padding: 20px;" @Click.once="hello">
            大div
            <div style="border: 1px solid green;padding: 20px;" @Click.stop="hello">
                小div
                <a href="wwww.baidu.com" @Click.prevent.stop="hello">去百度</a>
            </div>
        </div>
    </div>
    <script src="js/vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            data: {
                num: 0
            },
            methods: {
                hello(){
                    alert("点击了")
                }
            },
        })
    </script>
</body>

按键修饰符

在监听键盘事件时,我们经常需要检查常见的键值。Vue 允许为 v-on 在监听键盘事件时添加按键修饰符:

全部的按键别名:

.enter

.tab

.delete (捕获“删除”和“退格”键)

.esc

.space

.up

.down

.left

.right

<!-- 按键修饰符 -->
<input type="text" v-model="num" @keyup.enter="num+=2" @keyup.up="num+=1" @keyup.down="num-=1">

v-for

遍历数据渲染页面是非常常用的需求,Vue 中通过 v-for 指令来实现。

<body>
    <div id="app">
        <ul>
            <li v-for="(user,index) in users" ::key="index">
                {{user.name}} —— {{user.gender}} —— {{user.age}}
            </li>
        </ul>
    </div>
    <script src="../js/vue.js"></script>

    <script>
        new Vue({
            el: '#app',
            data: {
                users: [{ name: '柳岩', gender: '女', age: 21 },
                { name: '张三', gender: '男', age: 18 },
                { name: '范冰冰', gender: '女', age: 24 },
                { name: '刘亦菲', gender: '女', age: 18 },
                { name: '古力娜扎', gender: '女', age: 25 }],
                nums: [1, 2, 3, 4, 4]

            }
        })
    </script>
</body>

v-if 和 v-show

v-if,顾名思义,条件判断。当得到结果为 true 时,所在的元素才会被渲染

v-show,当得到结果为 true 时,所在的元素才会被显示

语法:v-if="布尔表达式", v-show="布尔表达式",

<body>
    <div id="app">
        <button @click="isShow = !isShow">点我呀</button><br>
        <span v-if="isShow">v-if看到我啦~~</span><br>
        <span v-show="isShow">v-show看到我啦~~</span>
    </div>
    <script src="../js/vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            data: {
                isShow: false
            }
        })
    </script>
</body>

v-else、v-else-if

相当于java中的: 

if(){

}else if(){

}else{

}
<body>
    <div id="app">
        <button v-on:click="random=Math.random()">点我呀</button>
        <span>{{random}}</span>

        <h1 v-if="random>=0.75">
            看到我啦?! &gt;= 0.75
        </h1>

        <h1 v-else-if="random>=0.5">
            看到我啦?! &gt;= 0.5
        </h1>

        <h1 v-else-if="random>=0.2">
            看到我啦?! &gt;= 0.2
        </h1>

        <h1 v-else>
            看到我啦?! &lt; 0.2
        </h1>

    </div>
    <script src="../js/vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            data: {
                random: 1
            }
        })
    </script>
</body>

5、计算属性和监听器

computed:某些结果是基于之前数据实时计算出来的,我们可以利用计算属性。

watch: 可以让我们监控一个值的变化。从而做出相应的反应

<body>
    <div id="app">
        <ul>
            <li>西游记; 价格:{{xyjPrice}},数量:<input type="number" v-model="xyjNum"> </li>
            <li>水浒传; 价格:{{shzPrice}},数量:<input type="number" v-model="shzNum"> </li> 
            <li>总价:{{totalPrice}}</li>
            {{msg}}
        </ul>
    </div>
    <script src="../js/vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            data: {
                xyjPrice: 89.9,
                shzPrice: 88.8,
                xyjNum: 0,
                shzNum: 0,
                msg: ''
            },
            //  计算属性
            computed: {
                totalPrice() {
                    return this.xyjNum * this.xyjPrice + this.shzNum * this.shzPrice;
                }
            },
            //  监听器
            watch: {
                xyjNum(newValue,oldValue) {
                    if(newValue >= 3) {
                        this.msg = '库存不足'
                        this.xyjNum = 3
                    }else{
                        this.msg = ''
                    }
                }
            }
        })
    </script>
</body>

6、过滤器

过滤器不改变真正的data,而只是改变渲染的结果,并返回过滤后的版本。在很多不同的情况下,过滤器都是有用的,比如尽可能保持 API 响应的干净,并在前端处理数据的格式。

<body>
    <div id="app">
        <ul>
            <li v-for="user in userList">
                {{user.name}} —— {{user.gender ==1?'男':'女'}} —— {{user.gender | genderFilter}}—— {{user.gender | gFilter}}
            </li>
        </ul>
    </div>
    <script src="../js/vue.js"></script>
    <script>
        //  全局过滤器
        Vue.filter('gFilter', function (val) {
            if (val == 1) {
                return '男'
            } else {
                return '女'
            }
        })
        new Vue({
            el: '#app',
            data: {
                userList: [
                    { id: 1, name: 'jacky', gender: 1 },
                    { id: 2, name: 'peter', gender: 0 }
                ]
            },
            //  局部过滤器
            filters: {
                genderFilter(val) {
                    if (val == 1) {
                        return '男'
                    } else {
                        return '女'
                    }
                }
            }
        })
    </script>
</body>

7、组件

在大型应用开发的时候,页面可以划分成很多部分。往往不同的页面,也会有相同的部分。

例如可能会有相同的头部导航。

但是如果每个页面都独自开发,这无疑增加了我们开发的成本。所以我们会把页面的不同部分拆分成独立的组件,然后在不同页面就可以共享这些组件,避免重复开发。

在 vue 里,所有的 vue 实例都是组件

image-20221223143957844

  • 组件其实也是一个 Vue 实例,因此它在定义时也会接收:data、methods、生命周期函 数等
  • 不同的是组件不会与页面的元素绑定,否则就无法复用了,因此没有 el 属性。
  • 但是组件渲染需要 html 模板,所以增加了 template 属性,值就是 HTML 模板
  • 全局组件定义完毕,任何 vue 实例都可以直接在 HTML 中通过组件名称来使用组件了
  • data 必须是一个函数,不再是一个对象。

全局组件

<body>
    <div id="app">
        <button @click="count++">点击了{{count}} 次</button>
        <!-- 使用组件 -->
        <counter></counter>
        <counter></counter>
        <counter></counter>
        
    </div>
    <script src="../js/vue.js"></script>
    <script>
        // 1、全局组件
        Vue.component('counter',{
            template: '<button @click="count++">点击了{{count}} 次</button>',
            data(){
                return {
                    count: 0 
                }
            }
        })

        new Vue({
            el: '#app',
            data: {
                count: 0
            },
        })
    </script>
</body>

局部组件

<body>
    <div id="app">
        <button @click="count++">点击了{{count}} 次</button>
        <!-- 使用组件 -->
        <counter></counter>
        <counter></counter>
        <counter></counter>
        <br>
        <button-counter></button-counter>
        <button-counter></button-counter>
    </div>
    <script src="../js/vue.js"></script>
    <script>
        // 1、全局组件
        Vue.component('counter', {
            template: '<button @click="count++">点击了{{count}} 次</button>',
            data() {
                return {
                    count: 0
                }
            }
        })

        //  2、局部组件
        const buttonCounter = {
            template: '<button @click="count++">点击了{{count}} 次</button>',
            data() {
                return {
                    count: 0
                }
            }
        }
        new Vue({
            el: '#app',
            data: {
                count: 0
            },
            // 注册组件
            components: {
                'button-counter': buttonCounter
            }
        })
    </script>
</body>

8、声明周期钩子函数

每个 Vue 实例在被创建时都要经过一系列的初始化过程 :创建实例,装载模板,渲染模 板等等。Vue 为生命周期中的每个状态都设置了钩子函数(监听函数)。每当 Vue 实例处于 不同的生命周期时,对应的函数就会被触发调用

组件生命周期图示

钩子函数

  • beforeCreated:我们在用 Vue 时都要进行实例化,因此,该函数就是在 Vue 实例化时调用,也可以将他理解为初始化函数比较方便一点,在 Vue1.0 时,这个函数的名字就是 init。
  • created:在创建实例之后进行调用。
  • beforeMount:页面加载完成,没有渲染。如:此时页面还是{{name}}
  • mounted:我们可以将他理解为原生 js 中的 window.οnlοad=function({.,.}),或许大家也在用 jquery,所以也可以理解为 jquery 中的$(document).ready(function(){….}),他的功能就是:在 dom 文档渲染完毕之后将要执行的函数,该函数在 Vue1.0 版本中名字为 compiled。 此时页面中的{{name}}已被渲染成张三
  • beforeDestroy:该函数将在销毁实例前进行调用 。
  • destroyed:改函数将在销毁实例时进行调用。
  • beforeUpdate:组件更新之前。
  • updated:组件更新之后。

9、Vue模块化开发

全局安装 webpack

npm install webpack -g

全局安装 vue 脚手架

npm install -g @vue/cli-init

初始化Vue项目

Counter = {
template: ‘<button @click=“count++”>点击了{{count}} 次’,
data() {
return {
count: 0
}
}
}
new Vue({
el: ‘#app’,
data: {
count: 0
},
// 注册组件
components: {
‘button-counter’: buttonCounter
}
})

```

8、声明周期钩子函数

每个 Vue 实例在被创建时都要经过一系列的初始化过程 :创建实例,装载模板,渲染模 板等等。Vue 为生命周期中的每个状态都设置了钩子函数(监听函数)。每当 Vue 实例处于 不同的生命周期时,对应的函数就会被触发调用

[外链图片转存中…(img-DHPfR1ez-1673086766253)]

钩子函数

  • beforeCreated:我们在用 Vue 时都要进行实例化,因此,该函数就是在 Vue 实例化时调用,也可以将他理解为初始化函数比较方便一点,在 Vue1.0 时,这个函数的名字就是 init。
  • created:在创建实例之后进行调用。
  • beforeMount:页面加载完成,没有渲染。如:此时页面还是{{name}}
  • mounted:我们可以将他理解为原生 js 中的 window.οnlοad=function({.,.}),或许大家也在用 jquery,所以也可以理解为 jquery 中的$(document).ready(function(){….}),他的功能就是:在 dom 文档渲染完毕之后将要执行的函数,该函数在 Vue1.0 版本中名字为 compiled。 此时页面中的{{name}}已被渲染成张三
  • beforeDestroy:该函数将在销毁实例前进行调用 。
  • destroyed:改函数将在销毁实例时进行调用。
  • beforeUpdate:组件更新之前。
  • updated:组件更新之后。

9、Vue模块化开发

全局安装 webpack

npm install webpack -g

全局安装 vue 脚手架

npm install -g @vue/cli-init

初始化Vue项目

vue init webpack appname

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/149340.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【CANN训练营第三季】基于昇腾PyTorch框架的模型训练调优

文章目录性能分析工具PyTorch Profiling性能分析工具CANN Profiling结业考核1、使用Pytorch实现LeNet网络的minist手写数字识别。2、采用课程中学习到的手工或者自动迁移方式&#xff0c;将上述脚本迁移到昇腾npu上&#xff0c;单机单卡&#xff0c;提供迁移脚本&#xff0c;突…

YOLOv5视觉AI库安装

打开YOLOv5开源仓库: https://github.com/ultralytics/yolov5/blob/master/README.zh-CN.md下载源码:安装 : pip install -r requirements.txt完成安装目标检测推理可通过PyTorch Hub加载YOLOv5检测模型检测图像并返回数据帧使用YOLOv5要先安装opencv-python和pandas库安装open…

C#,图像二值化(18)——全局阈值的模糊集理论算法(Huang Thresholding)与源程序

1 模糊集理论模糊集理论,也称为模糊集合论,或简单地称为模糊集,1965年美国学者扎德在数学上创立了一种描述模糊现象的方法—模糊集合论。这种方法把待考察的对象及反映它的模糊概念作为一定的模糊集合&#xff0c;建立适当的隶属函数&#xff0c;通过模糊集合的有关运算和变换&…

arduino - pinMode参数1的确定 - 以arduino nano every核心板为例

文章目录arduino - pinMode参数1的确定 - 以arduino nano every核心板为例概述笔记pins_arduino.hABX00028-datasheet.pdf简单的辨认管脚号就照ABX00028-datasheet.pdf来ENDarduino - pinMode参数1的确定 - 以arduino nano every核心板为例 概述 arduino nano every的核心板使…

我的交易抽象思路分享

这几天我老是抛出一些问题给老师们&#xff0c;都是故意而为之&#xff0c;因为我靠这种方式自己引导自己很多年&#xff1b; 比如&#xff1a;龙头真的存在么&#xff1f;为何前几天它还不是龙头&#xff0c;怎么今天就是了&#xff1f; 再如&#xff1a;交易模式和交易系统…

微信小程序解密encryptedData报错pad block corrupted

前要&#xff1a; 今天调试一下微信授权登录的时候老是第一次报错解密失败pad block corrupted&#xff0c;第二次授权的时候正常&#xff0c;因为第一次已经获取到手机号码&#xff01; 后端代码&#xff1a; public static JSONObject getUserInfo(String encryptedData, S…

微信自动回复软件

软件介绍 软件名称&#xff1a; 微信超级管家 适用平台&#xff1a; windows 是否免费&#xff1a; 完全免费 病毒检测&#xff1a; 火绒安全检测通过 流氓检测&#xff1a; 无广告、无弹窗、无其他流氓行为 软件大小&#xff1a; 183M 这个软件依赖的是本地微信客户端&#x…

C++ 初始化列表详解

目录 1.什么是初始化列表 2.什么时候需要使用初始化列表&#xff1f; 3.初始化列表的效率 4.初始化列表的初始化顺序 1.什么是初始化列表 class A { public:A(int value):m_dada(value){}private:int m_dada; }; 如上图&#xff0c;红色圈起来的部分&#xff0c;就是构造函…

MXNet的Faster R-CNN(基于区域提议网络的实时目标检测)《5》

在上一篇文章的介绍中&#xff0c;我们知道语义分割可以对图像中的每个像素进行类别预测。这节主要讲关于全卷积网络(Fully Convolutional Network,FCN)&#xff0c;实现从图像像素到像素类别的变换。 那这里的卷积神经网络跟以往的有什么不一样的地方吗? 这里的网络是通过转置…

Java中享元模式是什么/享元模式有什么用,编程如何实现,哪里用到了享元模式

继续整理记录这段时间来的收获&#xff0c;详细代码可在我的Gitee仓库SpringBoot克隆下载学习使用&#xff01; 5.8 享元模式 5.8.1 概述 运用共享技术来有效地支持大量细粒度对象的复用&#xff0c;通过共享已经存在的对象来大幅度减少需要创建的对象数量、避免大量相似对象…

图文并茂strapi 4.5.5自定义搭建指南以及数据库字段名接口返回mapping分析

strapi是什么&#xff1f; 基于Nodejs的开源免费CMS框架 为什么选择它&#xff1f; 基于nodejs,100&#xff05;JavaScript&#xff0c;上手迅速可轻松创建功能强大且可自定义的API可以使用任何喜欢的数据库 先决条件 首先你的电脑需要具备以下环境&#xff0c;再执行命令…

技术破局:程序员2023为何跳出舒适圈?

1前言今天的冬日暖阳高照&#xff0c;给我羽绒服下的肉身火一般的燥热&#xff0c;给了我一个错觉&#xff0c;以为到了阳春三月。刚刚送完老妈还有老婆孩子回老家&#xff0c;我坐到电脑机器前&#xff0c;准备捋一下思绪&#xff0c;回首2022的生活和工作。 2 2022 回顾今年用…

Linux下C/C++实现cpustat(测量CPU利用率)

在Linux中&#xff0c;cpustat定期转储正在运行的进程的当前CPU利用率统计信息。cpustat已被优化为具有最小的CPU开销&#xff0c;与top相比&#xff0c;通常使用约35%的CPU。cpustat还包括一些简单的统计分析选项&#xff0c;可以帮助描述CPU的加载方式。 cpustat介绍 cpust…

大数据概论

大数据概论大数据概论概念特点(4V)Volume(大量)Velocity(高速)Variety(多样)Value(低价值密度)应用场景发展前景部门间业务流程分析部门组织结构大数据概论 概念 大数据(BigData)&#xff0c;指无法在一定时间范围内\textcolor{Red}{无法在一定时间范围内}无法在一定时间范围…

iOS—Effective Objective—C2.0(2)

文章目录对象&#xff0c;消息&#xff0c;运行期理解“属性”概念合成与存取dynamic关键字属性特性原子性读/写权限内存管理语义方法名为什么几乎所有的属性都可以使用nonatomic&#xff1a;要点在对象的内部尽量直接访问实例变量惰性初始化&#xff1a;要点理解“对象同等性”…

2022年度总结——平凡之路

文章目录一、缘起二、回首2022三、展望2023四、结束语我是平凡的人&#xff0c;总要接受普通平凡的自己。一、缘起 我注册CSDN的时间是2021-07-25&#xff0c;这是一个值得纪念的时间。不过那时候的我并没有写博客&#xff0c;只是在CSDN游览一些文章&#xff0c;查看资料&…

一文读懂Java垃圾回收机制及算法原理万字详解

Java垃圾回收机制及算法 文章目录Java垃圾回收机制及算法垃圾回收概述垃圾回收-对象是否已死判断对象是否存活 - 引用计数算法判断对象是否存活-可达性分析算法可达性分析算法JVM之判断对象是否存活再谈引用垃圾收集算法分代收集理论标记-清除算法什么是标记-清除算法?标记-复…

读书:《卡片笔记写作法》

2023年罗胖跨年演讲时提到了一个故事&#xff0c;说Flomo的创始人有3个原则&#xff1a;一不在软件内弹广告&#xff0c;二不做永久会员&#xff0c;三不融资。我就马上试用了一下这款Flomo软件&#xff0c;然后就发现了《卡片笔记写作法》这本书。 这本书的卡片写作法来自于一…

【Qt】QtCreator新建Application项目的6类应用程序的示例

【Qt】QtCreator新建Application项目的6类应用程序的示例1、背景2、Application分类1、背景 操作系统&#xff1a;windows10专业版。 Qt版本&#xff1a;qt-opensource-windows-x86-msvc2013_64-5.7.1.exe 注意&#xff1a;安装了该exe可执行文件&#xff0c;就自动安装了qtcr…

(考研湖科大教书匠计算机网络)第一章概述-第一节:因特网概述

文章目录一&#xff1a;网络、互联网和因特网基本概念二&#xff1a;因特网发展的三个阶段三&#xff1a;ISP和基于ISP的三层结构的因特网&#xff08;1&#xff09;ISP&#xff08;2&#xff09;基于ISP的三层结构的因特网四&#xff1a;因特网的标准化工作五&#xff1a;因特…