IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> vue学习笔记 -> 正文阅读

[JavaScript知识库]vue学习笔记

VUE

由于笔记是从电脑上复制过来的,图片无法加载过来,故缺失了很多,如果有人看,看目录的学习路径,仅供参考

编程范式:

原生的js,jquery是命令式编程

现在的vue是声明式编程:可以做到页面和数据完全分离

在这里我想说一下,无论是前端还是后端," 约定大于配置 "是很重要的

对象里的方法称为方法,单独的称为函数

生命周期:执行一系列显示和隐式函数的过程叫做生命周期

1.1.认识语法

  • Mustache语法(又称双大括号):插值操作

    • 可以在其中写简单的表达式
    • v-once :锁定数据不更改
    • v-html:可以使用数据里的html标签
    • v-pre:禁止解析双大括号
    • v-cloak:意为斗篷,隐藏vue渲染之前的参数,在vue解析渲染之后vue自动删除这个属性
  • v-bind(对象语法):单向绑定,动态绑定属性,使标签启用解析,匹配变量

    • 语法糖:v家族语法简写的方式称为语法糖,v-bind的简写 “ : ”,v-on简写 :“@”

    • 属性里的一个大括号,是代表写入多个对象,可以用来做激活判断

    • 数组语法:灵活性较差,有单引号不会解析是字符串,没有单引号才会解析

1.2.事件监听(v-on)

在vue中,使用v-on来监听事件,其缩写为:@

<div id="app">
    <h1>{{count}}</h1>
    <button v-on:click="add">+</button>
    <button @click="sub">-</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
<script>
    const app = new Vue({
    el: '#app',
     data: {
        count: 0
     },

     methods: {
        add: function (){
            console.log("nice"),
            this.count++
        },
        sub: function (){
            console.log("nice1"),
            this.count--
        }
        }
    });

</script>

v-on的传参问题:

在事件定义时,写函数省略了小括号,但是方法本身是需要一个参数的

如果函数需要参数,但是没有传入,有小括号时,那么函数的形参为undefined

如果既没有参数,更没有小括号,那这就过分了,不过就算这么过分,也是能运行的,它会传递的时此时触发的Event

v-on的修饰符

为了防止事件冒泡,vue提供了修饰符

stop:这个事件触发后立即停止,不触发其他事件

prevent:阻止默认事件,自定义提交事件

input:监听用户输入的事件

keyup / keydown:监听键盘的点击事件

once:只触发一次的回调

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

</head>
<body>

<div id="app">
    <div @click="divClick">div按钮</div>
    <button @click.stop="btnClick">按钮</button>
    <form action="submit" >
        <input type="submit" value="提交" @click.prevent="submitClick">
        <input type="text" value="键盘事件" @keyup="submitClick">
        <input type="text" value="键盘事件" @keyup.enter="submitClick">
        <input type="text" value="键盘事件" @click.once="submitClick">
    </form>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
<script>

    var vm = new Vue({
        el: "#app",
        data:{
            message: 'hello'
        },
        methods: {
            btnClick(){
                console.log("btnclick");
            },
            divClick(){
                console.log("divClick");
            },
            submitClick(){
                console.log("subClick");
            }
        }

    });
</script>
</body>
</html>

1.3.计算属性(computed)

计算属性在去名字时不要带有动词


? 把原有的属性通过某种方式显示出来,这个过程叫做计算属性,且计算属性虽然写法是函数,但放在computed里就成了属性,调用时并不需要加小括号

? 计算属性与methods区别:

计算属性在多次调用中只调用一次,拥有缓存,methods调用几次就执行几次,没有缓存

get和set方法

计算属性一般没有set方法,是只读属性

<div id="app">
<h1>{{fullName}}</h1>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            movies: ['nice','one','power','electirc'],
            isActvie: true,
            btnindex: 0,
            onesie: 13
        },
       computed: {
            fullName: {
                get: function (){
                    return this.btnindex+' '+this.onesie
                }
            }
       }
    });
</script>

------只读的话,可以这样写,get可以省略
  computed: {
                fullName: function (){
                    return this.btnindex+' '+this.onesie
                }
       }

1.4.条件判断

v-if ------------- v-else-if --------------v-else

不必多写了吧,看到这个没反应过来,就重学吧

为了避免服用,可以加入表示,key

key:作为标识,标识一样时可复用,标识不一样,表示不可复用

<div id="app">
 <span v-if="isActvie">
     <label for="username">用户账号</label>
     <input id="username" type="text" placeholder="用户账号" key="username">
 </span>
    <span v-else>
     <label for="useremail">用户邮箱</label>
     <input id="useremail" type="text" placeholder="用户邮箱" key="usercode">
 </span>
    <button type="button" @click="isActvie=!isActvie">切换类型</button>
</div>

v-show

v-if:当条件为false时,包含v-if指令的元素,不存在于dom中,被删掉,切换一次使用这个

v-show:当条件为false时,v-show只是给我们的元素添加一个行内样式:display:none,切换频繁时使用这个

ES6

2.1.块级作用域

let比var更优秀的地方,就在于块级作用域

var作用域没有限制,会造成程序的执行是无序的

let是ES6开始才诞生的,在ES6之前,只存在var

2.2.const

建议:在ES6开发中,优先使用const,只有需要改变某一个标识符的时候才使用let

const修饰的标识符不能进行修改

用const定义标识符时,必须进行赋值

常量的含义是指向的对象不能修改,但是可以改变对象内部的属性
const ob={
    name: wang,
    age: 18
},
      ob.name=zhang,
      ob.age=20

2.3.ES6增强写法

//1. 属性的增强写法
const name = 'why';
const age = 18;
const obj = (
  name,
  age
)
//2.函数的增强写法
const obj1={
    run(){

    },
    eat(){
            
    }
}

循环遍历

在遍历的时候,小括号内,遍历的属性越重要就越靠前

官方推荐我们在使用v-for时,给对应的元素或组件添加上一个:key属性

v-for遍历数组

v-for="item in items " //无使用下标值

v-for = “(item,index) in items” //获取下标值

v-for遍历对象

v-for=“item in info”

//在遍历对象的过程中,如果只是获取一个值,那么获取到的是value

v-for = “(item,key,index) in items”

//获取value和key和下标

v-for绑定key(diff算法):

v-for使用时需要绑定key,是为了更高效的更新虚拟DOM

有key是单向排序,即插入,无key是重构双向排序,即排序迭代直到把位置迭对

< v-for=“item in items” :key=“item”>

能做到响应式的一些方法:
push() / pop() / shift() / unshift() / splice() / sort()

注意:通过索引值修改属性并不是响应式,vue并没有监听这种方式改变数组

可变参数:可以传n个参数

function(…items){

}

function(…items:T[]){

}

for (let  in this.books)
//in型遍历,遍历的是对象,只能遍历下一级对象的个数,不能越级遍历对象的数据

for (let i of this.books) {
                totalPrice += i.price * i.count
            }
//of形遍历,遍历的是数组,能遍历出数组中的数据,不过比较迟性能

高阶函数的使用

for循环高阶函数的使用(filer的使用)

加入了回调函数

回调函数返回的是boolean类型

如果为true,就会创建空间加入数组里

Map函数的使用

对数组里的每个数进行遍历,并创建空间赋值给数组

Reduce函数的使用

至少需要传两个值,第一个需要是函数,第二个传初始化值,初始化值一般为0

对所有数据进行同一操作

与其说是汇总,不如说是根据已有的参数返回一个表达式吧

回调函数里,第一个参数是初始化的值,第二个参数是数组里的数据

高级用法

filter,筛选条件的函数-》Map,映射数据改变的函数-》reduce,使用函数表达式的函数,我悟了,函数式编程

大师,我又悟了,原来箭头函数省略了写function的步骤

箭头函数是简写的匿名函数

箭头函数this指向是父函数的this指向

表单绑定v-model—双向绑定

radio表单类型的结合

没有v-model的情况下,需要添加name,且name的值是一样的,才会互斥,表单提交是将name作为key提交的

checkbox选框类型的结合
select类型的结合

值绑定

v-model修饰符的使用

lazy:懒加载,作用是延迟加载,例如,input鼠标离开框里面后,不在有选中,失去焦点,才会加载

number:input里限定输入类型为数字类型

trim:如果首尾有很多空格,通常我们希望将其去除,可以使用trim修饰符可以过滤内容左右两边的空格

组件的使用

<div id="app">
<!--    复用组件-->
    <my-cpn></my-cpn>
</div>
//组件内容,记得放在 漂`` 里面

<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
<script>
    //创建组件构造器对象
    const cpnC=Vue.extend({
    template: `<div>
    <h2>hello</h2>
    </div>`

    });
//注册组件(全局组件,可以在多个vue实例下使用)
    Vue.component('my-cpn',cpnC);

    var vm = new Vue({

        el: "#app",
        data:{
            message: "hello,vue"
    },
        components: {    //在这里面注册的组件为局部组件,只能在一个实例中使用
            cpn: cpnC  //cpn是使用组件时的标签名
        }
    });
</script>

父组件与子组件

子组件只能通过父组件使用,不可以单独使用

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

</head>
<body>

<div id="app">
    <cpn2></cpn2>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
<script>
    //创建第二个组件构造器
    const cpnC1 = Vue.extend({
        template: `
            <div>
                <h2>我是标题</h2>
                <p>2333</p>
            </div>
        `
    });
     const cpnC2 = Vue.extend({//父组件
        template: `
            <div>
                <h2>我是标题</h2>
                <p>qwq</p>
            <cpn1></cpn1>  //子组件
            </div>
        `,
         components: {    //在这里面注册的组件为局部组件,只能在一个实例中使用
             cpn1: cpnC1,  //cpn1是使用组件时的标签名
         }
    });

    var vm = new Vue({
        el: "#app",
        data: {
            message: 'how are you',
        },
        components: {    //在这里面注册的组件为局部组件,只能在一个实例中使用
            cpn2: cpnC2  //cpn2是使用组件时的标签名
        }
    });
</script>
</body>
</html>

组件的语法糖注册方式与分离写法

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>Title</title></head><body><div id="app">    <cpn></cpn>    <cpn2></cpn2></div><script type="text/x-handlebars-template"  id="cpn">    <div>        <h2>我是标题</h2>        <p>维生素哈哈哈</p>    </div></script>//可以换成template<script src="https://cdn.jsdelivr.net/npm/vue@2"></script><script><!--    语法糖的分离注册写法-->    Vue.component('cpn',{        template: '#cpn'    });<!--    语法糖全局注册,内部帮助做了extend-->    // Vue.component('cpn1',{    //     template: `    //         <div>    //             <h2>我是标题</h2>    //             <p>2333</p>    //         </div>    //     `    // })    //创建第二个组件构造器    // const cpnC1 = Vue.extend();    var vm = new Vue({        el: "#app",        data: {            message: 'how are you',        },        components: {            //语法糖局部注册            'cpn2': {                template: `            <div>                <h2>我是标题</h2>                <p>2333</p>            </div>        `            }        }    });</script></body></html>

组件的data必须是函数,不能访问vue实例

组件是一个单独功能模块的封装

  • 这个模块有属于自己的html模块,也应该有属于自己的数据data,且也是避免vue实例过于臃肿

组件自己的数据应有一个data属性,这个data属性为函数

这个函数返回一个对象,对象内部保存着数据

  <div>        <h2>{{abc}}</h2>        <p>维生素哈哈哈</p>    </div></template><script src="https://cdn.jsdelivr.net/npm/vue@2"></script><script><!--    语法糖的分离注册写法-->    Vue.component('cpn',{        template: '#cpn',        data() {            return {                title: 'abc',            }        }    });

使用data函数的原因是,避免多个模块指向同一个对象,指向同一个内存地址,因此使用data函数,在每次使用时创建一个新的对象

<div id="app">    <cpn></cpn></div><template id="cpn">    <div>        <h2>当前计数: {{counter}}</h2>     <button @click="increment">+</button>     <button @click="decrement">-</button>    </div></template><script src="https://cdn.jsdelivr.net/npm/vue@2"></script><script><!--    语法糖的分离注册写法-->    Vue.component('cpn',{        template: '#cpn',        data() {            return {                counter: 0,            }        },        methods: {            increment(){                this.counter++;            },            decrement(){                this.counter--;            }        }    });    var vm = new Vue({        el: "#app",        data: {            message: 'how are you',        }    });</script>

父子组件的通信

Vue官方提到:
父组件通过props向子组件传递数据

? 子组件通过事件向父组件发送消息

两者本质其实一样

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>Title</title></head><body><div id="app">    <cpn :cmovies="movies" :cmesssage="message"></cpn></div><template id="cpn">    <div>        <ul>            <li v-for="item in cmovies">{{item}}</li>        </ul>        <p>{{cmovies}}</p>        <h2>{{cmesssage}}</h2>    </div></template><script src="https://cdn.jsdelivr.net/npm/vue@2"></script><script>    const cpn ={        template: '#cpn',        // props: ['cmovies','cmesssage'],        props: {            //类型限制         //   cmovies: Array, //要求传过来的是数组         // cmesssage: String  //要求传过来的是string            //提供一些默认值            cmesssage: {                type: String,                default: 'aaaa',                required: true  //这个作用时,使用这个组件,这个属性比传,不穿就报错            },            cmovies: {                //类型是对象或者数组时,默认值必须是一个函数                type: Array,                default(){                    return []                }            }        },        data(){            return{}        },    }    var vm = new Vue({        el: "#app",        data: {            message: 'how are you',            movies: ['海王','哪吒重生']        },        components: {            cpn        }    });</script></body></html>

父传子过程中props的驼峰命名

在传递过程中props的驼峰标识,使用起来很蛋疼,绑定的时候需要用横杠隔开大小写,再把大写写为小写

因此,极度不建议在传递过程中用驼峰命名props

子传父自定义事件($emit)

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>Title</title></head><body><!--父组件模板--><div id="app"><!--    这个参数可加可不加,因为它的传递是通过其它方式--><cpn @itemclick="cpnClick(item)"></cpn></div><!--子组件模板--><template id="cpn">    <div>    <button v-for="item in categories" @click="btnClick(item)">{{item.name}}</button>    </div></template><script src="https://cdn.jsdelivr.net/npm/vue@2"></script><script>    const cpn ={        template: '#cpn',        data(){            return{                categories: [                    {id: 'aaa', name: '热门推荐'},                    {id: 'bb', name: '手机数码'},                    {id: 'ccc', name: '家用家电'},                    {id: 'ddd', name: '电脑办公'},                ]            }        },        methods: {            btnClick(item){                this.$emit('itemclick',item)//发射itemclick事件,避免使用驼峰            }        }    }    var vm = new Vue({        el: "#app",        data: {            message: 'how are you',            movies: ['海王','哪吒重生']        },        components: {            cpn        },        methods: {            cpnClick(item){                console.log('cpnClick');            }        }    });</script></body></html>

组件化开发

如果需要改变组件里的props值,需要通过计算属性或数据集创建一个同样的属性来绑定,用于同步更改

父子组件的访问方式

------父访问子: $children 或 $refs (来源于reference引用)

一般使用refs,因为refs指定的属性,而children是用下标来索引的,下标容易改变,因此一般使用refs

children一般用于访问全部子组件时使用的

------子访问父:$parent

插槽(slot)

组件的插槽是为了让我们封装的组件更加具有扩展性

结构一样,内容不一样一般就使用插槽

  1. 插槽的基本使用

  2. 插槽的默认值使用

  3. 如果有多个值,同时放入到组件进行替换时,一起作为替换元素

    具名插槽

    指定插槽需要插入的类型

    <div id="app">  <cpn><span>标题</span></cpn>  <cpn><span slot="left">标题</span></cpn></div><template id="cpn">    <div>        <slot name="left">left</slot>        <slot name="right">right</slot>    </div></template>
    

作用域插槽的使用

官方准则:父组件模板的所有东西都会在父级作用域内编译;子组件模板的所有东西都会在子级作用域内编译

总结:父组件替换插槽的标签,但是内容由子组件来提供

slot-scope是引用插槽的关键字

<div id="app"> <cpn>     <!--         取到template的插槽对象--><!--     这个template可以改其它名字,slot-scope存在就行,使用template只是为了低版本的vue支持这种写法-->     <template slot-scope="slot">         <span v-for="item in slot.aabb">{{item}}  -- </span>     </template> </cpn>    <cpn>        <template slot-scope="slot"><!--            使用join函数分割字符串-->            <span>{{slot.aabb.join(' - ')}}</span>            <!--         取到template的data-->        </template>    </cpn></div><template id="cpn">    <div>        <slot :aabb="pLanguages">            <ul>                <li v-for="item in pLanguages">{{item}}</li>            </ul>        </slot>    </div></template><script src="https://cdn.jsdelivr.net/npm/vue@2"></script><script>    const vm = new Vue({        el: "#app",        data:{            message: ["YND","adsf",'adc']    },        components: {            cpn : {                template: '#cpn ',                data(){                    return{                        pLanguages: ['Js','C#']                    }                },                // create(){                //     this.pLanguages.join(' --- ')                // //    把数组转换成字符串,多个字符串之间以一个符号连接                // }        }        }    });

模块化开发,第二阶段

ajax这种东西,学前端学到通信就可以了,之后转战vue的,对于后端来说,学习vue就行了,ajax对ta侧重后端来说,狗都不学

原生js真是太傻了,各自干涉,耦合性太高,如果使用匿名闭包,又无法复用,模块化才是趋势,而基于模块化诞生的vue做到的不只是前后端分离,还做到了页面工程分离

CommonJs了解

这个用的不多,基本用ES6

使用export 和 require 是为了解析语法

ES6模块化

使用的时候加入module,就会以模块的形式编译

模块与模块之间不能直接使用其它模块的东西

这个东西要注意以下,导入的后缀不要少,因为idea默认跨域请求,

这个写法是简单写法,有漏洞

//导出方式一:export{flag,sum}//导出方式二export var num = 1000;export var height = 1.88
//导出方式三// 导出函数,或者当成对象放进去export function mul(num1,num2){    return num1 + num2}// 导出类export class Person{}
//导出方式四  import defaultconst address = ' 地址'export dafault address//这种导出方式是默认的,且导入的名字是用户自定义的,且不需要大括号//这种导出方式默认只能有一个///imoprt addr from './*'
//导入方式,全部导入
import * as a form './*'
a.flag  //通过这种方式拿对象

WebPack

从本质上来说,Webpack是一个现代的JS应用的静态模块打包工具

总结以下,两个关键词:模块 和 打包

通过webpack做底层支持了多种模块化方案

webpack:万物皆可模块

gulp(做了解):

gulp的核心是Task,可以配置一系列task,并且定义task要处理的事务(例如ES6,ts转换,图片压缩,scss转成css)

之后让gulp来依次执行这些task,而且让整个流程自动化

所以gulp也被称为前端自动化任务管理工具

webpack安装

  1. 安装webpack需要先安装node.js

  2. 全局安装webpack,先指定3.6.0版本,因为vue cli2依赖于这个版本以上

    npm install webpack@5.48.0 -g

    这里我用的版本比较新,用这个没问题

  3. 局部安装webpack

    npm install webpack@5.48.0 --save-dev

    –save-dev 是开发时依赖,项目打包后不需要继续使用

  4. 为什么全局安装后,还需要局部安装?

    • 在终端执行webpack命令,使用的全局安装webpack
    • 当在package.json中定义了sripts时,其中包含了webpack命令,那么使用的是局部webpack

dist 和 src目录,dist放打包的东西,src放工程代码

打包指令:

webpack src/main.js dist/bundle.js

//从node的包里面找这个路径
const  path = require('path')

moudule.exports = {
    entries: './src/main.js',
    output: {
        //需要动态获取路径,使用函数拼接地址,dirname是全局变量,无需自己定义,这个变量保存的是当前文件所在的路径
        path: path.resolve(__dirname,'dist'),
        filename: 'bundle.js'
    }
}

loader

loader是webpack中的核心概念

https://webpack.js.org/loaders/css-loader/#root

使用多个loader时,从右向左读

import css from "./src/css/normal.css";
//从node的包里面找这个路径
const  path = require('path');

module.exports = {
    entry: './src/main.js',
    output: {
        //需要动态获取路径,使用函数拼接地址,dirname是全局变量,无需自己定义,这个变量保存的是当前文件所在的路径
        path: path.resolve(__dirname,'dist'),
        filename: 'bundle.js'
    },
    module: {
        rules: [
            {
                test: /\.css$/i,
                use: ["style-loader", "css-loader"],
            },
        ],
    },
}
  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-09-24 10:26:52  更:2021-09-24 10:30:07 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/18 23:11:50-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码