路飞项目 1.vue框架: 前台html+css+js框架,是不同于js与jq的数据框架 指令| 实例成员| vue项目 2.drf框架: django的插件,完成前后台分离项目后台接口编写的框架 序列化组件| 三大认证组件| 分页,筛选,过滤,排序|请求,解析,响应 3.路飞项目: 前台vue完成,后台由drf框架完成前后台分离项目 git| 短信认证| celery异步任务| 项目上线 ----------------------------------------------------------------------------------- js对象(字典)补充: let b = 20; let dic = { a:10, //字典本身就是对象,key都是字符串形式可以省略引号 b(b:b) // 值为变量时,且与key同名,可以简写 }; console.log(dic) vue: 1.what是:用于构建用户界面的渐进式JavaScript框架(选择性控制) 2.why.学: 1.是三大主流框架之一: Angular React Vue 2.有先进的前端设计模式: MVVM 3.可以完全脱离服务器端,以前端代码复用的方式渲染整个页面,组件化开发 4.结合了其他框架的优点,轻量级,中文API,数据驱动,双向绑定,单页面应用 5.虚拟DOM *** 缺点:没其他两个框架完善,在趋于完善中 3.vue环境: 本地导入,cdn导入 注: 渐进式框架:根据需求,可以决定vue框架控制项目的具体方位,可以为一个标签,也可以为一个页面,甚至可以为一个项目 new Vue({el:'.xxx'}) 4.挂载点: 1.html页面:html与body不能作为挂载点,css3选择器语法 2.一个vue对象挂载点之后只索引一个匹配结果,所以通常用id标识 实例成员: 1.实例成员,data为vue环境提供数据,数据采用字典{}形式; 2.fiters: 过滤器函数fn(a,b)-----> {{a | fn(b)}} | {{a,b | fn}} 3.method:事件方法 ------------------------------------ computed: 设置 方法属性,该方法属性在页面渲染后,绑定的方法中任意变量发生改变(都被监听),都会回调绑定的方法, eg: 一个变量依赖多个变量 watch: 设置已有属性的监听事件,监听的变量改变就会回调绑定的方法啊 eg:多个变量依赖一个变量 props:声明组件的自定义属性 emit: 为组建自定义事件发送数据 指令: 文本: {{}} | v-text | v-html 事件: v-on:click="clickAction" | @click="clickAction" | @click="clickAction($event)" 属性: v-bind:stylt="myStyle" | :class="[c1,c2]" | :class="{active: isActive}" 表单指令: v-model="变量" ----------------------------- v-once: v-cloak: 防止页面加载 抖动 v-show: 绑定的页面为布尔类型,隐藏时,在页面中以 display:none 渲染 v-if|v-else-if|v-else: 前分支成立会屏蔽后分支,else分支不需要条件 v-for: 遍历 字符串: v-for="(ch,index) in str" 数组: v-for="(ele,index) in arr" 对象: v-for="(value,key,index) in obj" 组件: 1.定义:一个包含html,css,js独立的集合体,可以完成页面解析的代码复用 2.组件分为根组件,全局组件,局部组件 根组件: 全局组件: vue.component("组件名",{实例成员萌}) 局部组件:必须在使用该组件的父组件中注册 let 组件名 = {实例抽根烟} 3.组件都有自己template(根组件可以省略采用挂在点), 子组件可以复用,所以数据要做局部化处理data(){ return{} }: 在哪个组件模板中出现的变量,就由当前组件提供变量对应 的值 4.组件信息交互 父传子:提供绑定自定义属性 子传父:提供自定义事件携带 Vue 项目搭建: 1.安装 node 官网下载安装包,傻瓜式安装:https://nodejs.org/zh-cn/ 2.换源安装cnpm npm install -g cnpm --registry=https://registry.npm.taobao.org 3.安装脚手架 cnpm install -g @vue/cli 4.如果2或3安装出错 清除缓存处理 npm cache clean --force Vue 项目创建: vue create 项目名; 在pycharm中配置npm项目 项目目录 main.js:程序的入口文件 加载vue环境 加载插件环境: 路由,仓库,ajax,cookie,element-ui... 加载自定义环境:全局样式(global.css),全局配置(settings.js) 渲染根组件 .vue文件形式组件 template标签:内部有且只有一个跟标签 script标签: export default{},导出该局部内容 style标签: scope属性,实现样式的组件化 项目运行生命周期: main.js => router.js => 链接 => 页面组件 =>替换根组件中的router-view 标签完成页面渲染 => 通过 router-link | this.$router.push()切换路由 (链接) => 完成渲染组件的替换 => 页面的跳转 新建页面的三步骤: 1.创建页面组件 2.设置组件路由 3.设置路由跳转 组件的生命周期钩子:组件从生成到销毁整个过程的一些特殊时间节点回调的函数 this.$router:路由跳转 this.$route:路由数据(this.$route.path) vue-router插件:**** 路由跳转: this.$router.push('/course'); this.$router.puth({name:course}); this.$router.go(-1); this.$router.go(1); <router-link :to="/course">课程页</router-link> <router-link :to='{name:'course'}">课程页</router-link> 路由传参 第一种: 配置:path:'/path/:pk' =>请求: '/path/${pk} =>取值:this.$route.params.pk 第二种: 配置:path:'/path',name='path' =>请求:{name:'path',query={pk:值}} =>取值 this.$route.query.pk 完成跨组件传参的方式: 1. localStarage: 永久存储数据 2. sessionStorage: 临时存储数据(刷新页面数据不重置) 3. cookie: 临时或永久数据(由过期时间决定) 4. vuex的仓库(store.js): 临时存储数据(刷新页面数据重置) vuex仓库插件*** store.js配置文件 export default new Vuex.Store({ state: { title: '默认值' }, mutations: { // mutations 为 state 中的属性提供setter方法 // setter方法名随意,但是参数列表固定两个:state, newValue setTitle(state, newValue) { state.title = newValue; } }, actions: {} }) 在任意组件中给仓库变量赋值 this.$store.state.title = 'newTitle' this.$store.commit('setTitle','newTitle') 在任意组件中取仓库变量的值 console.log(this.$store.state.title) vue-cookie插件:*** 安装: >:cnpm install vue-cookies main.js配置: 第一种: import cookies from 'vue-cookies' // 导入插件 Vue.use(cookies); // 加载插件 new Vue({ // ... cookies, // 配置使用插件原型 $cookies }).$mount('#app'); 第二种***** import cookies from 'vue-cookies' // 导入插件 Vue.prototype.$cookies = cookies; // 直接配置插件原型 $cookies 使用: 增(改): key,value,exp(过期时间) 时间: 1s | 1m | 1h | 1y this.$cookies.set('token',token,'1y'); 查:key this.$cookies.get('token'); 删: key this.$cookies.remove('token') 注: cookie一般是用来存储token的 1.token: 安全认证的随机字符串 2.有后台产生,存储于后台的(session表中,文件,内存缓存),存储于前台的(cookie中) 3.服务器先生成反馈给前台(登录认证过程), 前台提交给后台完成认证(需要登录后的请求) 4.前后台分离项目:后台生成token,返回给前台 ==>前台自己存储, 发送携带token请求 ==> 后台完成token校验 ==>后台得到登录用户 axios插件:**** 安装: cnmp install axios main.js配置: import axios from 'axios' //导入插件 Vue.prototype.$axios = axios; 直接配置插件原型 使用: this.axios({ url:'请求接口', method:'get|post', data:{post提交的数据}, params:{get提交的数据}, header:{请求头} }).then(function(response){ 请求成功的回调函数}).catch(function(error){ 请求失败的回调函数}) 案例: // get请求 this.$axios({ url: 'http://127.0.0.1:8000/test/ajax/', method: 'get', params: { username: this.username } }).then(function (response) { console.log(response) }).catch(function (error) { console.log(error) }); // post请求 this.$axios({ url: 'http://127.0.0.1:8000/test/ajax/', method: 'post', data: { username: this.username } }).then(function (response) { console.log(response) }).catch(function (error) { console.log(error) }); 跨越问题(同源策略): 后台接收到前台的请求,可以接收前台数据与请求信息,发现请求的信息不是自身服务器发来的请求,拒绝响应数据,这种情况称之为 - 跨域问题(同源策略 CORS) 导致跨域情况有三种 1) 端口不一致 2) IP不一致 3) 协议不一致 Django如何解决 - django-cors-headers模块 1) 安装:pip3 install django-cors-headers 2) 注册: INSTALLED_APPS = [ ... 'corsheaders' ] 3) 设置中间件: MIDDLEWARE = [ ... 'corsheaders.middleware.CorsMiddleware' ] 4) 设置跨域: CORS_ORIGIN_ALLOW_ALL = True element-ui插件: 下载=>配置=>使用 下载: cnpm install element-ui 配置main.js: import ElementUI from 'element-ui' import 'element-ui/lib/theme-chalk/index.css'; Vue.use(ElementUI); 使用: 依照官网 https://element.eleme.cn/#/zh-CN/component/installation api
组件间的交互
父传子: <head> <meta charset="UTF-8"> <title></title> <style> .info { text-align: center; width: 200px; padding: 3px; box-shadow: 0 3px 5px 0 pink; float: left; margin: 5px; } .info img { width: 200px; } </style> </head> <body> <div id="app"> <info v-for="info in infos" :key="info.image" :myinfo="info"></info> </div> </body> <script src="js/vue.js"></script> <script> // 伪代码:模拟数据从后台请求 /* let infos = ''; document.onload = function () { $.ajax({ url: '/images/', type: 'get', success (response) { infos = response.data } }) }; */ let infos = [ { image: 'img/001.png', title: '小猫' }, { image: 'img/002.png', title: '蛋糕' }, { image: 'img/003.png', title: '蓝糕' }, { image: 'img/004.png', title: '恶犬' }, ]; let info = { template: ` <div class="info"> <img :src="myinfo.image" alt=""> <p><b>{{ myinfo.title }}</b></p> </div> `, props: ['myinfo'] }; // 数据交互 - 父传子 - 通过绑定属性的方式 // 1) 父组件提供数据 // 2) 在父组件模板中,为子组件标签设置自定义属性,绑定的值有父组件提供 // 3) 在子组件实例中,通过props实例成员获得自定义属性 new Vue({ el: '#app', components: { info, }, data: { infos, } }) </script>
子传父: <head> <meta charset="UTF-8"> <title></title> <style> .close:hover { cursor: wait; color: red; } </style> </head> <body> <div id="app"> <p> <input type="text" v-model="userMsg"> <button @click="sendMsg">留言</button> </p> <ul> <msg-li @remove_msg="removeAction" v-for="(msg, i) in msgs" :msg="msg" :index="i" :key="msg"></msg-li> </ul> </div> </body> <script src="js/vue.js"></script> <script> let msgLi = { template: ` <li> <span class="close" @click="deleteMsg(index)">x </span> <span>第{{ index + 1 }}条:</span> <span>{{ msg }}</span> </li> `, props: ['msg', 'index'], methods: { // 系统的click事件 deleteMsg(i) { // $emit('自定义事件名', 参数们) this.$emit('remove_msg', i); this.$emit('myclick', 1, 2, 3, 4, 5) } } }; // 组件交互-子传父 // 1) 数据由子组件提供 // 2) 子组件内部通过触发系统事件,发送一个自定义事件,将数据携带出来 // 3) 父组件位子组件标签的自定义属性通过方法实现,就可以通过参数拿到子组件传递处理的参数 new Vue({ el: '#app', data: { msgs: [], userMsg: '' }, methods: { sendMsg() { if (this.userMsg) { this.msgs.push(this.userMsg); this.userMsg = ""; } }, removeAction(i) { this.msgs.splice(i, 1) } }, components: { msgLi } }) </script>