仿有赞后台+vue+ts+vuecli3.0+elementUi+四期vueX的使用+图片上传+富文本编译器
栏目: JavaScript · 发布时间: 6年前
内容简介:今天把整个项目剩余都讲完,后面将会学习一下react,然后用react写个后台,然后浅谈一下使用心得,以及学习技巧当前项目demo预览游泳健身了解一下:首先我们先在图形话界面去下载当前需要到依赖(版本号以及axios都需要一致不知道可以去我们都第一章看看
今天把整个项目剩余都讲完,后面将会学习一下react,然后用react写个后台,然后浅谈一下使用心得,以及学习技巧当前项目demo预览
游泳健身了解一下: github
JQ插件
技术文档
技术文档会持续更新
内容总结
- vueX的使用 //划重点
- 图片上传(批量上传)
- 分页的使用
- 重制按钮的分装
- 富文本编译器 //划重点
1.vueX的使用(划重点
首先我们先在图形话界面去下载当前需要到依赖(版本号以及axios都需要一致不知道可以去我们都第一章看看
先建4个文件,我一个文件一个文件讲,观众老爷耐心听
1. state
文件(不了解的可以先去看下 vuex
官网 )
这里我们把全局的变量放里面(说一下不是为了用vuex才用vuex的,有些项目完全可以不用当然可以不用)
import { getToken, setToken, removeToken } from '@/views/utils/auth' const state: any = { token: getToken(), imgUrl: 'https://api.uat.iyuedian.com/iyd-imall-manage/imall/v1/upload' } export default state 复制代码
2. mutations
文件
这个文件就是提交改变当前的 state
里面的值的不懂 interface
的可以看下慕课网
export default mutations{ ## 老方法 SET_TOKEN(state: any, data: any) { state.token = data }, } import { MutationTree } from 'vuex' ## 新方法 MutationTree<any> 相信应该有些人不理就是一个接口 const mutations: MutationTree<any> = { 'SET_TOKEN'( state: any, data: any ): void { state.token = data } } 复制代码
vuex 里面的源码可以看一下
3. actions
文件
这个文件可以执行 mutations
文件里面的方法公共的方法都可以放到这个里面 async
定义一个一步函数总是实际返回值总是一个 Promise 对象
import { sysUserLogin } from '@/views/interface/login'; import { getToken, setToken, removeToken } from '@/views/utils/auth'; import { ActionTree } from 'vuex'; import { Message } from 'element-ui'; const actions: ActionTree<any, any> = { /** * 登陆 * @param param0 * @param userInfo 登陆信息 */ async Login({state, commit} , userInfo: any) { return new Promise((resolve, reject) => { sysUserLogin(userInfo).then((response: any) => { setToken(response.data.systoken); console.log(response.data.systoken); commit('SET_TOKEN', response.data.systoken); ## 这边调用了上面的方法 resolve(response); }).catch((error) => { reject(error); }); }); }, /** * 深拷贝 * @param param0 * @param params */ async deep({state, commit} , params: any) { let obj = {}; obj = JSON.parse(JSON.stringify(params)); return obj; }, }; export default actions; 复制代码
4. getters
文件
getters
可以定义是 store
的计算属性可以将 state
进行过滤然后 return
出来
## 老方法 export default { token: (state:any) => state.token, } ## 新方法 import {GetterTree} from 'vuex' const mutations: GetterTree<any,any> = { 'token'( state: any, ): any { return state.token } } export default mutations 复制代码
vuex
使用方式 vuex-class
## 获取state的值 (先要定义一遍才可以使用) @State imgUrl @Action('Login') Login; @Getter('Login') getterFoo; @Mutation('Login') mutationFoo; // 简写方式 @State foo @Getter bar @Action baz @Mutation qux //最先开始执行 created() { ## 后面的是原来的使用方式 console.log(this.imgUrl); // -> this.store.state.imgUrl console.log(this.getterFoo(2)) // -> this.store.getters.Login this.Login({ value: true }).then() // -> this.store.dispatch('Login', { value: true }) this.mutationFoo({ value: true }) // -> this.store.commit('Login', { value: true }) } 复制代码
2.图片上传(以及批量的图片上传
这里我们用的是element的图片上传 如有不懂的可以看下 element
的组件
单张图片上传
我们想要更佳简便的使用方式
// 单张图片上传(组件) <template> <div> <el-upload class="avatar-uploader" :action="$store.state.imgUrl" ## 我们图片上传的地址 :show-file-list="false" :on-success="handleAvatarSuccess" :before-upload="beforeAvatarUpload"> <img v-if="BeforeUploadImg" :src="BeforeUploadImg" class="avatar"> <i v-else class="el-icon-plus avatar-uploader-icon"></i> </el-upload> </div> </template> <script lang="ts"> import { Component, Vue, Model, Watch, Prop } from 'vue-property-decorator'; @Component export default class BeforeUpload extends Vue { ## 初始值 @Prop(String)BeforeUploadImg:string; ## 生命周期最先开始执行 void 表示没有返回值 created():void { } public handleAvatarSuccess(res:any, file:any) { ## 本地图片预览; update: 这样配合父组件可以实现父子组件的双向绑定 this.$emit('update:BeforeUploadImg',res.data[0].newFileName); } public beforeAvatarUpload(file:any) { // const isJPG = file.type === 'image/jpeg'; const isLt2M = file.size / 1024 / 1024 < 2; // if (!isJPG) { // this.$message.error('上传头像图片只能是 JPG 格式!'); // } if (!isLt2M) { this.$message.error('上传头像图片大小不能超过 2MB!'); } // return isJPG && isLt2M; return isLt2M; } } </script> # 使用方式 # html .sync 配合update可以实现双向绑定 <BeforeUpload :BeforeUploadImg.sync="BeforeUploadImg"></BeforeUpload> # script import BeforeUpload from '@/components/beforeUpload/beforeUpload.vue'; import { Component, Vue, Model, Watch, Prop } from 'vue-property-decorator'; @Component({ components: { BeforeUpload, } }) export default class Content extends Vue { ## 默认图片 public BeforeUploadImg: string = ''; } 复制代码
批量图片上传
我们想要更佳简便的使用方式
// 批量图片上传(组件) <template> <div> <el-upload class="upload-demo" :action="$store.state.imgUrl" :on-preview="handlePreview" :on-success="handleOnSuccess" :on-remove="handleRemove" :file-list="UploadListsImg" list-type="picture"> <el-button size="small" type="primary">点击上传</el-button> <div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过1024kb</div> </el-upload> </div> </template> <script lang="ts"> import { Component, Vue, Model, Watch, Prop } from 'vue-property-decorator'; @Component export default class UploadListImg extends Vue { // 初始值 @Prop(null)UploadListsImg:object[]; //最先开始执行 created():void { // tinyMce.init({}) } /** * 删除图片 * @param file 删除的图片 * @param fileList 剩下的图片 */ public handleRemove(file:any, fileList:any) { console.log(file, fileList); this.$emit('update:UploadListsImg',fileList) this.$emit('removeListImg',file) } public handlePreview(file:any) { console.log(file); } /** * 添加图片 * @param response 成功的返回值 * @param file 当前的这个图片 * @param fileList 当前所有的图片 */ public handleOnSuccess(response:any, file:any, fileList:any){ file.url = response.data[0].newFileName; file.name = response.data[0].originalFilename; this.$emit('update:UploadListsImg',fileList) } } </script> ## html UploadListsImg为当前剩下的图片的list removeListImg为删除掉的list 使用方式 <UploadListImg :UploadListsImg.sync="UploadListsImg" @removeListImg="removeListImg" style="width: 400px"></UploadListImg> ## script import UploadListImg from '@/components/uploadListImg/uploadListImg.vue'; import { Component, Vue, Model, Watch, Prop } from 'vue-property-decorator'; @Component({ components: { UploadListImg, } }) export default class Content extends Vue { public UploadListsImg: object[] = [ { name: 'food.jpeg', url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100' }, { name: 'food2.jpeg', url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100' } ]; public removeListImg: object[] = [] } 复制代码
3.分页的使用
分页我们想要更加简便的使用方式
// 分页组件 <style scoped lang="scss"> .t-pagination{ width: 100%; overflow: hidden; } .t-pagination-content{ float: right; margin: 20px; } </style> <template> <div class="t-pagination"> <div class="t-pagination-content"> <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="currentPage4" :page-sizes="[10, 20, 30, 40, 100]" :page-size="pageSize" layout="total, sizes, prev, pager, next, jumper" :total="Paginationtotal"> </el-pagination> </div> </div> </template> <script lang="ts"> import Utils from '@/utils/utils' import { Component, Vue, Model, Prop, Watch } from 'vue-property-decorator'; @Component export default class Reset extends Vue { // props声明 @Prop() private Paginationtotal!: number; private pageSize:number = 20; private currentPage4:number = 1; //最先开始执行 created():void { if (this.$route.query.pageNum) { this.currentPage4 = Number(Utils.deep(this.$route.query.pageNum)); this.pageSize = Number(Utils.deep(this.$route.query.pageSize)); }else { this.currentPage4 = 1; this.pageSize = 20; } } //监听路由变化 @Watch('$route') onRouteChanged(route: any, oldRoute: any) :void { if (route.query.pageNum) { this.currentPage4 = Number(Utils.deep(route.query.pageNum)) this.pageSize = Number(Utils.deep(route.query.pageSize)); }else { this.currentPage4 = 1; this.pageSize = 20; } this.$forceUpdate()//强刷当前 } private handleSizeChange(val:any) { let data:any = Utils.deep(this.$route.query); [data.pageNum,data.pageSize] = [1,val] this.start(data) console.log(`每页 ${val} re条`); } private handleCurrentChange(val:any) { let data:any = Utils.deep(this.$route.query); data.pageNum = val data.pageSize = this.pageSize this.start(data) console.log(`当前页: ${val}re`); } private start(ret:any) { this.$store.dispatch('paramsUrl',ret).then((res:any) => { this.$router.push(`${this.$route.path}${res}`) }) } } </script> # html 使用方式 <Pagination :Paginationtotal="Paginationtotal"></Pagination> # script import Pagination from '@/components/pagination/pagination.vue'; import { Component, Vue, Model, Watch, Provide } from 'vue-property-decorator'; @Component({ components: { Pagination } }) export default class Content extends Vue { Paginationtotal:number = 0; } 复制代码
4.重制按钮的分装
我们重置只需要把当前的分页重置成第一页 20跳数据即可
// 重置按钮 <template> <el-button size="mini" @click="reset(searchReserved)">重置</el-button> </template> <script lang="ts"> import { Component, Vue, Model, Prop } from 'vue-property-decorator'; @Component({ }) export default class Reset extends Vue { // props声明 paramsUrl 为定义的当前的vuex里面的方法 @Prop() private searchReserved!:object public reset(search:any) { [search.pageNum,search.pageSize] = [1,20] this.$store.dispatch('paramsUrl',search).then((res:any) => { this.$router.push(`${this.$route.path}${res}`) }) } } </script> ## html 使用方式 <Reset :searchReserved="searchReserved"></Reset> ## script import Reset from '@/components/reset/reset.vue'; @Component({ components: { Reset } }) export default class Content extends Vue { searchReserved = {} } 复制代码
5.富文本编译器
关于富文本编译器,我想大家应该不陌生了,我推荐一筐 tinyMce
来使用到我们当前到项目里面来富文本编译器 ts
都支持还不是多,我找来很多来尝试,最后决定用 tinyMce
下载一下这两个,中间踩了很多坑,给我们伸手党线上开箱即食的代码把
把cdn放上速度更快
重要的说一下我们的静态的这个文件放public 下面这个一定要放这,下面的这个一定要放进去不然页面食用不了 文件链接
## 富文本编译器 ## EditorContent 默认值 onChangeHandler 改变的事件 editorInit 初始配置 ## 基本上图片上传都需要form表单方式上传 FormData <template> <div> <Editor :initial-value="EditorContent" @onChange="onChangeHandler" id="tinyMce" :init="editorInit"></Editor> </div> </template> <script lang="ts"> import 'tinymce/themes/modern/theme'; import Editor from '@tinymce/tinymce-vue'; import { Component, Vue, Model, Watch, Prop } from 'vue-property-decorator'; @Component({ components: { Editor } }) export default class Content extends Vue { // 父组件传进来的html @Prop(String) EditorContent: any; // 初始值 public initialVal:any = ''; public editorInit:any = { language_url: './static/zh_CN.js', language: 'zh_CN', selector: 'textarea', skin_url: './static/skins/lightgray', height: 300, // width:600, images_upload_url: 'https://api.uat.iyuedian.com/iyd-imall-manage/imall/v1/upload', plugins: 'link lists image code table colorpicker textcolor wordcount contextmenu', toolbar: 'bold italic underline strikethrough | fontsizeselect | forecolor backcolor | alignleft aligncenter alignright alignjustify | bullist numlist | outdent indent blockquote | undo redo | link unlink image code | removeformat', images_upload_handler: function (blobInfo:any, success:any, failure:any) { let xhr:any, formData:any; xhr = new XMLHttpRequest(); xhr.withCredentials = false; xhr.open('POST', this.$store.state.imgUrl); xhr.onload = function() { if(xhr.status<200||xhr.status>=300){ failure(xhr.status); return; } let json = JSON.parse(xhr.responseText); if(json.code==0){ success(json.data[0].newFileName); } else { failure('HTTP Error: ' + json.msg); } }; formData = new FormData(); formData.append('file', blobInfo.blob(), blobInfo.filename()); xhr.send(formData); }, // images_upload_url: 'https://api.iyuedian.com/iyd-imall-manage/imall/v1/upload' } //最先开始执行 created():void { // tinyMce.init({}) } //监听路由变化 @Watch('$route') onRouteChanged(route: any, oldRoute: any) :void { this.$forceUpdate() } /** * 富文本内容变化时事件 */ public onChangeHandler(res:any,index:any,tag:any){ //width height小程序不支持这个把这个替换了 let html = res.level.content.replace("width","xxx") html = html.replace("height","yyy") // console.log(html) this.$emit('update:EditorContent',html) } } </script> ## html 使用方式 <Editor :EditorContent.sync="EditorContent"></Editor> ## script import Editor from '@/components/tinyMceEditor/tinyMceEditor.vue'; @Component({ components: { Editor } }) export default class Content extends Vue { // 默认图文详情 public EditorContent: string = ''; } 复制代码
以上所述就是小编给大家介绍的《仿有赞后台+vue+ts+vuecli3.0+elementUi+四期vueX的使用+图片上传+富文本编译器》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- LLVM接受NVIDIA的“f18” Fortran编译器作为官方Fortran编译器
- 编译原理实战入门:用 JavaScript 写一个简单的四则运算编译器(四)结语
- Scala.js 0.6.29 发布,将 Scala 编译成 js 的编译器
- Go 编译器介绍
- Go 编译器介绍
- C++编译器优化
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Search User Interfaces
Marti A. Hearst / Cambridge University Press / 2009-9-21 / USD 59.00
搜索引擎的本质是帮助用户更快、更方便、更有效地查找与获取所需信息。在不断改进搜索算法和提升性能(以技术为中心)的同时,关注用户的信息需求、搜寻行为、界面设计与交互模式是以用户为中心的一条并行发展思路。创新的搜索界面及其配套的交互机制对一项搜索服务的成功来说是至关重要的。Marti Hearst教授带来的这本新作《Search User Interfaces》即是后一条思路的研究成果,将信息检索与人......一起来看看 《Search User Interfaces》 这本书的介绍吧!