核心思想:
1.数据驱动 所谓的数据驱动就是当数据发生变化的时候,用户界面发生相应的变化,开发者不需要手动的去修改dom。
https://www.cnblogs.com/caizhenbo/p/6418284.html 数据驱动原理
2.组件化
1. 处理类 : 先给class加v-bind绑定 => :class , 然后再三元表达式 :class = "['mui--control-item',item.id == 0 ? ' mui-active' : ' ' ]"
2. 处理路由高亮
- : MUI库中默认的高亮是 ' mui-acrive', (推荐)
路由配置的第二个参数 用这个去覆盖默认高亮类 router-link-active
- 把router-link-active 的样式改了 (不推荐 因为要设置样式表 还要考虑优先级 很麻烦)
3. 视图切换样式 (包住路由的区域,因为只有路由在切换的时候才需要改造样式,其他都是固定的)
1 .v-enter {
2 opacity: 0;
3 transform: translateX(100%);
4 }
5
6 .v-leave-to {
7 opacity: 0;
8 transform: translateX(-100%);
9 position: absolute;
10 }
11
12 .v-enter-active,
13 .v-leave-active {
14 transition: all 0.5s ease;
15 }
<transition>
<router-view></router-view>
</transition>
4. 阻止页面切换时出现滑动条
1 .app-container {
2 overflow-x: hidden;
3 }
5.把router-link标签 指定渲染成li标签 => 加tag属性 tag= “ li ”
6.router-link跳转到带有id的地址上:
如果是普通的跳转 直接to 就行,但如果地址带有id,name就要改造to 因为item.id是一个表达式
1 <router-link v-for="item in list" :key="item.id" :to="'/home/photoinfo/' + item.id" tag="li">
7.编程式导航 意思就是用js来跳转页面,项目中用到最多的就是当点击某个按钮时判断当前登录没登录,没有登录点击的时候跳转到登录页面。距离
1 <template> 2 3 <button @click="getNews()">通过js跳转</button> 4 5 </template> 6 7 <script> 8 9 export default{ 10 11 data(){ 12 13 return{ 14 15 } 16 17 }, 18 19 methods:{ 20 21 getNews(){ 22 23 this.$router.push({path:'./login'})//这种是通过path 24 25 this.$router.push({path:'./login/1'})//这种是动态路由 26 27 this.$router.push({name:'login',params:{id:1}})//这种是命名路由,路由配置时候的name,还可以传参数 28 29 } 30 31 } 32 33 } 34 35 </script>
8.导航前进后退
this.$router.go(1);
this.$router.go(-1);
9. router-view详解 https://www.cnblogs.com/yuerdong/p/9877912.html
10.$route 和 $ router 的区别 https://www.cnblogs.com/czy960731/p/9288830.html
1. this.$router:
表示全局路由器对象,项目中通过router路由参数注入路由之后,在任何一个页面都可以通过此方法获取到路由器对象,并调用其push(), go()等方法;
2. this.$route:
表示当前正在用于跳转的路由器对象,可以调用其name、path、query、params等方法;
注:使用的时候注意拼写,两个很像,就差一个字母,经常会因为写错而导致调用的方法无效,而且浏览器的控制台中还不会报错
有时的需求是页面不直接跳转,有确认弹框或者其他事件,此时就需要在js中设置跳转,常用的一种方法是 .$router.push ,用法如下:
this.$router.push({path: '/...'});
11. v-if 和 v-show
v-if appendChild / removeChild 如果在运行时条件不大可能改变 v-if 较好。
v-show style.display = ‘block’ / ‘none ’ 如果是频繁切换,v-show较好。
v-for 优先级最大
12. v-on和v-bind
v-on:原生js的事件名 = ‘逻辑’
v-on:原生js事件名 = ‘方法名’ 该方法必须在methods內
常用
1 v-on:input 对应HTML5中新增的oninput事件 类似于onchange
v-bind:标签中的原生属性
v-bind:自定义属性
单向数据绑定 data ======> view
v-model 只能应用在表单控件 value UI控件(单选框 多选框)
13 .父子通信
ref和$ref的区别 https://www.cnblogs.com/xumqfaith/p/7743387.html
子组件传值父组件: $ref实现子组件向父组件通信 ===>如果ref用在子组件上,是作为子组件的一个索引,通过$ref可以获取到子组件里面的属性和方法。如果ref在dom元素上面使用,可以通过ref获取到该dom的属性集合。
prop和$ref的区别是: 尽管有 prop 和事件,但是有时仍然需要在 JavaScript 中直接访问子组件。为此可以使用 ref
为子组件指定一个引用 ID
prop 官网解释 https://cn.vuejs.org/v2/guide/components-props.html
prop是用于父组件向子组件传递数据(单向下行绑定)。 直接写 xx = abc 静态赋值 ,v-bind:xx='list.title' 动态赋值 https://www.cnblogs.com/xiaohuochai/p/7388866.html
1 //1父组件在子组件的标签内自定义要传值的属性给子组件 2 <test1 happy='123'></test1> 3 //子组件声明后,在template中直接用插值表达式使用 4 <template> 5 <div> 6 <input type ='button' @click='info' value='点我'> 7 <span>{{happy+'hello'}} </span> 8 </div> 9 </template> 10 <script> 11 export default{ 12 data(){ 13 return { 14 foo:1 15 } 16 }, 17 props:['happy'], 18 methods: { 19 info:function(){ 20 console.log(this.happy) 21 } 22 } 23 } 24 </script>
$ref着重于子组件的索引,带领父组件查找到子组件的属性和方法,并不适合用来做数据之间的通信。
3.$emit和$ref以及$on的区别
用ref为子组件赋一个标记引用
1 <p ref="username">传值给父组件</p>
在已经定义了这个 ref
的组件里,可以使用
console.log(this.$refs.username)
来访问这个 <p>
实例,以便不时之需
http://www.cnblogs.com/developer-sue/p/9434425.html
https://blog.csdn.net/wngzhem/article/details/53409561
子组件可以通过props接收到来自父组件的数据,并且是单向绑定的。也就是说,只能收数据。
vuejs官网解释 https://cn.vuejs.org/v2/guide/instance.html
父组件使用$refs获得子组件实例
//父组件
1 <template> 2 <div id="app"> 3 <!-- <test></test> --> 4 <test1 happy='123' ref="btn"></test1> 5 <img src="./assets/logo.png"> 6 <input type='button' value='聚焦子组件' @click='focus'></input> 7 </div> 8 </template> 9 10 <script> 11 import test from './components/test' 12 import test1 from './components/test1' 13 export default { 14 name: 'App', 15 components:{ 16 test, 17 test1 18 }, 19 data(){ 20 return { 21 foo:2 22 } 23 }, 24 methods: { 25 baz: function () { /* ... */ }, 26 focus: function () { 27 console.log(this.$refs.btn.dangerous) 28 //console.log(this.$refs.btn) 29 } 30 } 31 } 32 </script>
子组件
1 <template> 2 <div> 3 <input type ='button' @click='info' value='点我'> 4 <span>{{happy+'hello'}} </span> 5 <p ref="username">传值给父组件</p> 6 </div> 7 </template> 8 <script> 9 export default{ 10 data(){ 11 return { 12 foo:1,
//这里的值将被父组件得到 13 dangerous: '危险的' 14 } 15 }, 16 props:['happy'], 17 methods: { 18 info:function(){ 19 //console.log(this.happy) 20 console.log(this.$refs.username) 21 } 22 } 23 } 24 </script>
切记: 想用ref 获取那个子组件的实例 就在那个子组件的标签上添加ref属性,要传那个属性给儿子就在那个儿子身上绑定自定义属性(props接收)
$emit 子组件给父组件传值 $on监听当前实例$emit事件
1 vm.$on('test', function (msg) {
2 console.log(msg)
3 })
4 vm.$emit('test', 'hi')
5 // => "hi"
父组件模板:
1 <template> 2 <div id="app"> 3 <!-- <test></test> --> 4 <h1>{{title}}</h1> 5 <test1 happy='123' ref="btn" @getMessage="showMsg"></test1> 6 <img src="./assets/logo.png"> 7 <input type='button' value='聚焦子组件' @click='focus'></input> 8 </div> 9 </template> 10 11 <script> 12 import test from './components/test' 13 import test1 from './components/test1' 14 export default { 15 name: 'App', 16 components:{ 17 test, 18 test1 19 }, 20 data(){ 21 return { 22 foo:2, 23 title:'标题为空' 24 } 25 }, 26 methods: { 27 baz: function () { /* ... */ }, 28 focus: function () { 29 console.log(this.$refs.btn.dangerous) 30 //console.log(this.$refs.btn) 31 }, 32 showMsg:function(title){ 33 this.title =title 34 } 35 } 36 } 37 </script>
子组件模板:
1 <template> 2 <div> 3 <input type ='button' @click='info' value='点我'> 4 <input type ='button' @click='click' value='改标题'> 5 <span>{{happy+'hello'}} </span> 6 <p ref="username">传值给父组件</p> 7 </div> 8 </template> 9 <script> 10 export default{ 11 data(){ 12 return { 13 foo:1, 14 dangerous: '危险的' 15 } 16 }, 17 props:['happy'], 18 methods: { 19 info:function(){ 20 //console.log(this.happy) 21 console.log(this.$refs.username) 22 }, 23 click:function(){ 24 this.$emit('getMessage', '标题被我改回来了') 25 } 26 }, 27 mounted(){ 28 this.$emit('getMessage', '标题被我占了') 29 } 30 31 } 32 </script>
三点对比 :
- prop 着重于数据的传递,它并不能调用子组件里的属性和方法。像创建文章组件时,自定义标题和内容这样的使用场景,最适合使用prop。
- $ref 着重于索引,主要用来调用子组件里的属性和方法,其实并不擅长数据传递。而且ref用在dom元素的时候,能使到选择器的作用,这个功能比作为索引更常有用到。
- 前门两种方法主要都是父组件向子组件通信,而通过$emit 实现子组件向父组件通信
15. watch 用来监测Vue实例上的数据变动。
https://www.cnblogs.com/jin-zhe/p/9319648.html
16.v-bind:key 增删或切换顺序时提高性能
17.template嵌套template
template不会渲染成元素,用div的话会被渲染成元素。把if,show,for等语句抽取出来放在template上面,把绑定的事件放在temlpate里面的元素上,可以使html结构更加清晰,还可以改善一个标签过长的情况
1.vue-cli脚手架里面的 vue ui
1 首先安装 最新的vue-cli cnpm install -g @vue/cli 2 Terminal 输入vue ui命令
18. watch :{ } 监听 ,
记住了 只有data 和生命周期钩子函数 才是 (){ } ES6匿名函数写法
methods / computed / watch 都是 : { }
watch、computed、methods的对比
watch/computed 共同点: 只要数据一变化就可以监视到
1、computed不适合写大量的业务逻辑,只适合做一些简单的数据操作,然后并给它return 出去就完事了。 添油加醋的修改 不要改本身)
2、computed属性的结果会被缓存。除非依赖的响应式属性变化了才会重新计算,主要当做属性来使用。
3、methods 方法表示一个具体的操作,主要书写业务逻辑。
4、watch 是一个对象,它的键 是我们要观察的表达式,值是对应的回调函数。当前面观察的值发生变化的时候,会触发我们的回调函数。在回调函数的形参中,有两个参数:一个是newVal(最新的值),一个是oldVal(旧值)。主要用来监听某些特定数据的变化,从而进行某些具体的业务逻辑操作;可以看作是 computed 和 methods 的结合体。
5、computed和watch 都可以监视到,数据的变化。methods里只能做一些业务逻辑。watch里面也能做业务逻辑
19. vue样式的切换
官方文档 :https://cn.vuejs.org/v2/guide/class-and-style.html
实例1:
两个值相等的时候 true active生效
点击的时候 当前的curNav等于当前的content
实例2: 地图切换
效果图:
代码:
1 <div class="select-gpu"> 2 <div :class="{'gpu-type':true,active:chart_type=='gtx 1050ti'}" @click="chartHandle('gtx 1050ti')">gtx 1050ti</div> 3 <div :class="{'gpu-type':true,active:chart_type=='gtx 1080ti'}" @click="chartHandle('gtx 1080ti')">gtx 1080ti</div> 4 </div>
1 <style lang="less"> 2 .select-gpu { 3 display: inline-block; 4 margin-left: 70%; 5 .gpu-type { 6 display: inline-block; 7 background-color: #eee; 8 min- 40px; 9 padding: 0 10px; 10 text-align: center; 11 font-size: 14px; 12 border-radius: 10px; 13 margin-left: 10px; 14 cursor: pointer; 15 line-height: 22px; 16 } 17 .active { 18 color: #fff; 19 background-color: #7baaf3; 20 } 21 } 22 </style>
export default { data(){ return{ chart_type: "gtx 1050ti" } } methods:{ chartHandle(value) { if (value === "user") { this.search_type = value; } else { this.search_type = "gpu"; this.gpu = value; } this.chart_type = value; this.getGpuData(); }, }
数据切换: ======> 通过参数名的改变而改变
20.vue 组件切换
1 <div :class="{'resource-nav-item':true,active:curNavContent === item.content}" @click="tabChange(item)">
1 <component v-bind:is="curNavContent"></component>
1 navList:[{name:'艺术滤镜',content:'artFilters',description:',又称为风格迁移,可以使一张图片保持本身内容大致不变的情况下呈现出另外一张图片的风格。以往,基于PhotoShop,我们费时费力才能实现风格的转换。现在,基于最新的人工智能技术,我们可以一次性实现多种多样的、风格逼真的艺术风格变换。'}
2 ,{name:'目标检测',content:'Object',description:',是从图像中辨识感兴趣目标的类型与位置。借助于人工智能深度学习技术,我们不仅能识别人、车、动植物、常用家具等目标,还能准确地标识目标的轮廓。'}],
3 curNavContent: 'artFilters',//当前组件名
1 components: { artFilters: () => import("@/views/lab/art_filters"),
2 Object: () => import("@/views/lab/object_detection") }
1 tabChange(row) {
2 this.curRow = row;
3 this.curNavContent = row.content;
4 }
21. 插槽 slot-scope(已废弃) v-slot (2.6新增)
插槽的含义: 简单的说,插槽就是可以让开发者自定义地往子组件中放置代码片段而开发出来的东西。就好像专门在某几个地方弄了几个槽(子组件中),我们开发时,就可以在对应的槽中放置对应的代码了。
官方安装
1 # 全局安装 vue-cli 2 $ cnpm install --global vue-cli 3 # 创建一个基于 webpack 模板的新项目 4 $ vue init webpack my-project 5 # 这里需要进行一些配置,默认回车即可 6 This will install Vue 2.x version of the template. 7 8 For Vue 1.x use: vue init webpack#1.0 my-project 9 10 ? Project name my-project 11 ? Project description A Vue.js project 12 ? Author runoob <test@runoob.com> 13 ? Vue build standalone 14 ? Use ESLint to lint your code? Yes 15 ? Pick an ESLint preset Standard 16 ? Setup unit tests with Karma + Mocha? Yes 17 ? Setup e2e tests with Nightwatch? Yes 18 19 vue-cli · Generated "my-project". 20 21 To get started: 22 23 cd my-project 24 npm install 25 npm run dev 26 27 Documentation can be found at https://vuejs-templates.github.io/webpack