谷粒商城前端笔记

article/2025/9/13 20:37:13

前端笔记

JavaScript

ES6

ECMAScript6.0(以下简称ES6,ECMAScript是一种由Ecma国际通过ECMA-262标准化的脚本),是JavaScript语言的下一代标准,2015年6月正式发布,从ES6开始的版本号采用年号,如

ES2015,就是ES6。
ES2016,就是ES7。
ES2017,就是ES8。
ECMAScript是规范,JS的规范的具体实现。

声明变量的方式

  • 如果我们在一个大括号体中声明变量,那么let声明的变量不会作用到{}外,var声明的变量则会越域跳到{}外
  • var可以多次声明同一变量,而let则会报错
  • var定义的变量在定义之前可以使用,let定义的变量在定义之前不可使用。(变量提升问题)
<script>// var 声明的变量往往会越域// let 声明的变量有严格局部作用域{var a = 1;let b = 2;}console.log(a);  // 1console.log(b);  // ReferenceError: b is not defined// var声明的变量可以声明多次// let声明的变量只能声明一次var m = 1var m = 2let n = 3let n = 4console.log(m)  // 2console.log(n)  // Identifier 'n' has already been declared// var声明的变量会变量提升// let声明的变量不存在变量提升console.log(x);  // undefinedvar x = 10;console.log(y);   //ReferenceError: y is not definedlet y = 20;// 1. const声明的变量声明之后不允许改变// 2.onst声明的变量一但声明必须初始化,否则会报错const a = 1;a = 3; //Uncaught TypeError: Assignment to constant variable.</script>

解构表达式

  • 支持let arr = [1,2,3]; let [a,b,c] = arr;这种语法
  • 支持对象解析:const { name: abc, age, language } = person; 冒号代表改名,旧:新
  • 字符串函数
  • 支持一个字符串为多行``
  • 占位符功能 ${}
<script>//数组解构let arr = [1,2,3];// let a = arr[0];// let b = arr[1];// let c = arr[2];这种写法太过麻烦let [a,b,c] = arr;//需要俺顺序声明数组元素const person = {name: "jack",age: 21,language: ['java', 'js', 'css']}// const name = person.name;// const age = person.age;// const language = person.language;一样过于麻烦//对象解构:声明了abc、age、language三个变量,默认变量顺序就是person中的属性顺序,如果不同名需要手动表明声明的变量所对应的对象的属性const { name: abc, age, language } = person;//字符串扩展let str = "hello.vue";console.log(str.startsWith("hello"));//trueconsole.log(str.endsWith(".vue"));//trueconsole.log(str.includes("e"));//trueconsole.log(str.includes("hello"));//true//字符串模板 ``可以定义多行字符串let ss = `<div><span>hello world<span></div>`;function fun() {return "这是一个函数"}//字符串插入变量和表达式。变量名写在 ${} 中,${} 中可以放入 JavaScript 表达式。 ${}就相当于是一个占位符let info = `我是${abc},今年${age + 10}了, 我想说: ${fun()}`;
</script>

函数优化

支持函数形参默认值 function add2(a, b = 1) {
支持不定参数 function fun(…values) {
支持箭头函数 var print = obj => console.log(obj);
箭头函数+结构 var hello2 = **({name}) => console.log(“hello,” +name);**本来应该是person.name

<script>//在ES6以前,我们无法给一个函数参数设置默认值,只能采用变通写法:function add(a, b) {// 判断b是否为空,为空就给默认值1b = b || 1;return a + b;}//现在可以直接给参数写上默认值,没传就会自动使用默认值function add2(a, b = 1) {return a + b;}//不定参数function fun(...values) {console.log(values.length)}fun(1, 2)      //2fun(1, 2, 3, 4)  //4//箭头函数(lambda)//以前声明一个方法// var print = function (obj) {//     console.log(obj);// }现在则可以简化语法var print = obj => console.log(obj);//箭头前面是参数,箭头表示传入,箭头后是方法体,整体意思就是把参数传入方法体var sum = (a, b) => a + b;//箭头后的内容会自动返回 var sum2 = function (a, b) {c = a + b;return a + c;}//下面是箭头函数简化写法var sum2 = (a, b) => {c = a + b;return a + c;}const person = {name: "jack",age: 21,language: ['java', 'js', 'css']}function hello(person) {console.log("hello," + person.name)}//箭头函数+解构//这里的{name}表示取传入参数的name属性var hello2 = ({name}) => console.log("hello," +name);</script>

对象优化

可以使用Object.keys()/values/entries方法获取对象的键值对(属性名/值)等信息
Object.assgn(target,source1,source2) 合并传入参数的变量
如果属性名和属性值的变量名相同,可以省略const person2 = { age, name } 代表age属性的值是变量age的值
…代表取出该对象所有属性拷贝到当前对象。let someone = { …p1 }

<script>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 };// 合并Object.assign(target, source1, source2);//{a:1,b:2,c:3}//声明对象简写const age = 23const name = "张三"const person1 = { age: age, name: name }冒号前为要赋值的变量名,冒号后为当前声明对象的属性名// 等价于const person2 = { age, name }//如果要声明对象的属性名和要赋值对象的属性名相等则声明对象可以简写//对象的函数属性简写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);}}//对象拓展运算符// 1、拷贝对象(深拷贝)let p1 = { name: "Amy", age: 15 }let someone = { ...p1 }//意思就是把p1对象的属性全部拷贝给someone变量//合并对象let age1 = { age: 15 }let name1 = { name: "Amy" }let p2 = {name:"zhangsan"}p2 = { ...age1, ...name1 } //单个对象的属性可以拷贝,多个也可以且会进行合并(到一个变量上),属性值采取就近原则
</script>

map和reduce

map():接收一个函数,将原数组中的所有元素用这个函数处理后放入新数组返回。
reduce() :为数组中的每一个元素依次执行回调函数,不包括数组中被删除或从未被赋值的元素。


/**1、previousValue (上一次调用回调返回的值,或者是提供的初始值(initialValue))2、currentValue (数组中当前被处理的元素)3、index (当前元素在数组中的索引)4、array (调用 reduce 的数组)*/
<script>//数组中新增了map和reduce方法。let arr = ['1', '20', '-5', '3'];//map():接收一个函数,将原数组中的所有元素用这个函数处理后放入新数组返回。//  arr = arr.map((item)=>{//     return item*2//  });arr = arr.map(item=> item*2);//这里传入的函数使用了箭头函数进行函数简化了,结果为[2, 40, -10, 6]//reduce() 函数为数组中的每一个元素依次执行回调函数,不包括数组中被删除或从未被赋值的元素,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);//结果为上一次处理后:100(这是我们设置的初始值),当前正在处理:2,上一次处理后:102,当前正在处理:40,上一次处理后:142,当前正在处理:-10,上一次处理后:132,当前正在处理:6到这里就执行完了result结果为138
</script>

promise

promise对象可以优化异步操作,比如封装ajax异步操作。

<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);//     }// });//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) => { //成功以后干什么,这是最后一步了,所以不需要在返回promise对象了//     console.log("上一步的结果", data)//     $.ajax({//         url: `mock/corse_score_${data.id}.json`,//         success: function (data) {//             console.log("查询课程得分成功:", data)//         },//         error: function (err) {//         }//     });// })function get(url) { //自己定义一个方法整合一下return new Promise((resolve, reject) => {$.ajax({url: url,success: function (data) {resolve(data);},error: function (err) {reject(err)}})});}get("mock/user.json").then((data) => {//then方法只有在上一步promise对象中的函数成功之后(也就是上一步进入了success: function (data) {}这个方法体中这里才会执行then方法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方法只有在上一步promise对象中的函数失败之后(上一步进入了error方法)才会执行console.log("出现异常",err)});</script>

promise小总结: 以前嵌套ajax的时候很繁琐。现在使用promise就很方便了,步骤如下:

  • 把Ajax封装到Promise中,赋值给let p
  • 在Ajax中成功使用resolve(data),失败使用reject(err)
  • p.then().catch()

模块化import/export

模块化就是把代码进行拆分,方便重复利用。类似于java中的导包,而JS换了个概念,是导模块。

模块功能主要有两个命令构成 export 和import

  • export用于规定模块的对外接口
  • import用于导入其他模块提供的功能
#user.js
var name = "jack"
var age = 21
function add(a,b){return a + b;
}
// 导出变量和函数
export {name,age,add}#hello.js
// export const util = {
//     sum(a, b) {
//         return a + b;
//     }
// }
// 如果我们导出时使用了default作为变量名,则导出后,别的模块想引用这个导出的变量可以重命名这个default变量
export default {sum(a, b) {return a + b;}
}
//`export`不仅可以导出对象,一切JS变量都可以导出。比如:基本类型变量、函数、数组、对象。#main.js
import abc from "./hello.js"
import {name,add} from "./user.js"
//引入后我们就可以直接进行使用这些变量
abc.sum(1,2);//这个abc就是对函数变量default的重命名
console.log(name);
add(1,3);

Vue

MVVM思想

M: model 包括数据和一些基本操作
V: view 视图,页面渲染结果
View-model:模型与视图间的双向操作(无需开发人员干涉)
视图和数据通过VM绑定起来,model里有变化会自动地通过Directives填写到视图view中,视图表单中添加了内容也会自动地通过DOM Listeners保存到模型中。即只要我们Model发生了改变,View上自然就会把改变的内容表现出来。
当用户修改了View,Model中的数据也会跟着改变。使用MVVM是开发人员从烦琐的D0M操作中解放出来,把关注点放在如何操作Model数据上。

Vue的初步使用:

使用步骤:

  • 首先创建出vue实例(new vue()),然后在括号里面传入跟这个vue实例有关的数据,比如其关联的哪个页面的模板,然后是关联模板的相关信息需要声明出来如关联数据(data),关联方法(methods)。
  • 在dom中想使用vue中的model数据信息可以使用两对大括号{{},其代表从model数据模型中放到view视图中
  • v-model实现双向绑定,即model和view的改变对双方都是可见的。
<body><div id="app"><input type="text" v-model="num">v-model实现双向绑定。此处代表输入框和vue里的data绑定<button v-on:click="num++">点赞</button>v-on:click是绑定单击事件的,可以直接声明单击事件内容,也可以绑定回调函数。<button v-on:click="cancel">取消</button><h1> {{name}} ,非常帅,有{{num}}个人为他点赞{{hello()}}</h1>h1中num属性值改变原理:num属性先从vue中拿到值填充到dom,input标签中如果改变num值,vue实例则会更新,然后此处也更新</div><!-- 导入依赖 --><script src="./node_modules/vue/dist/vue.js"></script><script>//1、vue声明式渲染let vm = new Vue({ //生成vue对象el: "#app",//绑定元素 div id="app",也可以指定标签,但是不可以指定body标签data: {  //封装数据name: "张三",  // 也可以使用{} //表单中可以取出num: 1},methods:{  //封装方法cancel(){this.num -- ;},hello(){return "1"}}});</script>
</body>

在vue中其指令都以v-开头。

v-text、v-html

{{}}:<div>123{{}}</div>这种写法叫插值表达式也就是说大括号里面是表达式(其支持js语法),可以计算,可以取值,可以调用js内置函数。但是这个表达式必须有返回结果!插值表达式也可以直接获取Vue实例中定义的数据或者函数。

插值闪烁: 使用{{}}方式在网速较慢时会出现问题。在数据未加载完成时,页面会显示出原始的{{}},加载完毕后才显示正确数据,我们称为插值闪烁。v-html 和v-text命令能解决这个问题。

<body><div id="app"><span v-html="msg"></span>//v-html命令作用是把内容用html语法解析之后内容表示出来 <br/><span v-text="msg"></span>//v-text命令作用是把内容以text的形式表示出来,而不会把其用别的语言的语法进行解析  </div><script src="../node_modules/vue/dist/vue.js"></script><script>new Vue({el:"#app",data:{msg:"<h1>Hello</h1>",link:"http://www.baidu.com"},methods:{hello(){return "World"}}})</script>
</body>

v-bind

但是插值表达式只能用在标签体里(

标签内> 标签体
),不能用在标签内。,如果我们这么用 是不起作用的,所以需要 这种用法。

v-bind:可以简写为:。冒号后为要绑定的属性名,表示把model绑定到view(它是单向绑定),比如可以设置src、title、class等。

而且我们可以在浏览器里把link的属性值进行修改,那么dom里的链接地址也会进行改变。

class里有哪些内容可以通过vue数据的bool值添加删除,而在style属性中属性值的形式是k:v值,所以可以直接对value进行修改来达到修改具体样式的目的。

<body><!-- 给html标签的属性绑定 --><div id="app"> <a v-bind:href="link">跳转</a><!-- class,style  {class名:vue值}--><span v-bind:class="{active:isActive,'text-danger':hasError}":style="{color: color1,fontSize: size}">你好</span></div><script src="../node_modules/vue/dist/vue.js"></script><script>let vm = new Vue({el:"#app",data:{link: "http://www.baidu.com",isActive:true,hasError:true,color1:'red',size:'36px'}})</script>
</body>

v-model

v-bind是单向绑定,只能从model到view。而v-model是双向绑定,不止能从model到view,还能从view到model。这个常用语用户可以修改页面内容的标签使用,如表单中的多选框,自定义组件。

<body><!-- 表单项,自定义组件 --><div id="app">精通的语言:如果是多选框,那么会把每个value值赋值给vue中vm对象的language属性<input type="checkbox" v-model="language" value="Java"> java<br/><input type="checkbox" v-model="language" value="PHP"> PHP<br/><input type="checkbox" v-model="language" value="Python"> Python<br/>选中了 {{language.join(",")}}</div><script src="../node_modules/vue/dist/vue.js"></script><script>let vm = new Vue({el:"#app",data:{language: []}})</script>
</body>

v-on

事件监听可以使用v-on指令

语法格式为:v-on:事件类型=“方法” ,可以简写成**@事件类型=“方法”**

事件冒泡:如果大小div都有单机事件,点了内部div相当于外部div也点击到了,那么两个div的单击事件会同时触发。

v-on指令可以使用.stop事件修饰符阻止事件冒泡

语法格式是v-on:事件类型.事件修饰符=“方法”

还可以绑定按键修饰符

v-on:keyup.up=“num+=2” @keyup.down=“num-=2” @click.ctrl=“num=10”

<body><div id="app"><!--事件中直接写js片段--><button v-on:click="num++">点赞</button><!--事件指定一个回调函数,必须是Vue实例中定义的函数--><button @click="cancel">取消</button><h1>有{{num}}个赞</h1><!-- 事件修饰符 -->大div<div style="border: 1px solid red;padding: 20px;" v-on:click.once="hello">这里once的意思是只会触发一次单击事件小div<div style="border: 1px solid blue;padding: 20px;" @click.stop="hello"><br /><a href="http://www.baidu.com" @click.prevent.stop="hello">去百度</a>//prevent的意思是阻止其默认事件的发生。</div></div><!-- 按键修饰符: -->绑定按键修饰符<input type="text" v-model="num" v-on:keyup.up="num+=2" @keyup.down="num-=2" @click.ctrl="num=10">			<br /></div><script src="../node_modules/vue/dist/vue.js"></script><script>new Vue({el:"#app",data:{num: 1},methods:{cancel(){this.num--;},hello(){alert("点击了")}}})</script>
</body>

v-for

可以遍历数组[]和字典{} 。

对于数组<li v-for="(item,index) in collection">in后面跟的是要遍历的集合,括号里面就是遍历出来的集合里的元素

对于字典<li v-for="(value,key,index) in Object">in后面跟的是要遍历的元素,括号里面就是遍历出来的元素里的属性

<body><div id="app"><ul><!-- 4、遍历的时候都加上:key来区分不同数据,提高vue渲染效率 --><li v-for="(user,index) in users" :key= "user.name" v-if="user.gender == ''"><!-- 1、显示user信息:v-for="item in items" -->当前索引:{{index}} ==> {{user.name}}  ==>   {{user.gender}} ==>{{user.age}} <br><!-- 2、获取数组下标:v-for="(item,index) in items" --><!-- 3、遍历对象:v-for="value in object"v-for="(value,key) in object"v-for="(value,key,index) in object" -->对象信息:<span v-for="(v,k,i) in user">{{k}}=={{v}}=={{i}};</span><!-- 4、遍历的时候都加上:key来区分不同数据,提高vue渲染效率 --></li></ul></div><script src="../node_modules/vue/dist/vue.js"></script><script>         let app = 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 }]},})</script>
</body>

v-if和v-show

在vue实例的data指定一个bool变量,然后v-show赋值即可。

show里的字符串也可以比较

if是根据表达式的真假,切换元素的显示和隐藏(操作dom元素)

区别: show的标签F12一直都在,if的标签会移除;if操作dom树对性能消耗大

<body><!-- v-if:条件判断。当得到结果为true时,所在的元素才会被渲染。v-show:当得到结果为true时,所在的元素才会被显示。 --><div id="app"><button v-on:click="show = !show">点我呀</button><!-- 1、使用v-if显示 --><h1 v-if="show">if=看到我....</h1><!-- 2、使用v-show显示 --><h1 v-show="show">show=看到我</h1></div><script src="../node_modules/vue/dist/vue.js"></script><script>let app = new Vue({el: "#app",data: {show: true}})</script>
</body>

v-else和v-else-if

<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="../node_modules/vue/dist/vue.js"></script><script>let app = new Vue({el: "#app",data: { random: 1 }})     </script>
</body>

计算属性和侦听器

计算属性computed

计算属性的属性不是具体值,而是通过一个函数计算出来的,随时变化的(只要计算属性方法体内的变量值变)

<div id="app"><p>原始字符串: {{ message }}</p><p>计算后反转字符串: {{ reversedMessage }}</p>
</div><script>var vm = new Vue({el: '#app',data: {message: 'Runoob!'},computed: {// 计算属性的 getterreversedMessage: function () {//可以简写为reversedMessage(){}// `this` 指向 vm 实例return this.message.split('').reverse().join('')}}})
</script>
<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="../node_modules/vue/dist/vue.js"></script><script>//watch可以让我们监控一个值的变化。从而做出相应的反应。new Vue({el: "#app",data: {xyjPrice: 99.98,shzPrice: 98.00,xyjNum: 1,shzNum: 1,msg: ""},computed: {totalPrice(){return this.xyjPrice*this.xyjNum + this.shzPrice*this.shzNum}},watch: {xyjNum: function(newVal,oldVal){if(newVal>=3){this.msg = "库存超出限制";this.xyjNum = 3}else{this.msg = "";}}},})</script>
</body>

监听$watch

监听属性watch,我们可以通过watch来响应数据的变化。

<div id = "app"><p style = "font-size:25px;">计数器: {{ counter }}</p><button @click = "counter++" style = "font-size:25px;">点我</button>
</div>
<script type = "text/javascript">var vm = new Vue({el: '#app',data: {counter: 1}});vm.$watch('counter', function(nval, oval) { // new oldalert('计数器值的变化 :' + oval + ' 变为 ' + nval + '!');});//这是写在Vue实例外边的写法,可以直接像computed计算属性一样写在vue实例中。写法为watch:{要监听的属性值:function(新值,旧值){方法体}}
</script>

过滤器filter

定义filter组件后,管道符后面跟具体过滤器{{user.gender | genderFilter}}表示|前面的属性值传入后面的过滤器方法,然后把过滤器方法中的处理结果进行返回,最后{{}}中展示的是过滤器方法的处理结果。

<body><!-- 过滤器常用来处理文本格式化的操作。过滤器可以用在两个地方:双花括号插值和 v-bind 表达式 --><div id="app"><ul><li v-for="user in userList">{{user.id}} ==> {{user.name}} ==> {{user.gender == 1?"男":"女"}} ==>{{user.gender | genderFilter}} ==> {{user.gender | genderFilter}}</li></ul></div><script src="../node_modules/vue/dist/vue.js"></script><script>// 全局过滤器Vue.filter("gFilter", function (val) {if (val == 1) {return "男~~~";} else {return "女~~~";}})let vm = new Vue({el: "#app",data: {userList: [{ id: 1, name: 'jacky', gender: 1 },{ id: 2, name: 'peter', gender: 0 }]},filters: { // 局部过滤器,只可以在当前vue实例中使用genderFilter(val) {if (val == 1) {return "男";} else {return "女";}}}})</script>
</body>

组件化

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

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

在vue里,所有的vue实例都是组件,组件其实也是一个vue实例,因此它在定义时也会接收:data、methods、生命周期函数等,不同的是组件不会与页面的元素绑定(所以不写el),否则就无法复用了,因此没有el属性。
但是组件渲染需要html模板,所以增加了template属性,值就是HTML模板
**data必须是一个函数,不再是一个对象。**因为我们需要复用组件,那么data如果还是一个对象的话可能这个值会出现类似多线程下的值错误一样,但我们定义成了函数之后,每次调用这个函数都会返回一个新的data。
全局组件定义完毕,任何vue实例都可以直接在HTML中通过组件名称来使用组件了
下面的html内容是在说:

  • 如果使用vue对象中的el属性指定了值为”#app”,则代表<div id="app">这个块跟下面的new Vue对象绑定
  • vue对象里如果指定了components属性,是指:标签里有子标签,'button-counter': buttonCounter代表有个组件叫buttonCounter,可以填充标签<button-counter>

全局组件

// 定义一个名为 button-counter的新全局组件
Vue.component('button-counter', {data: function () { // data是函数return {count: 0}},template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>' // 渲染的模板
})// 上面代码的意思是组件名为button-counter的html内容为template的内容,然后template中的数据要用data函数进行返回。

全局注册的组件可以用在其被注册之后的任何 (通过 new Vue) 新创建的 Vue 根实例,也包括其组件树中的所有子组件的模板中。

局部组件

局部组件需要我们像声明一个变量一样声明一个组件,然后把这个组件注册进vue实例的components属性中,这样我们就可以在vue实例绑定的dom中使用这个组件了。

注意:局部注册的组件在其子组件中不可用

<div id="app"><runoob></runoob>
</div><script>// 声明一个组件// 这个东西可以在当前文件中写,也可以importvar Child = {template: '<h1>自定义组件!</h1>'// 不定义el// 可以定义data函数data: function () { // data是函数return {count: 0}}// 创建根实例(它是使用组件的)new Vue({el: '#app',components: {// <runoob> 将只在父模板可用  别的组件如果想使用其他局部组件,必须指定'runoob': Child //局部组件在div中感应不到,所以要绑定一下,原来是就是说碰到runoob标签就替换为template内容}})
</script>

生命周期钩子函数

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

在这里插入图片描述

<body><div id="app"><span id="num">{{num}}</span><button @click="num++">赞!</button><h2>{{name}},有{{num}}个人点赞</h2></div><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);//两个undefinedconsole.log("方法未加载:" + this.show());//报错console.log("html模板未加载:" + document.getElementById("num"));//无任何显示,说明页面中并无num},//这个函数只是说明一下之后就会进行初始化阶段(creat)created: function () {console.log("=========created=============");console.log("数据模型已加载:" + this.name, this.num);//张三,100console.log("方法已加载:" + this.show());//张三console.log("html模板已加载:" + document.getElementById("num"));//返回一个SpanElementconsole.log("html模板未渲染:" + document.getElementById("num").innerText);但Span内容仍为{{num}}},//这个函数就代表着初始化阶段已经结束,vue实例的各个属性都已经赋值完毕,html模板被加载出来,但是html模板内容并未进行渲染beforeMount() {console.log("=========beforeMount=============");//console.log("html模板未渲染:" + document.getElementById("num").innerText);//},//这个函数就是代表挂载阶段即将开始mounted() {console.log("=========mounted=============");//console.log("html模板已渲染:" + document.getElementById("num").innerText);//},//这个函数表示挂载阶段已经结束,html已经被渲染过beforeUpdate() {console.log("=========beforeUpdate=============");console.log("数据模型已更新:" + this.num);//console.log("html模板未更新:" + document.getElementById("num").innerText);//},//这个函数表示即将进行更新阶段,因为已经发现数据进行更新了,接下来会把html中的数据进行同步更新updated() {console.log("=========updated=============");console.log("数据模型已更新:" + this.num);//console.log("html模板已更新:" + document.getElementById("num").innerText);//}//这个函数就是更新阶段已经结束,html模板中的数据也已经更新了});</script>
</body>

Vue.use()是用来安装插件的,我们使用user方法可以安装插件,那么之后在vue中使用这个插件就可以不用引入而直接使用这个插件了。


感谢耐心看到这里的同学,觉得文章对您有帮助的话希望同学们不要吝啬您手中的赞,动动您智慧的小手,您的认可就是我创作的动力!
之后还会勤更自己的学习笔记,感兴趣的朋友们点点关注哦。


http://chatgpt.dhexx.cn/article/fqIS1Alb.shtml

相关文章

谷粒商城-分布式基础【业务编写】

谷粒商城-分布式基础篇【环境准备】谷粒商城-分布式基础【业务编写】谷粒商城-分布式高级篇【业务编写】持续更新谷粒商城-分布式高级篇-ElasticSearch谷粒商城-分布式高级篇-分布式锁与缓存项目托管于gitee 一、三级分类 此处三级分类最起码得启动renren-fast、nacos、gate…

1. 谷粒商城架构

架构图 解析 客户通过任意客户端&#xff08;app/Web&#xff09;向服务器发送请求&#xff0c; 请求首先来到Nginx集群&#xff0c;Nginx将请求转交给Api网关&#xff08;SpringCloud Gateway&#xff09;, Api网关&#xff1a; 可以根据当前请求&#xff0c;动态路由到指…

谷粒商城详细笔记

前言 mysql安装在腾讯云 redis安装在本地虚拟机master上 运行时&#xff0c;renren-fast这个项目要到单独开个idea窗口打开。 一、项目简介 1、项目微服务架构图 微服务&#xff1a;拒绝大型单体应用&#xff0c;基于业务边界进行服务微化拆分&#xff0c;各个服务独立部…

谷粒商城之分布式基础(二)

6 商品服务 6.1 三级分类 商城的商品页面展示是一个三级分类的。有一级分类、二级分类、三级分类。这就是我们接下来要进行的操作。 6.1.1 数据库 首先我们在gulimall_pms这个数据库中的pms_category这个表下插入数据 商品三级分类SQL代码 6.1.2 查出所有分类及其子分类 1…

麦克

品牌&#xff1a;InvenSense Kingstate RS PRO 灵敏度&#xff1a;-27到-44db之间 方向性&#xff1a;全方位、单向性、噪声消除 标准操作电压&#xff1a;1.5V到3.3V均有 安装方式&#xff1a;导线、表面贴装、通孔 输出阻抗大小&#xff1a;1.8K、2.2K、200欧、350欧…

Kubeedge Beehive 模块源码分析

文章目录 概述结构Model --- 消息模型Header --- 消息头Router --- 消息路由资源操作资源类型 Context --- 上下文ModuleContext --- 模块上下文MessageContext --- 消息上下文GlobalContext --- 全局上下文方法 Channel Context数据结构方法ModuleContext 接口实现AddModuleAd…

谷粒商城简介(1~5集)

谷粒商城简介&#xff08;1~5集&#xff09; 一、项目简介 1、项目背景 1&#xff09;、电商模式 市面上有 5 种常见的电商模式 B2B、B2C、C2B、C2C、O2O&#xff1b; 1、B2B 模式 B2B (Business to Business)&#xff0c; 是指商家与商家建立的商业关系。 如&#xff1a;阿…

谷粒商城:分布式基础概念(2)

微服务 微服务架构风格&#xff0c;就像是把一个单独的应用程序开发为一套小服务&#xff0c;每个小服务运行在自 己的进程中&#xff0c;并使用轻量级机制通信&#xff0c;通常是 HTTP API。这些服务围绕业务能力来构建&#xff0c; 并通过完全自动化部署机制来独立部署。这些…

beetl,freemarker,thymeleaf对比及springboot集成

调研类型&#xff1a; Freemarker&#xff0c;Thymeleaf&#xff0c;Beetl&#xff0c;Velocity 调研方向&#xff1a; 性能&#xff0c;活跃度&#xff0c;各自优缺点&#xff0c;应用实例 2.1、性能报告&#xff1a; Jdk:1.8 Cpu: 8核12线程 Jvm : -Xms512m -Xmx512m B…

部分壳与脱壳

壳与脱壳 对网上部分壳与脱壳的摘录与总结&#xff0c;仅供参考&#xff0c;侵删 参考链接1 https://www.52pojie.cn/thread-138380-1-1.html 参考链接2 https://www.cnblogs.com/milantgh/p/3869083.html 参考链接3 http://blog.sina.com.cn/s/blog_3e28c8a5010132m6.html 壳…

谷粒商城项目学-分布式基础

项目框架图 分布式基础概念 • 微服务、注册中心、配置中心、远程调用、Feign、网关 • 2、基础开发 • SpringBoot2.0、SpringCloud、Mybatis-Plus、Vue组件化、阿里云对象存储 • 3、环境 • Vagrant、Linux、Docker、MySQL、Redis、逆向工程&人人开源 • 4、开发规范 •…

【笔记/后端】谷粒商城基础篇

目录 一、环境配置1 Docker1.1 Docker是什么&#xff1f;1.2 安装&启动1.2.1 阿里云镜像加速 1.3 安装MySQL1.4 安装Redis 2 开发环境2.1 Maven2.2 Git2.3 Node 二、创建微服务项目1 内容2 问题记录3 renren-generator 三、分布式组件1 Nacos1.1 注册中心1.2 配置中心1.2.1…

谷粒商城(二)

谷粒商城&#xff08;二&#xff09; 后台商品服务 - 三级分类1、查询1&#xff09;、接口编写2&#xff09;、树形展示三级分类数据3&#xff09;、配置网关路由1 更改前端 base 路径2 将服务注册进nacos3 网关模块配置路由4 测试 4&#xff09;、解决跨域 2、删除1&#xff0…

谷粒商城(五)

谷粒商城&#xff08;五&#xff09; 订单服务1、环境搭建1&#xff09;、页面2&#xff09;、代码 2、订单登录拦截3、订单确认页1&#xff09;、VO模型2&#xff09;、订单确认页数据查询1 接口编写2 调用远程服务 3&#xff09;、Feign远程调用丢失请求头启动服务报错解决 4…

谷粒商城(一)

谷粒商城&#xff08;一&#xff09; 1、环境搭建安装 dockerdocker 安装 mysqldocker 安装 redis安装配置 git准备工具 IDEA、VsCode从 gitee 初始化项目 2、创建微服务项目1&#xff09;、创建项目2&#xff09;、初始化数据库 3、使用人人开源搭建后台管理系统1&#xff09;…

谷粒商城:如何通过笔记复盘实现事半功倍?

前言 把谷粒商城做了一遍&#xff0c;其中遇的困难也记录了一下。将零散的笔记整理成有顺序的目录结构。方便自己回看、以及快速定位文章。特此记录、大部分在CSDN博客里边都可以搜索到。 大家想看的话也可以去这里看看&#xff1a;笔记地址传送门 后续还会继续维护这个笔记…

查壳、加壳、脱壳详细教程

查壳教程 1、打开软件后我们点击右上角的三个点&#xff0c;会弹出一个选择文件的窗口&#xff0c;我们选择要查壳的文件&#xff0c;同样也可以直接把需要查壳的软件拖到PEID页面里 2、这里拖入一个程序后出现如下信息页面 这里我们看到Borland Delphi 3.0,他不是一种壳&…

分布式项目-谷粒商城。

分布式项目一&#xff0c;分布图 二&#xff0c;环境搭建 1.安装linux 2.安装docker 1 卸载系统之前的docker sudo yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine2 设…

竞业限制是什么意思?

竞业限制是指用人单位与掌握商业秘密的职工约定在劳动合同解除或终止后的一定期限内&#xff0c;劳动者不得到有竞争关系的其他用人单位任职&#xff0c;也不得自己生产与原单位有竞争关系的同类产品或经营同类业务。 竞业限制对不同的人意义是不同的&#xff0c;比如&#xf…

所谓的1261考核法算不算是末尾淘汰?

【问题】 有无精通劳动法的老哥&#xff0c;分析一下所谓的1261考核法算不算是末尾淘汰&#xff1f; 已知最后考核的那个1会被约谈&#xff0c;连续两次都是最后就会调岗或者解除劳动合同 【解析】 算的&#xff01; 应该是“末位淘汰制” 劳动法不支持“末位淘汰制”&…