test() //函数调用表达式
var obj = {name:'wt'}; var arr = [123,'bai']; obj.name //属性调用表达式 arr[0] //属性调用表达式
let name = 'wutao'; name //变量调用表达式
123 //数值字面量表达式 'wtao' //字符串字面量表达式 true //布尔字面量表达式 null //空表达式 undefined //未定义表达式 {name:'wt'} //对象字面量表达式 [123,true] //数组字面量表达式
a + 1 //算术表达式 b * 1 //算术表达式
conidion ? name : title
// 语法: 双大括号{{}} // 使用场景: 标签内容处使用 // 单向数据绑定 // 支持JS表达式 <div id="app"> {{msg}} <div>{{getContent()}}</div> </div> <script> const vue = new Vue({ el: '#app', data: { msg: 'who is this' }, methods: { getContent: function(){ return 'wtao'; } } }); </script>
插值 与 v-text 区别
二者都是在标签内容处插入内容,但v-text是全量插入,而插值更灵活,除了全量插入,还可使用部分插入
推荐只要使用插值
就能够了
是模板语法重中之重,经常使用以下
v-text //使用插值替代 v-html v-show v-if //条件判断 v-else v-else-if v-for //循环 v-on //绑定事件 v-bind //绑定属性 v-model //双向数据绑定 v-pre v-cloak v-once
// 单向数据绑定 // 支持JS表达式 // 使用指令v-bind,需传入标签属性做为参数,例如:v-bind:title="" <div id="app"> <div title="你好" :title="go">xxx</div> <p :title="test()"></p> </div> <script> const vue = new Vue({ el: '#app', data: { go: '振东', test: function(){ return 'xxx'; } } }); </script>
出现上面的状况,属性谁后谁显示,原理是后面替代前面
, 若是title在:title后面,那单向数据绑定失效
若是是使用函数,必须后面加括号调用()
一、数值型 :title="123" 等同于 title="123" 二、布尔型 :title="true" 等同于 title="true" //false时,属性消失 三、字符串 :title="'go'" 等同于 title="go" 四、对象 :title="{name:'wt'}" 等同于 title="[Object object]" 五、数组 :title="[123,true,'bb']" 等同于 title="true,ok,123"
<div id="app"> <div v-html="title" @click="fngo"></div> <div v-html="title" @click="getUser"></div> </div> <script> var vm = new Vue({ el: '#app', data: { name:'wt', title: '<h1>试试</h1>', fngo: function(){ console.log(this); // this表明window } }, methods: { getUser: function(){ console.log(this); // this表明Vue实例 } } }); </script>
注意若是改成以下代码,this将发生变化
<div id="app"> <div v-html="title" @click="fngo()"></div> <div v-html="title" @click="getUser"></div> </div> <script> var vm = new Vue({ el: '#app', data: { name:'wt', title: '<h1>试试</h1>', fngo: function(){ console.log(this); // this表明Vue实例 } }, methods: { getUser: function(){ console.log(this); // this表明Vue实例 } } }); </script>
全部函数(方法)的定义,强烈推荐放在methods里,不要定义到data里面
// 单向数据绑定 // 支持JS表达式 <div v-if="0"></div> //数字0 --> false <div v-else-if="'0'"></div> //字符串0 ---> true <div v-else></div>
注意点:
一、对象和数组转boolean都是true
二、空字符串转boolean是false
三、null、underfined、NaN转boolean是false
四、数值0是false
let arr = [] if(arr){ console.log('true'); } if(arr == fasle){ console.log('true'); // ==两边转数值 }
// 单向数据绑定 // 支持JS表达式 // items能够是数字、字符串、数组、对象 <ul id="example-1"> <li v-for="item in 15"> {{ item.message }} </li> </ul> <ul id="example-1"> <li v-for="(item,key) in 'abcd'"> {{ item }} : {{ key }} </li> </ul> <ul id="example-1"> <li v-for="(item,key) in {name:'taobi',age:18}"> {{ item }} : {{key}} </li> </ul>
var obj = {}; var initValue = 'hello'; Object.defineProperty(obj,"newKey",{ get:function (){ //当获取值的时候触发的函数 return initValue; }, set:function (value){ //当设置值的时候触发的函数,设置的新值经过参数value拿到 initValue = value; } }); //获取值 console.log( obj.newKey ); //hello 输出 //设置值 obj.newKey = 'change value'; console.log( obj.newKey ); //change value console.log( initValue ); //change value
var obj = {}; var initValue = 'hello'; Object.defineProperty(obj,"newKey",{ get:function (){ //当获取值的时候触发的函数 return initValue; }, set:function (value){ //当设置值的时候触发的函数,设置的新值经过参数value拿到 initValue = value; } }); document.getElementById('txt').oninput = function(e){ obj.newKey = e.target.value; }
页面跳转 ---> 返回html 优势: 首屏速度快,SEO效果好 缺点: 页面切换慢
页面跳转 ---> JS动态渲染 优势: 页面切换快 缺点: 首屏速度慢,SEO差
根实例
与组件实例
区别一、是否有挂载 有---根实例 没---组件实例 二、文件后缀 .js---根实例 .vue--组件实例 三、写法 手动new Vue()---根实例 导出export default {}---组件实例
使用Vue构建单页应用,单页应用由Vue单文件组件组成,所谓组件指的就是Vue单文件组件(包含模板、样式、交互)
模块指的就是JS模块
(单纯包含JS代码)
使用ES6模块化导入 一、路径问题 nodejs内置模块与npm安装的第三方模块,直接引用 import Vue from 'vue'; import http from 'http'; 自定义模块或自定义组件,要带路径引用 ./ 表明 当前文件所在路径 ../表明 当前文件父级所在路径 import App from './App.vue'; import App from '../App.vue'; 二、后缀问题(无后缀,先判断是不是文件,找不到再判断是不是目录) 当省略后缀,只会匹配js/json/node后缀文件 因此当你要导入css、vue单文件组件时,就必须加上后缀 若是导入的是文件夹(包),将按以下顺序查找: <1>查找 package.json 下是否认义了 main 字段,是则读取 main 字段下定义的入口。 <2>若是没有 package.json 文件,则读取文件夹下的 index.js 或者 index.node。 <3>若是都 package.json、index.js、index.node 都找不到,抛出错误 Error: Cannot find module 'some-library'。
连接描述css
组件与模块最大区别是:
是否要注册
使用流程 组件(.vue): 导入——>注册——>使用 模块(.js): 导入——>使用
一、嵌套关系(父子、爷孙) 二、非嵌套关系(兄弟、表叔与我)
一、模板 <template> 0~1个 二、脚本 <script> 0~1个 三、样式 <style> 0~n个
一、父子组件间通讯 1>经过props 父向子传递数据,单向,响应 2>经过引用 $root/$refs/$parent/$children 3>经过自定义事件 $on/$emit/$once/$off 4>经过vuex (推荐) 二、兄弟组件间通讯 1>经过事件 $on/$emit/$once/$off 2>经过vuex (推荐)
原则:
谁发起自定义事件,谁就注册处理自定义事件函数
// 父级 this.$refs.customComp.$on('custom-event',function(){}); // 子级 this.$emit('custom-event');
还有另一种写法
一、安装 npm i vuex -S 二、导入 import Vue from 'vue'; import Vuex from 'vuex'; 三、安装插件 Vue.use(Vuex); 四、定义一个仓库并导出 export default new Vuex.Store({ state: { count: 0 }, mutations: { increment (state) { state.count++ } } }); 五、在vue根实例中注入store import store from './store' new Vue({ router, store, render: h => h(App) }).$mount('#app')
初始化Vue根实例时,自动注入两个插件,
分别是$router与$store,之后直接this.$store使用
状态就是数据 状态的分类: 一、组件级别 --- 组件内部的数据,只容许内部操做 二、应用级别 --- 多组件共享的数据,整个应用均可以操做,并且是响应式的,适用于层级很深的
Vuex
就是 集中存储应用级别状态
在Vuex的store中如此定义 export default new Vuex.Store({ state: { count: 0 } }); 在模板中 <p>{{$store.state.count}}</p> 在脚本中 this.$store.state.count
必须使用mutation
来对Vuex存储的状态
进行修改,修改方式相似处理事件
export default new Vuex.Store({ state: { count: 0 }, mutations: { increment (state) { // state参数自动注入 state.count++ } } }); 在模板中 <button @click="$store.commit('increment')">改变</button> 在脚本中 this.$store.commit('increment')
修改要传值时,该如何写?
一、只能传一个参数,建议传一个对象,代码以下: export default new Vuex.Store({ state: { count: 0 }, mutations: { increment (state,payload) { // state参数自动注入 state.count += payload.num; } } }); 在模板中 <button @click="$store.commit('increment',{num:12})">改变</button> 在脚本中 this.$store.commit('increment',{num:12});
使用注意
一、不要在组件中直接在data选项中绑定状态,以下 export default { name: 'about', data() { return { title: this.$store.state.num } } } 若是修改状态后,data中数据不会发生响应,所以推荐使用计算属性,代码修改以下 export default { name: 'about', data() { return { } }, computed: { title(){ return this.$store.state.num; } } }
单页应用,遇到第一个<router-view>标签
开始适配/
根路由 若是<router-view>中有<router-view>,那必需要配有嵌套路由,不然里面的<router-view>没有内容