vue

vue学习笔记整理

一、安装

1、CDN

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

2、npm

npm install vue
若报错,先执行npm init -f ,再执行npm install vue

3、开发版本

重要: GitHub 仓库的 /dist 文件夹只有在新版本发布时才会提交。如果想要使用 GitHub 上 Vue 最新的源码,需要自己构建!

git clone https://github.com/vuejs/vue.git node_modules/vue
cd node_modules/vue
npm install
npm run build

二、介绍

1、vue

Vue 是一套用于构建用户界面的渐进式框架

运行.vue文件
D:\workplace\vue>vue serve

2、Vue特点

易用: 会html、css、js即可上手
灵活: 不断繁荣的生态系统,可以在一个库和一套完整框架之间自如伸缩
高效: 20KB min + gzip 运行大小,超快虚拟DOM,最省心的优化
库和框架的区别
框架:是一套完整的解决方案,对项目的侵入性比较大,项目如果需要换框架,需重新搭建整个项目
库:提供一个小功能,对项目的入侵性比较小,如果某个库无法完成某些需求,可以很容易切换到其他库实现需求

引入vue


<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
或者

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

3、插值表达式{{ }}

(1) {{ string | number | booleans | 数组 | object | undefined | null | 表达式 }}
    里面可以放的东西   
    {{ 'a' }} 字符string    
    {{ 12 }} number    
    {{ true } 布尔值    
    {{ [1,2,3] }} 数组    
    {{ {a:1, b:10 } }} 对象object    
    {{ undefined }}    
    {{ null }}    
    {{ 1+1 }} 表达式
(2) v-text与插值表达式{{}}的区别

v-text会覆盖元素中原来的内容,但插值表达式只会替换自己的占位符不会把整个元素清空。


<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vue测试title>
    <script src="js/vue.js">script>
head>
<body>
<div id="app">
    <p>+++{{msg}}---p>
    <p v-text="msg">+++---p>
div>
<script>
    var vm = new Vue({
        el: '#app',
        data: {
            msg: '123'
        }
    });
script>
body>
html>
+++123---
123

4、vue指令

(1)绑定

v-bind 绑定属性(v-bind <==> ?
  如:绑定图片:<img  v-bind:src="imgUrl" v-bind:alt="name" /> 或者 
 	 <img  :src="imgUrl" :alt="name" />
  	当图片出现错误的时候,会显示图片的name
 特殊的:class、style
 class:
	1、绑定多个class用数组:<h4 :class="[h4Class, h4Width]">{{ name }}h4>
	2、对象:<h4 :class="{red: true}">{{ name }}h4>
	3、对象和数组:<h4 :class="[{red: true}, h4Width]">{{ name }}h4>
	4、多元表达式:<h4 :class="[h4Flag ? 'red' : '' , h4Width]">{{ name }}h4>
 style:
	对象: <img  :src="imgUrl" :alt="name" :style="{width: imgWidth, border: '10px solid red'}"/>
	数组: <img  :src="imgUrl" :alt="name" :style="[{width: imgwidth}, imgStyle]"/>  <script> data: { imgStyle: {border: '10px solid red'} }script>


v-on:xxx监听事件(v-on <==> @)
  <button v-on:click="handleClick">点击button>
等价于   <button @click="handleClick">点击button>

(2)条件渲染

v-if 能够控制元素的显示与隐藏
  <button @click="handleClick">{{ text }}button>
  <div class="box red" v-if="show">div>
		data: {
            show: true,
            text: '隐藏'
        },
        methods: {
            handleClick () {
                this.show = !this.show;
                this.text = this.show ? '隐藏' : '显示';
            }
        }
v-else
    <button @click="handleClick">{{ text }}button>
    <div class="box red" v-if="show">div>
    <div class="box green" v-else>div>
v-else-if
	<div class="box red" v-if="num === 0">div>
    <div class="box yellow" v-else-if="num === 1">div>
    <div class="box green" v-else>div>
		data: {
            show: true,
            text: '隐藏',
            num: 0
        },
        methods: {
            handleClick () {
                this.show = !this.show;
                this.text = this.show ? '隐藏' : '显示';
            }
        }
v-show 通过添加一个style:display来控制元素显示与隐藏
 
v-if与v-show的区别
  • v-if 控制dom的移除和添加,v-show控制dom的样式显示与隐藏(display)

    • 频繁地切换显示与隐藏使用v-show
    • 只判断一次时,使用v-if
  • v-if可以写在template上,v-show不行,写了也没用

(3)列表渲染

v-for:arr、obj、num、string
循环数组 arr: item, index in arr
<ul>
    <li v-for="(item, index)  in arr">{{ item }} --- {{ index }}li>
ul>
const vm = new Vue({
        el: '#app',
        data: {
            arr: ['html', 'js', 'vue']
        }
    })
循环对象
<h4 v-for="(value, key, index) in obj">{{ value }} --- {{key}} --- {{index}}h4>
const vm = new Vue({
        el: '#app',
        data: {
            obj: {
                name: 'yitian',
                age: 18,
                looks: 'beautiful'
            }
        }
    })

key:name value:'yitian'
循环数字
<p v-for="item in 10">{{ item }}p>
数字1到10打印出来
循环字符串
<div v-for="item in 'yitian'">{{ item }}div>
注意:key:必须是num或字符串且唯一

5、更改数组

(1)不能通过索引的方式去更改数组,这样不会渲染
(2)不能通过更改长度的方式去更改数组,这样不会渲染
(3)数组变异方法
  • pop
  • shift
  • unshift
  • splice
  • sort
  • reverse
  • push

6、更改对象

(1)向对象内添加或者删除属性,不会渲染页面
(2) vm.$set 添加一个属性和值

set方法还可以为对象添加属性和值

<script>
    export default {
        data(){
            return {
                obj:{
                    name:'xiaoming'
                }
            }
        },
        methods:{
            change(){
                this.$set(this.obj,'age',12)
                console.log(this.obj);{name:xiaoming,age:12}
            }
        }
    }
</script>
Object.defineProperty(obj, prop, desc)

obj 需要定义属性的当前对象
prop 当前需要定义的属性名
desc 属性描述符

(3)Object.assign(ES6语法),添加多个属性和值
<script>
    export default {
        data(){
            return {
                obj:{
                    name:'xiaoming'
                }
            }
        },
        methods:{
            change(){
                this.obj=Object.assign({},this.obj,{
                      height:180,
                      eq:200
                  })
            }
        }
    }
</script>

7、双向数据绑定

(1) v-model 实现数据的双向绑定
1) text
value+@ input 的语法糖
<input type="text" v-model="value"/>
<span>{{ value }}span>
data: {
            value: 'yitian'
        }
2) checkbox
一个选项
 <input type="checkbox" v-model="checked" />
 {{ checked }}
data: {
            checked: true
        }
复/多选框
for 属性规定 label 与哪个表单元素绑定。
    <label for="html" >htmllabel>
    <input type="checkbox" value="html" id="html" v-model="checkedList"/>
    <label for="js" >jslabel>
    <input type="checkbox" value="js" id="js" v-model="checkedList"/>
    <label for="vue" >vuelabel>
    <input type="checkbox" value="vue" id="vue" v-model="checkedList"/>
    {{ checkedList }}
data: {
            checkedList: []
        }
3)单选框 radio
    <label for="html">htmllabel>
    <input type="radio" id="html" value="html" v-model="picked"/>
    <label for="js">jslabel>
    <input type="radio" id="js" value="js" v-model="picked"/>
    <label for="vue">vuelabel>
    <input type="radio" id="vue" value="vue" v-model="picked"/>
    {{ picked }}
data: {
            picked: ''
        }
4)select下拉框
单选
 

    {{ selected }}
data: {
          selected: ''
        }
多选
	<select name="" id="" v-model="selectedList" multiple>
        <option value="html">htmloption>
        <option value="js">jsoption>
        <option value="vue">vueoption>
    select>

    {{ selectedList }}
data: {
            selectedList: ''
        }
(2) textarea
 <textarea v-model="content">textarea>
 {{ content }}
data: {
            content: ''
        }

8、计算属性和侦听器

(1) watch侦听器
    {{ desc }}
    {{ looks }}
data: {
            name: '一天',
            age: 24,
            looks: 'handsome',
            desc: '姓名: 一天 年龄: 24'
        },
       watch: {
            name() {
                this.desc = `姓名: ${this.name}  年龄: ${this.age}`;
            }
        }
(2) computed 计算属性

data: {
            name: '一天',
            age: 24,
            looks: 'handsome',
        },
       computed: {
            desc () {
                return `姓名: ${this.name} 年龄: ${this.age}`;
            }
        }
       }
(3) 查找顺序 data > methods > computed

methods: 想要去写一些逻辑,比如说要去触发一个事件的时候,或者在某一个函数里面再去写另一个函数作为封装的时候

computed: 想要得到一个新的数据,而且拿过来就可以使用

watch: 当想要在某一个事件改变的时候,去做一个什么什么样的事情的时候

9、组件数据传递和属性校验

全局组件 局部组件

(1) 全局组件

component

<div id="app">
    <hello-world>hello-world>
    <hello-world>hello-world>
    <hello-world>hello-world>
div>
//Vue.component('组件的名字',{对象:组件的一些配置参数})
    Vue.component('HelloWorld', {
        data() {
          return {
              msg: 'hello'
          }
        },
        //组件的模版即结构
        template: `
            
{{ msg }}
`
, methods: { handleClick () { this.msg = 'yitian'; } } }) const vm = new Vue({ el: '#app', data: { }, })
(2) 局部组件

components

const vm = new Vue({
        el: '#app',
        data: {

        },
        components: {
            'HelloWorld': {
                template: `
                   
hello
`
} } })
注意:它是先使用局部组件,再去找全局组件
(3) 属性校验
components: {
            myContent: {
                // props: ['title', 'content'],
                //  props属性校验
                props: {
                    title: {
                        type: String,
                        // default:规定默认值
                        default: '山山水水'
                    },
                    content: {
                        type: Number,
                        required: true,
                        validator (val){
                            return val > 10000
                        }
                    },
                    number: {
                        type: Number
                    },
                    obj: {
                        type: Object
                    }
                },
            }
	}
}
(4) 父 -> 子 传值 props, 校验, v-bind=“object”
<div id="app">
    <my-content v-bind="childrenInfo">my-content>
div>
const vm = new Vue({
        el: '#app',
        data: {
            childrenInfo: {
                title: '一天',
                content: 78525,
                number: 0,
                obj: { a:1, b:10}
            }
        },
        components: {
            myContent: {
                // props: ['title', 'content'],
                //  props属性校验
                props: {
                    title: {
                        type: String,
                        // default:规定默认值
                        default: '山山水水'
                    },
                    content: {
                        type: Number,
                        required: true,
                        validator (val){
                            return val > 10000
                        }
                    },
                    number: {
                        type: Number
                    },
                    obj: {
                        type: Object
                    }
                },
                data () {
                  return {
                     ownNumber: this.number
                  }
                },
                template: `
                    

{{ title }}

{{ content }}

{{ ownNumber }}
{{ obj }}
`
, methods: { handleClick() { this.ownNumber ++; // this.obj.a = 100; } } } } })
(5)子 -> 父 传值 $emit(‘handle’, value)

直接子组件告诉父组件做什么,由父组件去做

<div id="app">
    <my-content v-bind="childrenInfo" @add="handleAdd">my-content>
    父组件内的number: {{ childrenInfo.number }}
    <button @click="handleClick">点击button>

div>
const vm = new Vue({
        el: '#app',
        data: {
            childrenInfo: {
                title: '一天',
                content: 78525,
                number: 0,
                obj: { a:1, b:10}
            }
        },
        methods: {
            handleAdd(num){
               this.childrenInfo.number += num;
            },
            handleClick() {
                this.childrenInfo.title = '是一天吖'
            }
        },
        components: {
            myContent: {
                // props: ['title', 'content'],
                //  props属性校验
                props: {
                    title: {
                        type: String,
                        // default:规定默认值
                        default: '山山水水'
                    },
                    content: {
                        type: Number,
                        required: true,
                        validator (val){
                            return val > 10000
                        }
                    },
                    number: {
                        type: Number
                    },
                    obj: {
                        type: Object
                    }
                },
                data () {
                  return {
                     // ownNumber: this.number
                  }
                },
                template: `
                    

{{ title }}

{{ content }}

子组件内的number: {{ number }}
{{ obj }}
`
, methods: { handleClick() { // this.ownNumber += 10; // 触发一个事件“add” this.$emit('add', 10) // this.obj.a = 100; } } } } })

10、 ref引用

(1)dom的引用
dom对象的引用是该对象
<div id="app">
<square-change>square-change>
div>
.square-box {
            width: 100px;
            height: 100px;
            margin-top: 20px;
            border: 2px solid #ccc;
        }
const vm = new Vue({
        el: '#app',
        data: {

        },
        components: {
            squareChange: {
                data() {
                  return {
                      colorArr: ['red', 'orange', 'yellow', 'green']
                  }
                },
                template: `
                    
`
, methods: { handleClick (color) { // const color = e.target.dataset.color; const squareBox = this.$refs.squareBox; squareBox.style.backgroundColor = color; } } } } })
(2)组件的引用
组件的引用是组件的实例对象
<div id="app">
    <square-change ref="cmp">square-change>
    <button @click="handleClick">clickbutton>
div>
const vm = new Vue({
        el: '#app',
        data: {

        },
        methods: {
            handleClick() {
                console.log(this.$refs.cmp.colorArr);
            }
        },
        components: {
            squareChange: {
                data() {
                  return {
                      colorArr: ['red', 'orange', 'yellow', 'green']
                  }
                },
                template: `
                    
`
, methods: { handleClick (color) { // const color = e.target.dataset.color; const squareBox = this.$refs.squareBox; squareBox.style.backgroundColor = color; } } } } })
注意:
1、ref同名时,后添加的会覆盖前面的,引用指向的是最后一个元素
2、在v-for时添加引用,引用的值类型是数组,数组里面是一个一个的对象、组件的实例对象

11、安装脚手架

cnpm install -g @vue/cli  安装脚手架,用于生成项目
cnpm install -g @vue/cli-service-global 快速原型开发 编译.vue文件
vue --version  查看vue-cli版本
运行.vue文件命令:
D:\workplace\vue>vue serve App.vue

12、进度条组件

(1)线性进度条 —百分比外显
//App.vue



//Progress.vue






(2)线性进度条 —百分比内显
//App.vue









//Progress.vue






(3)环形进度条

三、Vue生命周期

beforeCreate :

在实例初始化之后,数据观测(data observer) 和 event/watcher 事件配置之前被调用

完成实例初始化,初始化非响应式变量,元素DOM和数据都还没有初始化
this指向创建的实例
可以在这加个loading事件
data computed watch methods上的方法和数据均不能访问

created:

在实例创建完成后被立即调用。

在这一步,实例已完成以下配置:数据观测(data observer),属性和方法的运算, watch/event 事件回调

然而,挂载阶段还没开始,$el属性目前不可见

实例创建完成
完成数据(data props computed)的初始化,导入依赖项
可访问data computed watch methods上的方法和数据
未挂载DOM,不能访问$el,$ref为空数组
可在这结束loading,还能做一些初始化,实现函数自执行
可以对data数据进行操作,可进行一些请求,但由于DOM未挂载,请求过多或者占用时间过长会导致页面线上空白。
若在此阶段进行的DOM操作一定要放在Vue.nextTick()的回调函数中

beforeMount:

在挂载开始之前被调用:相关的渲染函数首次被调用

有了el,编译了template/outerHTML
能找到对应的template,并编译完成render函数
el属性:检查vue配置,即new Vue{}里面的el项是否存在,有就继续检查template项,没有则等到手动绑定调用vm.$mount()

template: 检查配置中的template项,如果没有template进行填充被绑定区域,则被绑定区域的el对象的outerHTML(即整个#app DOM对象,包括
标签)都作为被填充对象替换掉填充区域

mounted:

el 被新创建的 vm.$el 替换,挂载成功

完成创建vm.$el,和双向绑定
完成挂载DOM和渲染,可在mounted钩子对挂载的dom进行操作
即有了DOM且完成了双向绑定,可访问DOM节点,$ref
可在这发起后端请求,拿回数据,配合路由钩子做一些事情
可对DOM进行操作

beforeUpdate:

数据更新时调用

数据更新之前
可在更新前访问现有的DOM,如手动移除天价的事件监听器

updated:

组件 DOM 已经更新,组件更新完毕

完成虚拟DOM的重新渲染和打补丁
组件DOM已完成更新
可执行依赖的DOM操作
注意:不要在此函数中操作数据,会陷入死循环

activated:keep-alive组件激活时调用。该钩子在服务器渲染期间不被调用

在使用vue-router时,有时需要使用来缓存组件状态,这个时候created钩子就不会被重复调用了
如果子组件需要在每次加载的时候进行某些操作,可以使用activated钩子触发

deactivated:keep-alive组件停用时调用。该钩子在服务器渲染期间不被调用

for keep-alive 组件被移除时使用

beforeDestroy:实例销毁之前调用。在这一步,实例仍然完全可用

在执行app.$destroy()之前
可做一些删除提示,如:您确认删除xx吗?
可用于销毁定时器,解绑全局时间,销毁插件对象

destroyed:当vm.$destroy()被调用,开始拆卸组件和监听器,生命周期终结

当前组件已被删除,销毁监听事件 组件 事件子实例也被销毁
这时组件已经没有了,无法操作里面的任何东西 

四、利用脚手架搭建项目

1、命令行生成项目

C:\Users\Admin>D:

D:\>cd workplace

D:\workplace>vue create vue-app

D:\workplace>"node"  "D:\nodejs\node_cache\\node_modules\@vue\cli\bin\vue.js" create vue-app
?  Your connection to the default npm registry seems to be slow.
   Use https://registry.npm.taobao.org for faster installation? Yes


Vue CLI v3.12.0
? Please pick a preset: Manually select features
? Check the features needed for your project: Babel
? Where do you prefer placing config for Babel, PostCSS, ESLint, etc.? In package.json
? Save this as a preset for future projects? Yes
? Save preset as: onlyBable

2、图形化界面生成项目

C:\Users\Admin>vue ui
创建 => 在此创建新项目 => 编辑信息之后,下一步 => 选择手动 => 功能界面,选择 Bable => 下一步,创建项目,不保留预设

你可能感兴趣的:(vue)