<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      學習vue——圖片、富文本的新增與修改回顯

       

      方法一

       1 <el-upload
       2       ref="RefUpload"
       3       class="avatar-uploader"
       4       :auto-upload="false"
       5       :show-file-list="false"
       6       :on-change="handleChange"
       7     >
       8       <img v-if="imageUrl" :src="imageUrl" class="avatar" />
       9       <el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
      10     </el-upload>
      11     
      12     <el-button type="primary" style="margin-top: 20px;" :icon="Plus" 
      13     @click="RefUpload.$el.querySelector('input').click()" <--!--點擊按鈕調出文件選擇框-->
      14     >選擇圖片</el-button>
              <el-button type="primary" style="margin-top: 20px;" :icon="Upload" @click='uploadImage'>上傳頭像</el-button>
       
       1 const imageUrl = ref() 
       4 const RefUpload = ref() // 用于按鈕調出文件選擇框
       5 const submitImage = ref()
       6 // 預覽圖片
       7 const handleChange = (file) => {
       8   imageUrl.value = URL.createObjectURL(file.raw)
       9   submitImage.value = file.raw
      10 }
      11 // 上傳圖片到后端
      12 const uploadImage = async () => {
      13   const formData = new FormData()
      14   formData.append('cover_img', submitImage.value)
      15   const { data } = await artAddChannelService(formData)
      16   console.log(data)
      17 }

       

      django

      1 from django.conf import settings
      2 import os
      3 import base64
      4 
      5 file = request.FILES.get("image")
      6 path = os.path.join(settings.STATICFILES_DIRS[0], 'xx3.jpeg')
      7 if file:
      8    with open(path, 'wb') as f:
      9                 f.write(file.open())

       

      方法二(byte)

       1 // 方法二
            const imageUrl = ref()
       2 const handleChange = (uploadFile) => {
       3   // 基于 FileReader 讀取圖片做預覽
       4   const reader = new FileReader()
       5   reader.readAsDataURL(uploadFile.raw)
       6   reader.onload = () => {
       7     imageUrl.value = reader.result
       8   }
       9 }
      10 const uploadImage = async () => {
      11   console.log(imageUrl.value)
      12   const { data } = await artAddChannelService(imageUrl.value)
      13   console.log(data)
      14 }

      django

       1 path = os.path.join(settings.STATICFILES_DIRS[0], 'xx3.jpeg')
       2 image_base64 = request.body.decode()
       3 if image_base64:
       4         # 去掉 base64 圖片數據中的前綴(如果有)
       5         image_base64 = image_base64.split(',')[1]
       6         print(image_base64)
       7         # 解碼 base64 數據
       8         file = base64.b64decode(image_base64)    
       9         if file:
      10             with open(path, 'wb') as f:
      11                 f.write(file)

      css

       1 </template>
       2 <style lang="scss" scoped>
       3 .avatar-uploader {
       4   :deep() {
       5     .avatar {
       6       width: 278px;
       7       height: 278px;
       8       display: block;
       9     }
      10     .el-upload {
      11       border: 1px dashed var(--el-border-color);
      12       border-radius: 6px;
      13       cursor: pointer;
      14       position: relative;
      15       overflow: hidden;
      16       transition: var(--el-transition-duration-fast);
      17     }
      18     .el-upload:hover {
      19       border-color: var(--el-color-primary);
      20     }
      21     .el-icon.avatar-uploader-icon {
      22       font-size: 28px;
      23       color: #8c939d;
      24       width: 278px;
      25       height: 278px;
      26       text-align: center;
      27     }
      28   }
      29 }
      30 </style>
      View Code

       

      提要

      富文本使用鏈接:https://vueup.github.io/vue-quill/

      父組件

      1 <tempalte>
      2  <!-- 抽屜  -->
      3   <drawer-page ref="open" @tijiao = EmitData></drawer-page>
      4 </template>
       1 <script lang="ts" setup>
       2 const open = ref()
       3 
       4 const EmitData = (data) => {
       5   // .get 是FromDate 的獲取方式
       6   console.log("cover_img:",data.get("cover_img"))
       7   // 子組件傳來的數據,父組件負責新增、修改
       8   artAddChannelService(data)
       9 }
      10 </script>
      // 新增
      const pubulic = () => {
        open.value.open()
      }
      // 修改
      const Edit = (row) => {
        console.log(row)
        // 調用子組件的方法open
        open.value.open(row)
      }

       

      子組件

       1 <template>
       2 <!-- 圖片 -->
       3 <el-form-item label="cover_img" prop="cover_img">
       4                     <el-upload
       5                         class="avatar-uploader"
       6                         :show-file-list="false"
       7                         :auto-upload="false"
       8                         :on-change="upImage"
       9                     >
      10                         <img v-if="imageUrl" :src="imageUrl" class="avatar" />
      11                         <el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
      12                     </el-upload>
      13 </el-form-item>
      14 <!-- 富文本 -->
      15 <el-form-item label="content">
      16                     <div class="editor">
      17                     <quill-editor ref="qedit" theme="snow"  
      18                       v-model:content="ruleForm.content" content-type="html">
      19                     </quill-editor>
      20                     </div>
      21 </el-form-item>
      22 </template>
       1 <script lang="ts" setup>
       2 import { ref } from 'vue'
       3 import { ElMessageBox } from 'element-plus'
       4 import SearchSelect from './SearchSelect.vue';
       5 import { Plus } from '@element-plus/icons-vue'
       6 import { QuillEditor } from '@vueup/vue-quill'
       7 import '@vueup/vue-quill/dist/vue-quill.snow.css';
       8 
       9 
      10 const defaultForm = {date:'',name:'',address:'',cover_img:'',content:''}
      11 const ruleForm = ref({ ...defaultForm })
      12 // 抽屜
      13 const drawer = ref(false)
      14 const cancelClick = () => {
      15   drawer.value = false
      16 }
      17 
      18 // 富文本,作用為了清空富文本
      19 const qedit = ref()
      20 // 本地預覽圖片
      21 const imageUrl = ref('')
      22 const upImage = (image) => {
      23     console.log(image.raw)
      24     // 本地預覽
      25     imageUrl.value = URL.createObjectURL(image.raw)
      26     // 添加到要提交的數據里
      27     ruleForm.value.cover_img = image.raw
      28 }
      29 
      30 
      31 // 父組件打開抽屜
      32 const open = (row) => {
      33     drawer.value = true
      34     console.log(row)
      35     if(row){
      36         console.log("編輯")
      37         // 回顯數據
      38         ruleForm.value = {...row}
      39         // 回顯圖片
      40         imageUrl.value = ruleForm.value.cover_img
      41         
      42     }else{
      43         console.log("新建")
      44         // 置空
      45         ruleForm.value = { ...defaultForm }
      46         imageUrl.value = ''
      47         qedit.value.setHTML('')
      48     }   
      49 }
      50 defineExpose({
      51     open
      52 })
      53 
      54 // 子組件觸發提交
      55 const emit = defineEmits(['tijiao'])
      56 const confirmClick = () => {
      57   ElMessageBox.confirm(`Are you confirm ?`)
      58     .then(() => {
      59       drawer.value = false
      60       // 把圖片做成對象的形式
      61       const fd = new FormData()
      62       for (const key in ruleForm.value) {
      63             console.log(`key:${key},${ruleForm.value[key]}`)
      64             fd.append(key, ruleForm.value[key])
      65           }
      66       // artAddChannelService(fd) 可以在子組件提交
      67       // 交給父組件提交
      68       emit('tijiao',fd)
      69       
      70     })
      71     .catch(() => {
      72       // catch error
      73     })
      74 }
      75 
      76 </script>

      上傳圖片的css

       1 <style lang="scss" scoped>
       2 .avatar-uploader {
       3   :deep() {
       4     .avatar {
       5       width: 178px;
       6       height: 178px;
       7       display: block;
       8     }
       9     .el-upload {
      10       border: 1px dashed var(--el-border-color);
      11       border-radius: 6px;
      12       cursor: pointer;
      13       position: relative;
      14       overflow: hidden;
      15       transition: var(--el-transition-duration-fast);
      16     }
      17     .el-upload:hover {
      18       border-color: var(--el-color-primary);
      19     }
      20     .el-icon.avatar-uploader-icon {
      21       font-size: 28px;
      22       color: #8c939d;
      23       width: 178px;
      24       height: 178px;
      25       text-align: center;
      26     }
      27   }
      28 }
      29 
      30 .editor {
      31   width: 100%;
      32   :deep(.ql-editor) {
      33     min-height: 200px;
      34   }
      35 }
      36 </style>

       完整版本

      父組件

        1 <script lang="ts" setup>
        2 import { ref } from 'vue'
        3 import DrawerPage from './components/DrawerPage.vue';
        4 import SearchSelect from './components/SearchSelect.vue';
        5 import { formatTime } from '@/utils/formdate';
        6 import { artAddChannelService } from '@/api/article.js'
        7 import { useRouter } from 'vue-router'
        8 const router = useRouter()
        9 const cat = () => {
       10   console.log(value.value)
       11 }
       12 const open = ref()
       13 
       14 const tableData = [
       15   {
       16     id: 1,
       17     date: '2016-05-03 12:23:00',
       18     name: 'Tom',
       19     address: 'No. 189, Grove St, Los Angeles',
       20     cover_img:"http://127.0.0.1:8000/static/xx.jpeg",
       21     content:'<p style="color: red">1233</p>'
       22   },
       23   {
       24     id: 2,
       25     date: '2016-05-02',
       26     name: 'Tom',
       27     address: 'No. 189, Grove St, Los Angeles',
       28     cover_img:"http://127.0.0.1:8000/static/xx.jpeg",
       29     content:'<p style="color: red">1233</p>'
       30   },
       31   {
       32     id: 3,
       33     date: '2016-05-04',
       34     name: 'Tom',
       35     address: 'No. 189, Grove St, Los Angeles',
       36     cover_img:"http://127.0.0.1:8000/static/xx.jpeg",
       37     content:'<p style="color: red">1233</p>'
       38   },
       39   {
       40     id: 4,
       41     date: '2016-05-01',
       42     name: 'Tom',
       43     address: 'No. 189, Grove St, Los Angeles',
       44     cover_img:"http://127.0.0.1:8000/static/xx.jpeg",
       45     content:'<p style="color: red">1233</p>'
       46   },
       47 ]
       48 // 新增
       49 const pubulic = () => {
       50   open.value.open()
       51 }
       52 // 修改
       53 const Edit = (row) => {
       54   console.log(row)
       55   // 調用子組件的方法open
       56   open.value.open(row)
       57 }
       58 
       59 const EmitData = (data) => {
       60   // .get 是FromDate 的獲取方式
       61   console.log("cover_img:",data.get("cover_img"))
       62   // 子組件傳來的數據,父組件負責新增、修改
       63   artAddChannelService(data)
       64 }
       65 const value = ref({
       66   page: 1,
       67   size: 2,
       68   selectId : ""
       69 })
       70 </script>
       71 <template>
       72   <title-page title="文章管理">
       73     <template #extra>
       74       <div>
       75         <el-button @click="pubulic">發布文章</el-button>
       76       </div>
       77     </template>
       78     
       79       <el-form inline >
       80         <el-form-item label="文章標題" >
       81           <search-select v-model="value.selectId"></search-select>
       82         </el-form-item>
       83         <el-form-item label="發布狀態">
       84           <el-select label="發布狀態" >
       85             <el-option label="已發布" value=1>新聞</el-option>
       86             <el-option label="未發布" value=0>新聞</el-option>
       87           </el-select>
       88           
       89         </el-form-item>
       90         <el-form-item>
       91           <el-button  style="margin-left: 25px"type="primary">搜索</el-button>
       92           <el-button plan>重置</el-button>
       93           <el-button plan @click="cat">cat</el-button>
       94         </el-form-item>
       95       </el-form>
       96       
       97 
       98     
       99 
      100     <el-table :data="tableData" style="width: 100%">
      101       <el-table-column type="index" label="index" width="180" />
      102       <el-table-column prop="date" label="Date" width="180" >
      103         <template #default="{ row }">
      104           {{ formatTime(row.date) }}
      105         </template>
      106       </el-table-column>
      107       
      108       <el-table-column prop="name" label="Name" width="180" >
      109         <template #default="{ row }">
      110           <el-link @click="router.push(`/article/detail/?aid=${row.id}`)" type="primary" :underline="false">{{ row.name }}</el-link>
      111           <!-- <el-link @click="router.push(`/article/detail/${row.id}`)" type="primary" :underline="false">{{ row.name }}</el-link> -->
      112         </template>
      113       </el-table-column>
      114       <el-table-column prop="address" label="Address" />
      115       
      116       <el-table-column label="Operations">
      117       <template #default="scope">
      118         <el-button size="small" circle icon="Edit" @click="Edit(scope.row)"></el-button>
      119         <el-button
      120           size="small"
      121           type="danger"
      122           circle
      123           icon="Delete"
      124           
      125         >
      126           
      127         </el-button>
      128       </template>
      129     </el-table-column>
      130     
      131     <template #empty>
      132       <el-empty description="暫無數據"></el-empty>
      133     </template>
      134     
      135     </el-table>
      136 
      137     <el-pagination
      138      v-if="tableData.length>0"
      139       v-model:current-page=value.page
      140       v-model:page-size=value.size
      141       :page-sizes="[5, 10, 20, 100]"
      142      
      143   
      144       :background="true"
      145       layout="jumper,total, sizes, prev, pager, next "
      146       :total="10"
      147       style="justify-content: flex-end;"
      148       next-text="下一頁"
      149       prev-text="上一頁"
      150 
      151     />
      152   </title-page>
      153   
      154   <!-- 抽屜  -->
      155   <drawer-page ref="open" @tijiao = EmitData></drawer-page>
      156 </template>
      157 <style scoped>
      158 .sear{
      159 margin-bottom: 10px;
      160 }
      161 </style>
      View Code

      子組件

        1 <script lang="ts" setup>
        2 import { ref } from 'vue'
        3 import { ElMessageBox } from 'element-plus'
        4 import SearchSelect from './SearchSelect.vue';
        5 import { Plus } from '@element-plus/icons-vue'
        6 import { QuillEditor } from '@vueup/vue-quill'
        7 import '@vueup/vue-quill/dist/vue-quill.snow.css';
        8 
        9 
       10 const defaultForm = {date:'',name:'',address:'',cover_img:'',content:''}
       11 const ruleForm = ref({ ...defaultForm })
       12 // 抽屜
       13 const drawer = ref(false)
       14 const cancelClick = () => {
       15   drawer.value = false
       16 }
       17 
       18 // 富文本,作用為了清空富文本
       19 const qedit = ref()
       20 // 本地預覽圖片
       21 const imageUrl = ref('')
       22 const upImage = (image) => {
       23     console.log(image.raw)
       24     // 本地預覽
       25     imageUrl.value = URL.createObjectURL(image.raw)
       26     // 添加到要提交的數據里
       27     ruleForm.value.cover_img = image.raw
       28 }
       29 
       30 
       31 // 父組件打開抽屜
       32 const open = (row) => {
       33     drawer.value = true
       34     console.log(row)
       35     if(row){
       36         console.log("編輯")
       37         // 回顯數據
       38         ruleForm.value = {...row}
       39         // 回顯圖片
       40         imageUrl.value = ruleForm.value.cover_img
       41         
       42     }else{
       43         console.log("新建")
       44         // 置空
       45         ruleForm.value = { ...defaultForm }
       46         imageUrl.value = ''
       47         qedit.value.setHTML('')
       48     }   
       49 }
       50 defineExpose({
       51     open
       52 })
       53 
       54 // 子組件觸發提交
       55 const emit = defineEmits(['tijiao'])
       56 const confirmClick = () => {
       57   ElMessageBox.confirm(`Are you confirm ?`)
       58     .then(() => {
       59       drawer.value = false
       60       // 把圖片做成對象的形式
       61       const fd = new FormData()
       62       for (const key in ruleForm.value) {
       63             console.log(`key:${key},${ruleForm.value[key]}`)
       64             fd.append(key, ruleForm.value[key])
       65           }
       66       // artAddChannelService(fd) 可以在子組件提交
       67       // 交給父組件提交
       68       emit('tijiao',fd)
       69       
       70     })
       71     .catch(() => {
       72       // catch error
       73     })
       74 }
       75 // 富文本:https://vueup.github.io/vue-quill/
       76 </script>
       77 <template>
       78     <div>
       79         <el-drawer
       80             v-model="drawer"
       81             :title="ruleForm.name ? '編輯' : '新增' "
       82             direction="rtl"
       83             size=40%
       84         >
       85             <el-form label-width="auto" label-position="right"    :model="ruleForm">
       86                 <!-- <el-form-item label="name" prop="name">
       87                         <search-select v-model="articleId" width="100%" ></search-select>
       88                 </el-form-item> -->
       89                 <!-- 圖片 -->
       90                 <el-form-item label="cover_img" prop="cover_img">
       91                     <el-upload
       92                         class="avatar-uploader"
       93                         :show-file-list="false"
       94                         :auto-upload="false"
       95                         :on-change="upImage"
       96                     >
       97                         <img v-if="imageUrl" :src="imageUrl" class="avatar" />
       98                         <el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
       99                     </el-upload>
      100                 </el-form-item>
      101                 <!-- 富文本 -->
      102                 <el-form-item label="content">
      103                     <div class="editor">
      104                     <quill-editor ref="qedit" theme="snow" v-model:content="ruleForm.content" content-type="html">
      105                     </quill-editor>
      106                     </div>
      107                 </el-form-item>
      108                 <el-form-item label="name" prop="name" >
      109                     <el-input v-model="ruleForm.name" />
      110                 </el-form-item>
      111                 <el-form-item label="date" prop="date" >
      112                     <el-input v-model="ruleForm.date" />
      113                 </el-form-item>
      114                 <el-form-item label="address" prop="address" >
      115                     <el-input v-model="ruleForm.address" />
      116                 </el-form-item>
      117             </el-form>
      118             <template #footer>
      119             <div style="flex: auto">
      120                 <el-button @click="cancelClick">cancel</el-button>
      121                 <el-button type="primary" @click="confirmClick">confirm</el-button>
      122             </div>
      123             </template>
      124         </el-drawer>
      125     </div>
      126 </template>
      127 <style lang="scss" scoped>
      128 .avatar-uploader {
      129   :deep() {
      130     .avatar {
      131       width: 178px;
      132       height: 178px;
      133       display: block;
      134     }
      135     .el-upload {
      136       border: 1px dashed var(--el-border-color);
      137       border-radius: 6px;
      138       cursor: pointer;
      139       position: relative;
      140       overflow: hidden;
      141       transition: var(--el-transition-duration-fast);
      142     }
      143     .el-upload:hover {
      144       border-color: var(--el-color-primary);
      145     }
      146     .el-icon.avatar-uploader-icon {
      147       font-size: 28px;
      148       color: #8c939d;
      149       width: 178px;
      150       height: 178px;
      151       text-align: center;
      152     }
      153   }
      154 }
      155 
      156 .editor {
      157   width: 100%;
      158   :deep(.ql-editor) {
      159     min-height: 200px;
      160   }
      161 }
      162 </style>
      View Code

       django

       1 setting.py
       2 STATIC_URL = '/static/'
       3 STATICFILES_DIRS = (
       4     os.path.join(BASE_DIR, 'static'),
       5 )
       6 
       7 url.py
       8 from book import views
       9 from django.conf.urls import url
      10 from django.conf import settings
      11 from django.conf.urls.static import static
      12 urlpatterns = [
      13     # 大事件項目
      14     url('/reg', views.reg),
      15     url('/login', views.login),
      16     url('/cate/list', views.articleList),
      17     url('/cate/add', views.addAticle),
      18 
      19 ]+static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
      View Code

       

      posted @ 2024-10-25 17:51  東方不敗--Never  閱讀(228)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 久久精品女人天堂av免费观看| 国产精品 亚洲一区二区三区| 久久精品人妻无码专区| 东方四虎在线观看av| 痉挛高潮喷水av无码免费| 97色伦97色伦国产| 97久久久亚洲综合久久| 成人亚洲精品一区二区三区| 亚洲狠狠狠一区二区三区| 国产黑色丝袜在线播放| 国产免费网站看v片元遮挡| 国内精品伊人久久久久av| 久久久精品人妻一区二区三区| 国产在线观看免费人成视频| caoporn成人免费公开| 人妻体内射精一区二区三区| 国产精品一线二线三线区| 国产成人精品无人区一区| 国产精品视频中文字幕| 四虎av永久在线精品免费观看| 久久综合婷婷成人网站| 国产精品视频亚洲二区| 免费人成在线观看网站| 亚洲国产成人久久77| 国产精品国产三级国产专业| 精品无码人妻| 免费人成在线观看网站| 鄂托克前旗| 成在线人永久免费视频播放| 亚洲色婷婷婷婷五月基地| 国产乱子影视频上线免费观看| 99久久精品国产一区二区蜜芽| 孟村| 91久久天天躁狠狠躁夜夜| 国产成人精品亚洲日本在线观看| 男女xx00上下抽搐动态图| 亚欧成人精品一区二区乱| 日日噜噜大屁股熟妇| 欧美激情一区二区三区成人| 政和县| 老司机亚洲精品一区二区|