文章目录
Vue 基础
Vue 构建用户界面的渐进式框架。Vue 被设计为可以自底向上逐层应用.基于 HTML 的模板语法,声明式地将 DOM 绑定至底层 Vue 实例的数据。所有 Vue.js 的模板都是合法的 HTML,所以能被遵循规范的浏览器和 HTML 解析器解析。
Vue 将模板编译成**虚拟 DOM **渲染函数。结合响应系统,Vue 能够智能地计算出最少需要重新渲染多少组件,并把 DOM 操作次数减到最少。
文件扩展名.vue
文件
template
是一级节点,用于写tag组件, script
和 style
是并列的一级节点,也就是有3个一级节点。这个叫vue单文件组件规范sfc
引入css 文件@import "./common/uni.css";
使用MVVM (Model-View-ViewModel的简写)模式
1. 语法
1.1 bind
文本绑定
{{ msg }} #文本
v-bind
v-bind - 缩写为‘ :
’
<template>
<view>
<!-- class -->
<view class="static" :class="{ active: isActive}">111</view>
<view class="static" :class="{ active: isActive, 'text-danger': hasError }">222</view>
<!--数组语法-->
<view class="static" v-bind:class="[isActive ? activeClass : '', errorClass]">222</view><!-- 三元表达式 -->
<view class="static" v-bind:class="[{ active: isActive }, errorClass]">333</view>
<!--方法-->
<view class="static" :class="computed 中带返回值为字符串的方法">333</view>
<!-- style -->
<view v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }">333</view>
</view>
</template>
<script>
export default {
data() {
return {
isActive: true,
hasError: false,
activeColor:"green",
errorClass:"red",
fontSize:50
}
}
}
</script>
<style>
.static{
color: #2C405A;
}
.active{
background-color: #007AFF;
}
.text-danger{
color: #DD524D;
}
</style>
表单控件绑定
指令:v-model
v-model 指令在表单 input
、textarea
及 select
元素上创建双向数据绑定
,忽略所有表单元素的 value、checked、selected attribute 的初始值而总是将 Vue 实例的数据作为数据来源。
你应该通过 JavaScript 在组件的 data 选项中声明初始值。
其他
v-html
- 更新元素的 innerHTML
- App端和H5端支持 v-html ,微信小程序会被转为 rich-text,其他端不支持 v-html
1.2. 指令
- 指令是带有
v-
前缀的特殊属性 - 指令的作用是,当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM
- 一些指令能够接收
一个“参数”
,在指令名称之后以冒号( : )表示
v-on
- 用于监听 DOM 事件
- 缩写为‘
@
’
v-once
- 只渲染元素和组件一次,之后的视为静态内容并跳过
- v-once 能保证节点只渲染一次
v-if和v-else 惰性的:如果在初始渲染时条件为假,则什么也不做
当 v-if
与 v-for
一起使用时,v-for
具有比 v-if
更高的优先级,不推荐同时使用 v-if 和 v-for
<view v-if="seen"></view>
<view v-else-if="type === 'B'">中间</view>
<view v-else></view>
v-show
Hello!
v-for
需要使用 item in items
形式的语法
<view v-for="(item, index) in items"> <!---index 可选->
{{ index }} - {{ item.message }}
</view>
使用对象:
///value 是被迭代的对象元素的属性值。
///property 名称 (也就是键名)。
///index 索引。
<view v-for="(value, name, index) in object">
{{ index }}. {{ name }}: {{ value }}
</view>
v-for="(item, index) in 10"
H5平台 item 从 1 开始,其他平台 item 从 0 开始,可使用第二个参数 index 来保持一致。
在非H5平台 不支持第三个参数
在组件上使用
<my-component v-for="item in items" :key="item.id"></my-component>
1.3. data 属性
返回一个初始数据对象的函数(不要直接引用函数外的对象,页面关闭时,数据不会自动销毁,再次打开该页面时,会显示上次数据。),
//正确用法,使用函数返回对象
data() {
return {
title: 'Hello'
}
}
//错误写法,会导致再次打开页面时,显示上次数据
data: {
title: 'Hello'
}
//错误写法,同样会导致多个组件实例对象数据相互影响
const obj = {
title: 'Hello'
}
data() {
return {
obj
}
}
1.4 props
props: {
msg: String
}
1.5 computed 计算属性
计算属性都包含 getter
和setter
,任何复杂逻辑,你都应当使用计算属性。
使用场景:当页面中有某些数据依赖其他数据进行变动的时候,可以使用计算属性,
computed: {
// 计算属性的 getter
reversedMessage(){
return this.message.split('').reverse().join('') //反转字符串 如果在模板中使用不易维护 <view> {{ message.split('').reverse().join('') }}</view>
}
}
Vue 知道 reversedMessage
依赖于 message
,因此当 message 发生改变时,所有依赖 reversedMessage 的绑定也会更新,
可以依赖多个 Vue 实例
的数据,只要其中任一数据变化,计算属性就会重新执行,视图也会更新。
在需要时可以提供一个 setter
函数,当手动修改计算属性的值时,就会触发 setter 函数
computed: {
fullName: {
// getter
get(){
return this.firstName + ' ' + this.lastName
},
// setter
set(newValue){
var names = newValue.split(' ')
this.firstName = names[0]
this.lastName = names[names.length - 1]
}
}
}
方法和计算属性的区别:
可以将同一函数定义为一个方法而不是一个计算属性。两种方式的最终结果确实是完全相同的。
然而,不同的是计算属性是基于它们的响应式依赖进行缓存的。
只在相关响应式依赖发生改变时它们才会重新求值。这就意味着只要 message 还没有发生改变,多次访问 reversedMessage 计算属性会立即返回之前的计算结果,而不必再次执行函数。
return Date.now()
计算属性将不再更新
1.6 watch 侦听属性
Vue 提供了一种更通用的方式来观察和响应 Vue 实例上的数据变动,类似于监听机制+事件机制.
当你有一些数据需要随着其它数据变动而变动时,你很容易滥用 watch 。然而,通常更好的做法是使用计算属性而不是命令式的 watch 回调。
使用场景:数据变化时执行异步或开销较大的操作,可以随时修改状态的变化
data():{return {
firstName:"",
lastName:"",
value:""
}}
,watch: {
firstName: function(val) {
this.fullName = val + ' ' + this.lastName
},
lastName(val) {
this.fullName = this.firstName + ' ' + val
},
//高级用法 // 页面加载时,就自动触发此事件
value:{
handler(val){
this.checkName(val);
this.tip = "正在验证......";
}
,immediate: true //true :首次加载就监听数据变化,false:只有发生改变才监听
//测了之后不生效
,deep:true // 开启深层次的监听,所有属性都加上监听器,如果其中一个发生改变了就执行handler函数
}
} //代码是命令式且重复的。将它与计算属性的版本进行比较
,computed: {
fullName(){
return this.firstName + ' ' + this.lastName
}
}
类型:{ [key: string]: string | Function | Object | Array } ,键是需要观察的表达式,值是对应回调函数。值也可以是方法名,或者包含选项的对象。
Vue 实例将会在实例化时调用 $watch()
,遍历 watch 对象的每一个 property 。
<template>
<view>
<input type="text" v-model="word">
</view>
</template>
<script>
export default {
data() {
return {
word: 'word'
}
},
watch: {
/* 使用watch来响应数据的变化 */
word(newVal, oldVal) {
console.log('最新值是:'+newVal,"原来的值是:"+ oldVal);
}
},
}
</script>
2. 组件
- 组件是视图层的基本组成单元。
- 组件是一个单独且
可复用的功能模块
的封装。 - 一个组件包括开始标签和结束标签,标签上可以写属性,并对属性赋值。内容则写在两个标签之内。
2.1 组件名称:
定义组件名的方式有两种
- 使用
kebab-case
引用这个自定义元素时使用 kebab-case, 例如<my-component-name>
- 使用
PascalCase
引用这个自定义元素时两种命名法都可以使用。 也就是说<my-component-name>
和<MyComponentName>
都是可接受的。
2.2 props
数组或对象,用于接收来自父组件的数据,
export default {
props: {
age: {
type: Number, //String 、 Number 、 Boolean 、 Array 、 Object 、 Date 、 Function 、 Symbol ,任何自定义构造函数、或上述内容组成的数组
default: 0, //any
required: true, //Boolean
validator: function(value) { //Function prop 的值作为唯一的参数代入
return value >= 0
}
}
}
}
所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定
:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外变更父级组件的状态,从而导致你的应用的数据流向难以理解。
不应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在浏览器的控制台中发出警告。
2.2.1 $emit
父组件可以使用 props
把数据传给子组件,子组件可以使用 $emit
触发父组件的自定义事件
vm.$emit( "eventName", arg ); //触发当前实例上的事件
vm.$on ( "eventName", fn ); //监听event事件后运行 fn;
//子组件
<template>
<view>
<block>子组件:{{name}}</block>
<button @click='select(`大连`)'>点击此处将‘大连’发射给父组件</button>
<block>计算属性:{{iName}}</block>
<view>绑定`props`属性:{{data}}</view>
</view>
</template>
<script>
export default {
name:"my-sub",
data() {
return {
name: this.data //当data 更改时不会触发name 更改
};
}
,props:{
data:{
type:String,
default:'{}'
}
},
computed: {
iName() {
return this.data+'你好!';
}
}
,methods:{
select(city){
let data = { name: city };
this.$emit('showData',data);//触发父组件的 showData事件
}
}
}
</script>
<style lang="scss">
</style>
// 父组件
<template>
<view>
<block>当前名称:{{name}}</block>
<my_sub @showData='updateData' :data="name"></my_sub>
</view>
</template>
<script>
import my_sub from './sub.vue'
export default {
name:"parent",
components:{my_sub}
,data() {
return {
name:"北京"
};
}
,props:{
}
,methods:{
updateData(data){
this.name = data.name;//改变了父组件的值
console.log('接收到子组件数据:'+this.name)
}
}
}
</script>
<style lang="less">
</style>
2.3 ref
用来给元素或子组件注册引用信息,引用信息将会注册在父组件的 $refs
对象上。
ref 本身是作为渲染结果被创建的,在初始渲染的时候你不能访问它们,它们还不存在!
$refs 也不是响应式的,因此你不应该用它在模板中做数据绑定 ,
//仅H5端支持,通过this.$refs.content
来获取view实例
<view ref="content">hello</view>
//支持通过this.$refs.child来获取child-component实例
<child-component ref="child"></child-component>
当 ref 和 v-for 一起用于元素或组件的时候,引用信息将是包含 DOM 节点或组件实例的数组。
- 子组件ref
通过 ref 为子组件赋予一个ID 引用
,在vue的js中可通过this. r e f s . X X X 来 获 取 到 组 件 对 象 。 ‘ < b a s e − i n p u t r e f = " u s e r n a m e I n p u t " > < / b a s e − i n p u t > ‘ t h i s . refs.XXX来获取到组件对象。 `<base-input ref="usernameInput"></base-input>` this. refs.XXX来获取到组件对象。‘<base−inputref="usernameInput"></base−input>‘this.refs.usernameInput来访问这个实例
3. 事件
<button v-on:click="greet">Greet</button>
在 methods
对象中定义greet(event)
方法.
带参数的方法:<button v-on:click="say('hi')">Say hi</button>
访问原始的 DOM 事件。可以用特殊变量 $event
把它传入方法 warn(message, event)
事件修饰符 指令应该以特殊方式绑定
<!-- 阻止单击事件继续传播 -->
`<view v-on:click.stop="doThis"></view>`
v-on 提供了事件修饰符:
.stop: 各平台均支持, 使用时会阻止事件冒泡,在非 H5 端同时也会阻止事件的默认行为
.native: 监听原生事件,仅在 H5 平台支持
.prevent: 仅在 H5 平台支持
.capture: 仅在 H5 平台支持
.self: 仅在 H5 平台支持
.once: 仅在 H5 平台支持
.passive: 仅在 H5 平台支持
web 与 uni-app 对应事件
click <===> 'tap',
touchstart <===> 'touchstart',
touchmove <===> 'touchmove',
touchcancel <===> 'touchcancel',
touchend <===> 'touchend',
tap <===> 'tap',
longtap <===> 'longtap', //推荐使用longpress代替
input <===> 'input',
change <===> 'change',
submit <===> 'submit',
blur <===> 'blur',
focus <===> 'focus',
reset <===> 'reset',
confirm <===> 'confirm',
columnchange <===> 'columnchange',
linechange <===> 'linechange',
error <===> 'error',
scrolltoupper <===> 'scrolltoupper',
scrolltolower <===> 'scrolltolower',
scroll <===> 'scroll'
### 3.1 自定义事件
原生事件绑定到组件,你可以使用 v-on
的 .native
修饰符
<!-- 我是父组件 -->
<template>
<view>
<componentA @click.native="clickComponentA" style="height: 200px;"></componentA>
</view>
</template>
<script>
export default {
methods: {
clickComponentA(){
console.log("clickComponentA");
}
}
}
</script>
<!-- 我是子组件 -->
<template>
<view>
<view type="default" @click.stop="open" style="height: 30px;">点击</view>
</view>
</template>
<script>
export default {
methods:{
open(){
console.log("open");
}
}
}
</script>