多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
> 基础语法学习,磨刀不误砍柴工,必须掌握 * [文本插值](https://www.kancloud.cn/wangking/uniapp/1882027#_3) * [v-bind](https://www.kancloud.cn/wangking/uniapp/1882027#vbind_14) * [v-on](https://www.kancloud.cn/wangking/uniapp/1882027#von_21) * [条件语句](https://www.kancloud.cn/wangking/uniapp/1882027#_44) * [v-if](https://www.kancloud.cn/wangking/uniapp/1882027#vif_45) * [v-show](https://www.kancloud.cn/wangking/uniapp/1882027#vshow_68) * [循环语句](https://www.kancloud.cn/wangking/uniapp/1882027#_73) * [数组循环](https://www.kancloud.cn/wangking/uniapp/1882027#_74) * [整数循环](https://www.kancloud.cn/wangking/uniapp/1882027#_100) * [计算属性](https://www.kancloud.cn/wangking/uniapp/1882027#_105) * [不带参的计算属性](https://www.kancloud.cn/wangking/uniapp/1882027#_111) * [带参的计算属性](https://www.kancloud.cn/wangking/uniapp/1882027#_140) * [computed vs methods](https://www.kancloud.cn/wangking/uniapp/1882027#computed_vs_methods_172) * [filter过滤器](https://www.kancloud.cn/wangking/uniapp/1882027#filter_210) * [监听属性](https://www.kancloud.cn/wangking/uniapp/1882027#_238) * [样式绑定](https://www.kancloud.cn/wangking/uniapp/1882027#_276) * [表单](https://www.kancloud.cn/wangking/uniapp/1882027#_319) * [输入框](https://www.kancloud.cn/wangking/uniapp/1882027#_320) * [复选框](https://www.kancloud.cn/wangking/uniapp/1882027#_341) * [单选框](https://www.kancloud.cn/wangking/uniapp/1882027#_374) * [下拉框 (picker)](https://www.kancloud.cn/wangking/uniapp/1882027#_picker_408) * [slot 插槽](https://www.kancloud.cn/wangking/uniapp/1882027#slot__460) * [组建里只有1个插槽](https://www.kancloud.cn/wangking/uniapp/1882027#1_464) * [hello 组建 (1个插槽)](https://www.kancloud.cn/wangking/uniapp/1882027#hello__1_466) * [客户端调用](https://www.kancloud.cn/wangking/uniapp/1882027#_475) * [组建里有多个插槽](https://www.kancloud.cn/wangking/uniapp/1882027#_495) * [hello 组建 (多个插槽)](https://www.kancloud.cn/wangking/uniapp/1882027#hello___497) * [客户端调用](https://www.kancloud.cn/wangking/uniapp/1882027#_521) * [解构插槽 Prop](https://www.kancloud.cn/wangking/uniapp/1882027#_Prop_555) * [组建定义](https://www.kancloud.cn/wangking/uniapp/1882027#_558) * [客户端调用](https://www.kancloud.cn/wangking/uniapp/1882027#_579) * [$set 动态响应视图](https://www.kancloud.cn/wangking/uniapp/1882027#set__602) ## 文本插值 > 数据绑定最常见的形式就是使用“Mustache”语法 (双大括号) 的文本插值 > Mustache 不支持if else 以及for loop之类的语法,仅简单的一个 双大括号标签,官方称之为 “logic-less”,没有逻辑的模板语法 ~~~ <view>{{val? val: '0'}}</view> // 简单的三元表达式 <view>{{val / 60}}</view> // 简单的数学算数运算,当然‘加减乘除’都可以 <view>{{(val / 60) * 10 - 10+20}}</view> // 或者更复杂的算数运算 <view>{{val.split('').reverse().join('')}}</view> // 调用复杂的逻辑 <view>{{function_name('传值')}}</view> //这是一个方法的调用 ~~~ ## v-bind > v-bind:property 可简写为: :property ~~~ <view :id="'nick'+id" :class="{active:true,error:true}">2222</view> <radio value="1" :checked="status == 1" /><text>3333</text> ~~~ ## v-on > v-on:event 可简写为: @event ~~~ <template> <view class="content"> <button type="default" @tap="myclick">点击我</button> </view> </template> <script> export default { data() { return {} }, methods:{ myclick:function(){ console.log('u click me') } } } </script> ~~~ ## 条件语句 ### v-if ~~~ <template> <view class="content"> <view class="title" v-if="name != null">1111</view> <view class="title" v-else-if="name == 'wk123'">2222</view> <view class="title" v-else-if="ok">3333</view> <view class="title" v-else-if="Math.random() > 0.5">4444</view> <view v-else>5555</view> </view> </template> <script> export default { data() { return { name : null, ok : false } } } </script> ~~~ ### v-show ~~~ <view class="title" v-show="ok">这个我的标题</view> ~~~ ## 循环语句 ### 数组循环 ~~~ <template> <view class="content"> <view v-for="(item,index) in items" :key="index"> <view>{{index}} : {{item.name}}</view> </view> <!-- <view v-for="item in items"> {{item.name}} </view> --> </view> </template> <script> export default { data() { return { items : [ {name:'user1', age:11}, {name:'user2', age:22} ] } } } </script> ~~~ ### 整数循环 ~~~ <view v-for="n in 10">{{n}}</view> ~~~ ## 计算属性 > 处理复杂逻辑,可以将其封装成计算属性方法供其调用 ~~~ <view>{{ message.split('').reverse().join('') }}</view> ~~~ ### 不带参的计算属性 ~~~ <template> <view class="content"> <view>原始数据:{{ message}}</view> <view>转化后的数据:{{ formatMessage }}</view> </view> </template> <script> export default { data() { return { message: 'wk123' } }, computed:{ formatMessage:function(){ if (this.message == 'wk123') { return this.message.split('').reverse().join(''); }else{ return 'Hello '+this.message; } } } } </script> ~~~ ### 带参的计算属性 ~~~ <template> <view class="content"> <view v-for="item in items"> {{formatMessage(item.name, 'from china')}} </view> </view> </template> <script> export default { data() { return { items:[ {name:"wk", age:11}, {name:"jj", age:22}, ] } }, computed:{ formatMessage:function(){ // 需要返回一个闭包,否则会报 formatMessage is not a function return function(name, pfrom) { return name +' '+ pfrom; } } } } </script> ~~~ ### computed vs methods > 我们可以使用 methods 来替代 computed,效果上两个都是一样的 > 但是 computed 是基于它的依赖缓存,只有相关依赖发生改变时才会重新取值,意味着多次访问 formatMessage 计算属性会立即返回之前的计算结果,而不必再次执行函数 > 而使用 methods 多次调用,函数总会重新调用执行。 ~~~ <template> <view class="content"> <view>原始数据:{{message}}</view> <view>转化后的数据1:{{formatMessage}}</view> <view>转化后的数据2:{{formatMessage2()}}</view> <button type="default" @tap="changeMessage">修改原始数据,重新渲染</button> </view> </template> <script> export default { data() { return { message: 'wk123' } }, computed:{ formatMessage:function(){ return this.message.split('').reverse().join(''); } }, methods:{ formatMessage2:function(){ return this.message.split('').reverse().join(''); }, changeMessage:function(){ this.message = 'abc123'; } } } </script> ~~~ ## filter过滤器 > Vue.js 允许你自定义过滤器,可被用于一些常见的文本格式化。过滤器可以用在两个地方:双花括号插值 ~~~ <template> <view> <view>{{name | formatData1}}</view> <view>{{name | formatData2('2020-09-22', 717)}}</view> </view> </template> <script> export default { data(){ return { name:'wk' } }, filters:{ formatData1(value){ return value + '__66' }, formatData2(value, date, rndNum){ return value + '__' + date + '___' + rndNum } } } </script> ~~~ ## 监听属性 > 我们可以通过 监听属性 watch 来响应数据的变化 ~~~ <template> <view class="content"> 千米:<input type="text" v-model="kilometers"/> 米:<input type="text" v-model="meters" /> 姓名 <input v-model="name" /> </view> </template> <script> export default { data() { return { meters:0, kilometers: 0, name: '' } }, watch:{ meters:function(val){ console.log("meter change:"+val); this.kilometers = val/ 1000; }, kilometers:function(newVal, oldVal){ console.log("kilometers change:"+newVal); this.meters = newVal * 1000 }, // es6 写法 name(newVal, oldVal){ console.log(`newVal: ${newVal}, oldVal: ${oldVal}`) } } } </script> ~~~ ## 样式绑定 ~~~ <template> <view class="content"> <!-- class支持的语法 --> <!-- 单类 --> <view :class="{active:isActive}">class最终值为:active</view> <!-- 对象 --> <view :class="{active:isActive,'text-danger': hasError}">class最终值为:active text-danger</view> <!-- 数组 --> <view :class="[activeClass, errorClass]">class最终值为:active text-danger</view> <!-- 数组:含条件 --> <view :class="[activeClass, hasError ? errorClass : '']">class最终值为:active text-danger</view> <!-- style支持的语法 --> <!-- 对象 --> <view v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }">1111</view> <!-- 数组 --> <view v-bind:style="[baseStyles,{'font-weight': 'bold', 'font-style': fontStyle }]">2222</view> </view> </template> <script> export default { data() { return { isActive : true, hasError: true, activeClass: 'active', errorClass: 'text-danger', fontSize: 30, activeColor: 'green', fontStyle:'italic', baseStyles: { color: 'green', fontSize: '30px', } } } } </script> ~~~ ## 表单 ### 输入框 > 实例中 input 和 textarea 元素中使用 v-model 实现双向数据绑定 ~~~ <template> <view class="content"> <input type="text" v-model="message" placeholder="编辑我……" /> <textarea v-model="message" placeholder="多行文本输入……" /> {{message}} </view> </template> <script> export default { data() { return { message : 'wk123' } } } </script> ~~~ ### 复选框 > 官方文档:[https://uniapp.dcloud.io/component/checkbox](https://uniapp.dcloud.io/component/checkbox) ~~~ <template> <view class="content"> <checkbox-group @change="checkboxChange"> <label> <checkbox value="wk"/><text>wk</text> </label> <label> <checkbox value="66" /><text>66</text> </label> </checkbox-group> {{name}} </view> </template> <script> export default { data() { return { name:[] } }, methods:{ checkboxChange(e) { console.log(e.detail.value); // 全部都勾选上的时候,打印为 ["wk","66"] this.name = e.detail.value; } } } </script> ~~~ ### 单选框 > 官方文档:[https://uniapp.dcloud.io/component/radio](https://uniapp.dcloud.io/component/radio) ~~~ <template> <view class="content"> <radio-group @change="radioChange"> <label> <radio value="1" :checked="status == 1" /><text>选中</text> </label> <label> <radio value="0" :checked="status == 0" /><text>未选中</text> </label> </radio-group> {{status}} </view> </template> <script> export default { data() { return { status:0 } }, methods:{ radioChange(e) { console.log(e.detail.value); // 打印为 0 / 1 this.status = e.detail.value; } } } </script> ~~~ ### 下拉框 (picker) > picker文档:[https://uniapp.dcloud.io/component/picker](https://uniapp.dcloud.io/component/picker) ~~~ <template> <view> <view class="uni-title">普通选择器</view> <picker @change="bindPickerChange" :value="index" :range="array" range-key="name" style="margin-bottom: 50rpx;"> <view class="uni-input">{{array[index].name}}</view> </picker> <view class="uni-title">时间选择器</view> <picker mode="time" :value="time" start="09:01" end="21:01" @change="bindTimeChange" style="margin-bottom: 50rpx;"> <view class="uni-input">{{time}}</view> </picker> <view class="uni-title">日期选择器</view> <picker mode="date" :value="date" :start="startDate" :end="endDate" @change="bindDateChange" style="margin-bottom: 50rpx;"> <view class="uni-input">{{date}}</view> </picker> </view> </template> <script> export default { data() { return { array: [{name:'中国'},{name: '美国'}, {name:'巴西'}, {name:'日本'}], index: 0, date: '2020-07-18', startDate:'2020-07-17', endDate:'2021-01-01', time: '12:01' } }, methods: { bindPickerChange: function(e) { console.log('picker发送选择改变,携带值为:' + e.detail.value) this.index = e.detail.value }, bindDateChange: function(e) { console.log('picker发送选择改变,携带值为:' + e.detail.value) this.date = e.detail.value }, bindTimeChange: function(e) { console.log('picker发送选择改变,携带值为:' + e.detail.value) this.time = e.detail.value } } } </script> ~~~ ## slot 插槽 > 主要用于组建封装过程中的插槽应用 > 参考文档:[https://cn.vuejs.org/v2/guide/components-slots.html](https://cn.vuejs.org/v2/guide/components-slots.html) ### 组建里只有1个插槽 #### hello 组建 (1个插槽) ~~~ <template> <view style="background-color: red;width: 100%;height: 90rpx;color: #FFF;"> <slot></slot> </view> </template> ~~~ #### 客户端调用 ~~~ <template> <view> <hello> <view style="color: blue;">aaaa</view> <view style="color: green;">bbb</view> </hello> </view> </template> <script> import hello from '../../components/hello.vue' export default { components:{ hello } } </script> ~~~ ### 组建里有多个插槽 #### hello 组建 (多个插槽) > 需要用到 “具名插槽”,就是给插槽设置具体的名称 ~~~ <template> <view> <view class="block1"> <slot name="header"></slot> </view> <view class="block2"> <slot></slot> </view> <view class="block3"> <slot name="footer"></slot> </view> </view> </template> <style> .block1,.block2,.block3{width: 100%;height: 90rpx;color: #FFF;margin-bottom: 20rpx;} .block1{background-color: red;} .block2{background-color: black;} .block3{background-color: green;} </style> ~~~ #### 客户端调用 ~~~ <template> <view> <hello> <template v-slot:header> <view>header...</view> <view>nav items...</view> </template> <view class="content"> this is content1 for default slot </view> <view class="content"> this is content2 for default slot </view> <!--<template v-slot:footer> <view>footer...</view> </template>--> <view slot="footer"> footer... </view> </hello> </view> </template> <script> import hello from '../../components/hello.vue' export default { components:{ hello } } </script> ~~~ ### 解构插槽 Prop > 将子组建里的数据,传递到父组建的插槽中使用 #### 组建定义 ~~~ <template> <view> <view class="block1"> <slot :user="user" :money="money"></slot> </view> </view> </template> <script> export default{ data(){ return { user:{name:'jack', sex:'male'}, money:12.5 } } } </script> ~~~ #### 客户端调用 ~~~ <template> <view> <hello> <!-- <template v-slot:default="{user, money}"> --> <template v-slot="{user, money}"> <view>{{user.name}}, dollar:{{money}}...</view> <view>nav items...</view> </template> </hello> </view> </template> <script> import hello from '../../components/hello.vue' export default { components:{ hello } } </script> ~~~ ## $set 动态响应视图 > 当给对象新增属性,在控制台能打印出来,但是却没有更新到视图上时,这个时候需要用到this.$set()这个方法来动态响应视图 > 语法:`Vue.set( target, propertyName/index, value )`, > 官方文档:[https://cn.vuejs.org/v2/api/#Vue-set](https://cn.vuejs.org/v2/api/#Vue-set) ~~~ <template> <view> <view v-for="(item,index) in list" :key="index"> index:{{index}},{{item.name}} </view> <view>---------------------</view> <view> {{person.name}}, {{person.age}} </view> <button type="default" @click="addProp">新增属性</button> </view> </template> <script> export default { data() { return { list: [ {name:'xxx1'}, {name:'xxx2'}, {name:'xxx3'} ], person: { name:'wk' } } }, methods: { addProp() { // 直接新增属性,console里可以看到数据变化,但是视图不会响应变化 /* this.list[3] = {name:'xxccc'} this.person.age = 11 console.log(this.list) console.log(this.person) */ // 使用$set ,视图响应变化 this.$set(this.list, 3, {name:'xxccc'}) this.$set(this.person, 'age', 11) console.log(this.list) console.log(this.person) } } } </script> ~~~