vue基础语法

Vue.js是一个构建数据驱动的web界面的库。核心概念:插值语法、插值表达式、v-model双向绑定、监听器 $watch、计算属性computed、动态绑定class、动态绑定内联样式、指令、过滤器等

MVVM

1
2
3
4
MVVM模式可以极大的简化我们开发的工作量
M: Model 模型 前端中的数据 例如数组 对象等
V: View 视图、模板 前端中的dom对象 例如下拉框,弹层等
VM: ViewModel 视图模型 双向绑定 连接Model和View 将模型中的数据与视图中的数据绑定在一起 事件监听和数据绑定

插值语法

  • 语法{{}}实现将模型中的数据渲染到视图中
  • v-text='js环境' 渲染数据
  • v-html='js环境' 可以将标签和数据渲染出来 注意: 写在里面的不需要{{}}
    插值语法

插值表达式

插值的语法的本质上是提供了一个js环境,在js环境中我们可以使用js表达式(变量,运算符,方法等),但不能写语句和if判断条件

1
2
3
4
5
6
7
<div>{{msg.toUpperCase()}} {{width*height}}</div>
nue Vue({
data () {
return { msg: 'tew', width: 20, height: 2}
}
}
// <div>TEW 40</div>

表单元素的v-model双向绑定

使用v-model指令在表单 input、textarea及select元素上创建双向数据绑定,v-model的属性值是一个js作用域(一般用于表单元素中)

  • 通过data属性实现数据模型到vue实例化对象的绑定(通过属性的特性实现)
  • 通过v-model指令,实现视图到vue实例化对象的绑定(通过事件实现、input或change事件)
  • v-model在表单中的使用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    <div>
    <!-- 文本框 v-model -->
    <p>当行输入框: <input v-model="msg" /></p>
    <!-- 多行文本(文本域) textarea 通过添加v-model属性实现文本域双向绑定 -->
    <textarea v-model="multiMsg"></textarea>
    <!-- 复选框 checkbox v-model绑定一个数组变量(多个复选框)或布尔值变量(单个复选框) -->
    <input type="checkbox" v-model="fruitArr" value="apple">苹果
    <input type="checkbox" v-model="fruitArr" value="banana">香蕉
    <input type="checkbox" v-model="fruitArr" value="pear">
    <!-- 单选框 v-model要设置同一个变量 -->
    <input type="radio" v-model="sex" value="0">
    <input type="radio" v-model="sex" value="1">
    <!-- 下拉框 通过给select设置v-model属性实现下拉框双向绑定 -->
    <select v-model="selectText">
    <option v-for="option in options" :value="option:value">{{option.text}}</option>
    </select>
    </div>
    <script>
    new Vue({
    data () {
    return {
    msg: '单行文本框',
    multiMsg: '多行文本',
    fruitArr: ['apple'],
    sex: '1',
    selectText: 'A',
    options: [{ text: 'One', value: 'A'}, {text: 'Two', value: 'B'}]
    }
    }
    })
    </script>
  • v-model修饰符

    1
    2
    3
    4
    // v-model默认在每次input事件触发后将输入框的值与数据进行同步
    // v-model.number='' 输入内容转化为数值类型
    // v-model.trim = '' 自动过滤(去除)用户输入的首尾空格
    // v-mode.lazy='' 使用lazy修饰符后转化为change事件进行同步

监听器 $watch

$watch 用于观察Vue实例上的数据变动 回调函数得到的参数为新值和旧值
watch 一个对象,键是需要观察的表达式,值是对应回调函数。值也可以是方法名,或者包含选项的对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// $watch 或 watch 值变化时才执行  加上 immediate:true 绑定之后立即执行handle
// deep:true 会遍历监听对象下所有属性开销较大时, 可以写成字符串监听对象具体的属性
// $watch
vm.$watch(
'a', // 监听的值 或 函数的计算结果
function(newval, oldVal){ // 回调函数
console.log(newVal+'--'+oldVal)
},
{
deep: true, // 深度监听对象内部值的变化
immediate: true // 立即执行回调函数
}
)
// watch
new Vue({
watch: {
a: {
handle () {
console.log(newVal+'--'+oldVal)
},
deep: true, //任何被侦听的对象的 property 改变时被调用,不论其被嵌套多深
immediate: true // 侦听开始之后被立即调用
}
}
})

计算属性 computed

在插值前对数据进行处理,vue提供了动态插值语法,允许在插值前调用一个函数来处理数据,动态函数要定义在computed属性中,属性值是一个对象,返回值就是插入视图中的数据
计算属性与methods普通方法好处: 计算属性中的计算结果会被缓存,多次使用时,计算属性只会调用一次。减少模板的复杂度,节省性能
计算属性依赖data数据只要有一个发生改变就会重新计算 计算的结果会被缓存 计算属性会挂载所在的实例上私有属性上 值是函数的返回值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// <li v-fot="(item, index) in limtList" :key="item">{{item}}</item>
nue Vue({
data () {
return { list: [1,2,3,4,5,6,7,8,9] }
}
computed: {
limtList () {
return this.list.filter(item => item > 7)
}
}
})
/*
<li>8</li>
<li>9</li>
*/

:class绑定HTML Class类

v-bind:class 简写 (:class) 动态的渲染元素上的类 只需要计算出表达式的最终的字符串 可以与普通的class特性共存

  • 对象方式绑定类

    1
    2
    3
    4
    // 对象中的每个属性名称代表一个类的名称 属性值只能是布尔值
    // true 表示保留这个属性类名 false 表示删除这个类名
    // 属性中出现特殊字符 需要加上引号,
    <div v-bind:class="{acitve: isActive, 'has-bg':hasBg}"></div>
  • 数组方式绑定类

    1
    2
    3
    4
    5
    // 数组每个成员是变量,一旦加上引号就将变量转化成字符串  每个成员只能代表一个类
    <div v-bind:class="[activeClass, errorClass]"></div>
    <div v-bind:class="[isActive ? activeClass : '', errorClass]"></div>
    // 数组语法中也可以使用对象语法:
    <div v-bind:class="[{ active: isActive }, errorClass]"></div>

:style绑定内联样式

  • 对象语法

    1
    2
    3
    4
    // CSS 属性名可以用驼峰式 (camelCase) 或短横线分隔 (kebab-case,记得用引号括起来) 来命名:
    // 对象的属性名称 表示css的属性名称
    // 对象的属性值 表示css的样式属性值
    <div v-bind:style="{ color: textColor, 'font-size': fontSize + 'px' }"></div>
  • 数组语法
    <div v-bind:style="[baseStyles, overridingStyles]"></div>

指令

指令(Directives)是特殊的带有前缀v-的特性.指令就是扩展html标签功能和属性的

  • v-once 只绑定一次 只渲染一次 保留在内存中 后续改变不会再渲染
  • v-text 插值
    <span v-text="msg"></span> 等同于 <span>{{msg}}</span>
  • v-html 避免html元素被编译
    <div v-html="html"></div>
  • v-bind 动态地绑定一个或多个 attribute,或一个组件 prop 到表达式 可简写成 :

    1
    2
    3
    <img v-bind:src="imageSrc">
    <img :src="imageSrc"> <!-- 缩写 -->
    <my-component :prop="someThing"></my-component>
  • v-model 在表单控件或者组件上创建双向绑定

  • v-pre 跳过这个元素和它的子元素的编译过程
  • v-cloak 可以隐藏未编译的 Mustache 标签直到实例准备完毕。

    1
    2
    <div id='app' v-cloak><div>{{text}}</div></div>
    <style>[v-cloak] { display: none }</style>
  • v-show 切换元素的 display CSS 属性。
    v-show是简单的切换元素的CSS display属性, 有v-show的元素会始终渲染到并保持在dom中,只是隐藏了而已,不支持template, 也不支持v-else
    <h1 v-show="isShow">Hello!</h1>

  • v-if 动态渲染一个元素

    1
    2
    3
    4
    5
    6
    7
    8
    9
    // v-if的属性值是true  会将这个元素渲染到页面中
    // v-if的属性自是false 会将这个元素从页面中删除
    // 切换多个元素,可以把多个元素放入template中,为其添加v-if指令,而最终的渲染结果并不会包含它
    <div id='app'>
    <template v-if="isShowDetail">
    <sapn>姓名: tew</span>
    <sapn>性别: 男</sapn>
    </template>
    </div>
  • v-else 为 v-if 或者 v-else-if 添加“else 块”。
    v-else元素必须紧跟v-if或v-show元素的后面 否则它不能被识别

    1
    2
    3
    4
    5
    6
    <div v-if="Math.random() > 0.5">
    Now you see me
    </div>
    <div v-else>
    Now you don't
    </div>
  • v-else-if
    v-else-if
    注: v-if是真实的条件渲染,它会在切换当中销毁与重建条件块内的事件监听器和子组件,有更高的切换消耗. v-show只是简单的基于css切换,有更高的初始渲染消耗,如果需要频繁的切换 使用v-show更好,如果条件不大可能改变则用v-if

  • v-on 绑定事件监听器, 事件类型由参数指定 简写@

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    <button v-on:click="doThis"></button>
    // <!-- 内联语句 -->
    <button v-on:click="doThat('hello', $event)"></button>
    // <!-- 缩写 -->
    <button @click="doThis"></button>
    // <!-- 停止冒泡 -->
    <button @click.stop="doThis"></button>
    // <!-- 阻止默认行为 -->
    <button @click.prevent="doThis"></button>
    // <!-- 阻止默认行为,没有表达式 -->
    <form @submit.prevent></form>
    // <!-- 串联修饰符 -->
    <button @click.stop.prevent="doThis"></button>
    // <!-- 键修饰符,键别名 -->
    <input @keyup.enter="onEnter">
    // <!-- 键修饰符,键代码 -->
    <input @keyup.13="onEnter">
    // <!-- 阻止单击事件冒泡 -->
    <a v-on:click.stop="doThis"></a>
    // <!-- 提交事件不再重载页面 -->
    <form v-on:submit.prevent="onSubmit"></form>
    // <!-- 修饰符可以串联 -->
    <a v-on:click.stop.prevent="doThat"></a>
    // <!-- 只有修饰符 -->
    <form v-on:submit.prevent></form>
    // <!-- 添加事件侦听器时使用事件捕获模式 -->
    <div v-on:click.capture="doThis">...</div>
    // <!-- 只当事件在该元素本身(而不是子元素)触发时触发回调 -->
    <div v-on:click.self="doThat">...</div>
    // <!--只触发一次-->
    <a v-on:click.once="doThis"></a>
    // passive 会告诉浏览器你不想阻止事件的默认行为, 不用执行是否有preventDefault事件查询了
    <div v-on:scroll.passive="onScroll">...</div
    // 全部的按键别名:
    // @keyup.enter="" .tab .delete .esc .space .up .down .left .right .ctrl .alt .shift .meta
    // 给组件绑定事件 需要事件加修饰符 @click.native=’handleClick’
    <Child @click.native='test'/>
  • 获取事件对象的两种方式

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    // 方式一 带括号 固定参数 $event
    // 如果带括号而不传$event参数 则获取不到事件对象event
    <button @click="btnClick(1, $event)">事件对象1</button>
    btnClick(a, ev) {
    console.log(a)
    console.log(ev)
    }
    // 方式二 不带括号
    <button @click="btnClick">事件对象1</button>
    btnClick(ev) {
    console.log(ev)
    }
  • 绑定多个事件处理程序

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    <!-- 方式一 使用逗号分隔多个事件处理程序 -->
    <button @click="one($event), two($event)">
    触发多个事件
    </button>
    <!-- 方式二 使用@xxx 和 v-on:xxx -->
    <button @click="one" v-on:click="two">
    触发多个事件
    </button>
    <script>
    methods: {
    one(event) {
    console.log('one')
    },
    two(event) {
    console.log('two')
    }
    }
    </script>
  • v-for 指令基于一个数组会对象来渲染一个列表。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    // v-for 也可以接受一个整数,此时他将重复数次
    <div>
    <span v-for="n in 3">{{ n }} </span>
    </div>
    // <span>1</span><span>2</span><span>3</span>
    // items 是源数据数组 item 迭代元素的别名 index 当前迭代元素的索引
    // 可以使用 of 替代 in 如 v-for="(item, index) of items"
    // :key 提升循环显示的性能 表示唯一key属性 可以避免重用或重排 2.2.0+以后key是必须的
    // 当v-for与v-if处于同一节点,v-for 的优先级比 v-if 更高,v-if // 将分别重复运行于每个 v-for 循环中,可实现渲染部分项节点
    <ul id="example-1">
    <li v-for="(item, index) in items" :key="item.message">
    {{ item.message }}
    </li>
    </ul>
    <div v-for="(val, key) of object"></div>
    <div v-for="(val, name, index) of object"></div>

过滤器

过滤器可以用在两个地方:双花括号插值和v-bind表达式
在双花括号中
<div v-bind:id="rawId | formatId"></div> 在v-bind中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// {{ message | capitalize }}
// 全局过滤器
Vue.filter('capitalize', function (value) {
if (!value) return ''
value = value.toString()
return value.charAt(0).toUpperCase() + value.slice(1)
})
// 局部过滤器
new Vue({
filters: {
capitalize: function (value) {
if (!value) return ''
value = value.toString()
return value.charAt(0).toUpperCase() + value.slice(1)
}
}
})
// 多个过滤器 {{ message | filterA | filterB }}
// 表达式 message 的值将作为参数传入到函数A中处理完成。然后继续调用filterB,将 filterA 的结果传递到 filterB 中
// 过滤器参数 {{ message | filterA('arg1', arg2) }}
// filterA 被定义为接收三个参数的过滤器函数。其中 message的值作为第一个参数,普通字符串 'arg1' 作为第二个参数,表达式 arg2 的值作为第三个参数。

数组或对象值的更新问题

因为 JavaScript 的限制,Vue.js 不能检测到下面数组变化:不会触发视图更新
直接用索引设置元素,如 vm.items[0] = {};
修改数据的长度,如 vm.items.length = 0。
数组变异方法会触发试图更新
push() pop() shift() unshift() splice() sort() reverse()

1
2
3
4
5
6
7
8
9
10
11
12
13
// 改变数组或对象的某一项值时,试图未更新, 触发试图更新的方法如下
// 1. 改变数组或对象的引用 重新为其赋值
// 2. 使用数组的变异方法 或 对象拷贝 新对象替换老对象
vm = { list: [{id: '11', name: 'bob'},{id: '22', name: 'tom'}] }
vm.list.splice(1,1, {id: '33', name: 'tew'})
// { list:[{id: "11", name: "bob"}, {id: "33", name: "tew"}] }
// 新对象 替换 旧对象
obj = Object.assign({}, this.obj, { a: 1, e: 2 })
obj = {...this.obj, { a: 1, e: 2 }}
// 3. 使用 Vue.set()或者 vm.$set()
Vue.set(vm.list,'name','tew')
vm.$set(vm.list,'name','tew')
// 4. 使用 this.$forceUpdate() 强制组件重新渲染

props 参数校验 与非props特性

  • props值方式一:字符串数组,数组中的字符串就是传父组件传递的名称
  • props值方式二:对象,对象可以设置传递时的类型, 默认值,是否必须等
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    // 非props 特性
    // 如果子组件没有用props接受 会报错
    // 父组件的属性会展示在子组件最外层的元素属性中
    // props参数校验
    Vue.comonent('child', {
    props: {
    content: {
    type: String, // String Number Boolean Array Object Date Function Symbol
    required: false, // 必填
    default: '默认值', // 字符串的默认值
    validator(value){ // 自定义验证函数
    return value.length > 5
    }
    },
    person: {
    type: Object,
    // 对象或数组 默认值 必须从一个工厂函数获取
    default: function (){
    return {name: 'tew'}
    }
    }
    }
    template: '<div>{{person.name}}--{{content}}</div>'
    })

Vue-cli2 脚手架

  1. npm install vue-cli -g 安装 vue命令环境 脚手架工具 验证安装ok? vue –V
  2. 生成项目模板
    vue init <模板名> 本地文件夹名称 vue list 查看官方提供模板
    模块名 webpack 大型项目 Eslint 检测代码规范 单元测试
    webpack-simple simple browserify browserify-simple
  3. 进入到生成目录里面 cd xxx npm install 安装项目依赖
  4. npm run dev 启动项目
    注: 使用npm init 初始化项目的时候 路径不能有中文 不能有大写字母
    vue-cli2 初始化项目过程
    vue-cli
    vue-cli2 项目目录结构
    vue-cli
-------------本文结束感谢您的阅读-------------
0%